MySQL Lock:
There are many types of locks inside MySQL, which can be divided into two categories depending on the purpose:
1. Lock that protects the memory structure
The server layer is basically protected with Mutex,rwlock for thread-shared variables.
InnoDB layer will increase using spinlock spin lock
2. Locks that provide or guarantee transactional functionality
The server provides an MDL lock, a table lock, and two types of locks
InnoDB implementing row-level locks
Atomic operation:
In a single-processor system (uniprocessor) architecture, atomic instructions are done in one instruction cycle, because the response to a hard interrupt is check after each CPU instruction is completed.
In multiprocessor architectures (symmetric multi-processor), to complete an atomic instruction, there is a need to ensure consistency between multiple cores, which introduces the steps to lock the bus.
Example: CMPXCHG directive under the x86 system
The following uses atomic directives to implement Mutex,rwlock,spinlock's simple pseudo-code
1. Pseudo-code of the mutex:
Mutex_lock:
?
1 2 3 4 5 6 |
while (1) if cmpxchg(*lock,0,1)==0 success break ; else futex(wait) |
Mutex_unlock:
?
1 2 3 |
if cmpxchg(*lock,1,0)==0 futex(wakeup) success |
2. Pseudo-code for spinlock:
Spinlock_lock:
?
1 2 3) 4 5 |
while (1) /* spin */ if compchg(*lock,0,1)==0 success break |
Spinlock_unlock:
?
1 2 |
if cmpxchg(*lock,1,0)==0 success |
3. Pseudo-code for Rwlock:
/* Variables */
?
1 2 3 4 |
mutex_lock rw_mutex int r_cnt; int w_cnt; int if_has_w_req; /* 防饿死*/ |
Rwlock_r_lock:
?
1 2 3 4 5 6 7 8 9 |
<em>mutex_ Lock (Rw_mutex) while (1) &NBSP;&NBSP; if (!if_has_w_req && w_cnt ==0) &NBSP;&NBSP;&NBSP;&NBSP; Success &NBSP;&NBSP;&NBSP;&NBSP; r_cnt++ Code class= "CPP Spaces" >&NBSP;&NBSP;&NBSP;&NBSP; mutex_unlock (Rw_mutex) Code class= "CPP Spaces" >&NBSP;&NBSP;&NBSP;&NBSP; return &NBSP;&NBSP; else futex (wait) </em> |
Rwlock_r_unlock:
?
1 2 3 4 |
mutex_lock(rw_mutex) r_cnt--; mutext_unlock(rw_mutex) fetex(wake_up) |
Rwlock_w_lock:
?
1 2 3 4 5 6 7 8 9 10 11 |
mutex_lock (Rw_mutex) if_has_w_req++ while (1) if (r_cnt>0 | | w_cnt >0) &NBSP;&NBSP;&NBSP;&NBSP; fetux (wait) &NBSP;&NBSP; else &NBSP;&NBSP;&NBSP;&NBSP; if_has_w_req-- &NBSP;&NBSP;&NBSP;&NBSP; success &NBSP;&NBSP;&NBSP;&NBSP; w_cnt++; &NBSP;&NBSP;&NBSP;&NBSP; break mutext_unlock (Rw_mutex) |
Rwlock_w_unlock:
?
1 2 3 |
mutex_lock(rw_mutex) w_cnt-- mutex_unlock(rw_mutex) |
Discussion of deadlocks
1. The lock of the memory structure, must control the lock order, guarantees does not appear the deadlock
2. Transaction lock, cannot guarantee user's behavior, need deadlock detection
Cond