Tanel Poder wrote excellent article about library cache latches in Oracle 11g: Library Cache Latches Gone in Oracle 11g.
Mutex (mutual exclusion) is a memory structure that allows multiple program threads to share the same resource, such as file access – but not simultaneously. When a program is started, a mutex is created with a unique name. After this stage, any thread that needs the resource must lock the mutex from other threads while it is using the resource. The mutex is set to unlock when the data is no longer needed or the routine is finished.
Suppose a section of code is altering piece of data, while another thread, triggered by some unpredictable event, starts executing. If second thread reads from the same piece of data, the data, in the process of being overwritten, is in inconsistent and unpredictable state. If the second state tries overwriting the data, the ensuing state will probably be unrecoverable. These sections of code accessing shared data must therefore be protected, so that other processes which read from or write to the chunk of data are excluded from running.
Mutex’s are very similar to latches, but still there are some differences between them.
From Tanel Poder:
In Oracle, latches and mutexes are different things and managed using different modules. KSL* modules for latches and KGX* for mutexes.
General mutex operations require less CPU instructions than latch operations (as they aren’t as sophisticated as latches and don’t maintain get/miss counts as latches do).
But the main scalability benefit comes from that there’s a mutex structure in each child cursor handle and the mutex itself acts as cursor pin structure. So if you have a cursor open (or cached in session cursor cache) you don’t need to get the library cache latch (which was previously needed for changing cursor pin status), but you can modify the cursor’s mutex recount directly (with help of pointers in open cursor state area in sessions UGA).
Therefore you have much higher scalability when pinning/unpinning cursors (no library cache latching needed, virtually no false contention) and no separate pin structures need to be allocated/maintained.
1) library cache latching is still needed for parsing etc, the mutexes address only the pinning issue in library cache
2) mutexes are currently used for library cache cursors (not other objects like PL/SQL stored procs, table defs etc)
3) As mutexes are a generic mechanism (not library cache specific) they’re used in V$SQLSTATS underlying structures too
4) When mutexes are enabled, you won’t see cursor pins from X$KGLPN anymore (as X$KGLPN is a fixed table based on the KGL pin array – which wouldn’t be used for cursors anymore)
I studied the mutex stuff a bit when 10.2 came out, I’d say mutexes are less intelligent than latches. But thanks to that, they are more lightweight and thanks to quite large caches on modern CPUs we can afford having tons of them – allowing very fine grained locking.
On my 32bit linux installation a mutex was 28 bytes in size, while a regular latch structure was 110 bytes. In theory every library cache child should have it’s own mutex, but in practice I saw one case where two different child objects were protected by the same mutex – that was what library cache dump showed me anyway.
Mutex also acts as a pin structure, so there’s no need to do another memory write for pinning a cursor. Mutex allows immediate shared access to resources it protects, the old approach would mean getting a library cache latch in exclusive mode and then modifying the corresponding library cache child pin structure.
Mutexes also don’t maintain statistics on successful gets as latches do, only sleeps are registered.
Thanks to all that, an immediately succeeding mutex get operation takes several times less CPU instructions (and hits possibly less memory stalls), from a 10gR2 perf tuning course I remember it was about 250 vs 50 CPU instructions on IA32 platform.
Note that mutexes don’t provide much benefit for poorly written applications, for most benefit your apps should avoid any kind of reparsing – keeping cursors open and cancelling them manually when interest in query results has ended.
Eric S. Emric
One of the appeals of the mutex, per the documentation, is the reduced potential for false contention. That is, a mutex can protect a single structure; often times stored with the structure it protects. However, latches often protect many structures (see cache buffers chain latch) and can yield what the documentation calls false contention. It is called false contention because “the contention is for the protection mechanism rather than the target object you are attempting to access.” This all sounds really great, right? Well, maybe. If Oracle goes to more widespread use of mutexes instead of latches to protect target objects that would be a boatload more mutexes. I am sure the porters at Oracle are not intending to use mutexes exclusively in the future. But, I can see where contention in Oracle could be dramatically reduced at the cost of CPU cycles and memory. What would happen if Oracle protected each buffer with a mutex? While each mutex is less expensive with regard to memory and CPU than an individual latch, you will need considerably more mutexes for each replaced latch. 50 mutexes used to replace a single latch could run the CPU up considerably for the “same” application workload.
Oracle is replacing some of its serialization protection objects from latches to mutexes. As you can see from Tanel’s example, the structures previously protected by “library cache latches” have been replaced with “library cache mutexes” in Oracle 11g. Also with Oracle 10g and 11g we got several new mutexes and related wait events which are described in documentation.
A session waits on this event when it is requesting a mutex in shared mode, when another session is currently holding a this mutex in exclusive mode on the same cursor object.
The session requests the mutex for a cursor object in exclusive mode, and it must wait because the resource is busy. The mutex is busy because either the mutex is being held in exclusive mode by another session or the mutex is being held shared by one or more sessions. The existing mutex holder(s) must release the mutex before the mutex can be granted exclusively.