The "Attempt to release mutex not owned by caller" exception - what is it and how to avoid it
Okay, so if you're reading this, there's a good chance you've either run into this issue yourself already or have heard about it and want to avoid it.
Also, if you are using (or planning to use) the Output Cache for a large SharePoint site collection, this will affect you too.
What is it?
This is an issue I first saw crop up quite a while ago, however I've seen an increasing number of occurrences of late.
Technically, this exception has been thrown for exactly the reason it states - an attempt was made to release a mutex (lock) by a thread that didn't create it. This could be for a number of reasons, however this article is around the most common reason for seeing this exception within SharePoint.
Essentially this is to do with the number of Access Control Lists (ACLs) you have within a given site collection when you are using the Site Collection Output Cache. Specifically, the cache will support up to 10,000 ACLs within one site collection. If you enable the Output Cache on a site that has more than this, you'll see this exception.
So what exactly is an ACL in this context? An ACL is essentially a binary object that contains the data for all principal to role assignments for a specific scope; essentially it's a collection of ACEs (Access Control Entries). In WSS 3.0, a scope can be any web (subsite), list, document library, folder, item or document that has broken role/permission inheritance; i.e. it has unique permissions to that of its parent. Each time you break role inheritance, a new security scope is created within the current SPSite object (site collection) for which an ACL is added.
It's important to emphasise that the 10,000 limit in the cache is around ACLs not ACEs, which I've seen can generate some confusion. A simple example:
- Say you were to create a new Site Collection with the root web based on the blank site template, i.e. no content.
- Add 50 unique users to the site all with the reader role.
- Create any number of subsites and/or lists.
At this point we have 50 principal to role assignments, i.e. 50 ACEs. We essentially only have one ACL though, which is against the scope of the root web.
- Create another subsite, this time breaking permission inheritance from it's parent.
When you break permission inheritance, the role assignments from the parent object are copied across to the new scope, so in this subsite you would have an additional 50 role assignments.
As we mentioned earlier, when we break inheritance, a new scope is created. New scope = New ACL. So although we now have 100 ACEs in our site collection, we only have 2 ACLs.
How do I tell how many ACLs I currently have in my site collection?
There is a very simple SQL script that you can run against your relevant content database which will give you an estimate of how many ACLs you have per site collection. I say estimate, as we are querying the content data raw here. Although it is of course technically possible to run select statements against the content db, the way to get accurate supported information out of WSS is via the SharePoint UI or Object Model.
We can do this by running the below SQL statement against your Content DB, which should return the estimate of ACLs per site collection. Please be sure to run all SQL transactions against your SharePoint databases as read-only:
SELECT
SiteID,
Count(ScopeID) as 'Estimate ACLs'
FROM
Perms
GROUP BY
SiteID
How do I avoid hitting this issue?
Firstly, this is only when you are using the Output Cache (Site Settings > Site Collection Administration > Site collection output cache) which is disabled as default. If you are not using this or planning to use this, you won't hit this particular issue.
Based on the example earlier above, I'm sure you can imagine that you've got to have broken role inheritance on a lot of items to be hitting this limit. Most implementations I've seen that do are either ones that have a custom security provisioning tool to apply fine grained permissions to all items, or ones where there is a large user base who create a lot of item level content, for example documents, again with unique permissions.
Therefore the best ways to avoid this are preventative approaches when designing your site architecture. If you have performance and optimisation in mind, a golden rule within site design is always try and incorporate as many Site Collections as possible within your application. This is more true than ever if you are planning to use the Output Cache in a deployment which will have a requirement for lots of unique permissions.
I know it's very tempting to only use one site collection, however in pretty much every scenario I've seen, there could be more site collections incorporated if you really think about it. Whether it's geography, business unit, function, department, there is usually always some category at the top level that a web application ends up being split into in terms of navigation.
Exception details
Attempt to release mutex not owned by caller. (Exception from HRESULT: 0x00000120)
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ApplicationException: Attempt to release mutex not owned by caller. (Exception from HRESULT: 0x00000120)
Comments
- Anonymous
March 22, 2010
at http://blogs.msdn.com/spfargo/archive/2009/01/08/attempt-to-release-mutex-not-owned-by-caller-exception-when-output-cache-is-enabled.aspx there is another sql query which yields another number? If I look into the pdf at http://msdn.microsoft.com/en-us/library/cc448602(PROT.10).aspx I think your query is better.