Neulich habe ich in einem SharePoint 2007 (MOSS) folgende Fehlermeldung erhalten.“Es wurde versucht, einen Mutex freizugeben, der nicht im Besitz des Aufrufers war. (Ausnahme von HRESULT:0x00000120)“.

Ereigniscode: 3005
Ereignismeldung: Es ist eine unbehandelte Ausnahme aufgetreten.
Ereigniszeit: 27.10.2011 10:53:34
Ereigniszeit (UTC): 27.10.2011 08:53:34
Ereignis-ID: e4a15d8d4a344d0fad29cddb014210e3
Ereignissequenz: 76
Vorkommen: 23
Ereignisdetailcode: 0
Anwendungsinformationen:
Anwendungsdomäne: /LM/W3SVC/1444631078/Root-1-129641789052031250
Vertrauensebene: Full
Virtueller Anwendungspfad: /
Anwendungspfad: C:InetpubwwwrootwssVirtualDirectories
Computername: MyServer
Prozessinformationen:
Prozess-ID: 2972
Prozessname: w3wp.exe
Kontoname: MyDomain/MySystemUser
Ausnahmeinformationen:
Ausnahmetyp: ApplicationException
Ausnahmemeldung: Es wurde versucht, einen Mutex freizugeben,
der nicht im Besitz des Aufrufers war. (Ausnahme von HRESULT: 0x00000120)
Anforderungsinformationen:
Anforderungs-URL: https://MyPortal/Seiten/default.aspx
Anforderungspfad: Seiten/default.aspx
Benutzerhostadresse:
Benutzer: MyDomain/MyUser
Ist authentifiziert: True
Authentifizierungstyp: Negotiate
Threadkontoname: MyDomain/MySystemUser
Threadinformationen:
Thread-ID: 7
Threadkontoname: MyDomain/MySystemUser
Identitätswechsel für: True
Stapelüberwachung: bei System.Threading.ReaderWriterLock.ReleaseWriterLockInternal()
bei System.Threading.ReaderWriterLock.ReleaseWriterLock()
bei Microsoft.SharePoint.Publishing.ThreadSafeCache`2.ReleaseWriterLock()
bei Microsoft.SharePoint.Publishing.AclCache.LoadAllAcls(SPSite site)
bei Microsoft.SharePoint.Publishing.PublishingHttpModule.EnableCachingIfAppropriate(Object source, EventArgs e)
bei System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
bei System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Zunächst betrachten wir einmal, was ein Mutex überhaupt ist. Dazu ein schneller Blick in die MSDN Dokumentation:
„Wenn zwei oder mehr Threads gleichzeitig auf eine gemeinsam genutzte Ressource zugreifen müssen, benötigt das System einen Synchronisierungsmechanismus, der sicherstellt, dass die Ressource von jeweils nur einem Thread verwendet wird. Mutex
ist ein primitiver Synchronisierungstyp, der jeweils nur einem Thread exklusiven Zugriff auf die gemeinsam genutzte Ressource gewährt. Wenn ein Thread einen Mutex erhält, wird ein zweiter Thread, der diesen Mutex abruft, so lange angehalten, bis der erste Thread den Mutex freigibt.“
Auf den ersten Schock folgten die ersten Rettungsversuche. Zunächst habe ich den IIS des Servers sowie den Server selbst neu gestartet, beides ohne Erfolg. Als Ursache konnte ich auch den SQL Server des Portals ausschließen. Die Anzahl der Workerprozesse des IIS haben ebenfalls keinen Einfluss.
Nach einiger Suche bin ich im Blog MsSharePointTip auf diesen Eintrag von Joshua Fuente gestoßen.
Die Ursache liegt im Ausgabecache der Site Collection. Dieser unterstützt maximal 10.000 ACL (Access Control Lists). Wird dieses Limit bei aktivem Output Cache überschritten, erscheint der hier beschriebene Fehler.
Einen entsprechenden Hinweis findet sich auch in diesem Technet Artikel. Hier wird auch die Funktionsweise des Output Cache beschrieben.
Nachdem wir nun wissen, wie das Problem entsteht können wir uns an die Lösung begeben.
Schnelle Lösung
Der Ausgabecache der Site Collection muss deaktiviert werden. Dazu rufen wir die Websiteeinstellungen der Root Site Collection auf (http://<MyPortal>/_layouts/settings.aspx). Im Bereich Websitesammlungsverwaltung kann der Ausgabecache der Websitesammlung ausgeschaltet werden.
Die Seiten sind anschließend sofort wieder erreichbar. Allerdings werden nicht alle Elemente korrekt angezeigt (Bilder fehlen auf den Seiten). Im Eventlog finden sich diese Fehlermeldungen:
Ereigniscode: 3005
Ereignismeldung: Es ist eine unbehandelte Ausnahme aufgetreten.
Ereigniszeit: 27.10.2011 11:09:20
Ereigniszeit (UTC): 27.10.2011 09:09:20
Ereignis-ID: e1b52f4722d44faabc4694c4d36d1268
Ereignissequenz: 143
Vorkommen: 15
Ereignisdetailcode: 0
Anwendungsinformationen:
Anwendungsdomäne: /LM/W3SVC/1444631078/Root-1-129641797726403056
Vertrauensebene: Full
Virtueller Anwendungspfad: /
Anwendungspfad: C:InetpubwwwrootwssVirtualDirectories
Computername: MyServer
Prozessinformationen:
Prozess-ID: 244
Prozessname: w3wp.exe
Kontoname: MyDomainMySystemUser
Ausnahmeinformationen:
Ausnahmetyp: COMException
Ausnahmemeldung: Der Vorgang kann nicht erfolgreich beendet werden.
Bitte versuchen Sie es erneut.
Anforderungsinformationen:
Anforderungs-URL: https://MyPortal/Style Library/Images/Customer/item.gif
Anforderungspfad: /Style Library/Images/Customer/item.gif
Benutzerhostadresse:
Benutzer: MyDomainMySystemUser
Ist authentifiziert: True
Authentifizierungstyp: Negotiate
Threadkontoname: MyDomainMySystemUser
Threadinformationen:
Thread-ID: 9
Threadkontoname: MyDomainMySystemUser
Identitätswechsel für: False
Stapelüberwachung: bei Microsoft.SharePoint.Library.SPRequestInternalClass.
GetAllAclsForCurrentSite(String bstrWebUrl, Int32 lMaxAcls)
bei Microsoft.SharePoint.Library.SPRequest.GetAllAclsForCurrentSite(String bstrWebUrl, Int32 lMaxAcls)
Die Lösung ist also noch nicht zufriedenstellend.
Endgültige Lösung
Da der Output Cache deutliche Performance Verbesserung verspricht, indem hier alle großen Objekte, die häufig angefragt werden, zwischengespeichert werden, sollte dieser wieder aktiviert werden. Es muss also ermittelt werden, wie viele Access Control Lists verwendet werden und wo diese zur Anwendung kommen. Nur so kann die Anzahl der ACLs reduziert werden.
Mittels diesem SQL Statement kann ermittelt werden, wie viele ACL’s es gibt:
SELECT SiteID, Count(ScopeID) as 'Estimate ACLs' FROM Perms GROUP BY SiteID
Hiermit lässt sich ermitteln, in welcher Website die meisten ACLs hinterlegt sind:
SELECT SiteID, webid, Count(ScopeID) as 'Estimate ACLs' FROM Perms GROUP BY SiteID, webid
Ist die Website bekannt, kann das Query so angepasst werden, dass nur eine bestimmte Website angezeigt wird:
select * from perms where webid = '<GUID>'
In meinem Fall lag es an einer Liste, die über zahlreiche Listenelemente (einige tausend) verfügte. Jedes Listenelement hatte dabei eigene Berechtigungsinformationen. Nachdem die Anzahl der Listenelemente mit eigener Berechtigung reduziert wurde, war der Spuk auch schon vorbei.