Design
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:9k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. # $Id: Design,v 11.3 2000/02/19 20:58:03 bostic Exp $
  2. Synchronization in the Locking Subsystem
  3. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  4. 1. Data structures
  5. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  6. The lock manager maintains 3 different structures:
  7. Objects (__db_lockobj):
  8. Describes an object that is locked.  When used with DB, this consists
  9. of a __db_ilock (a file identifier and a page number).
  10. Lockers (__db_locker):
  11. Identifies a specific locker ID and maintains the head of a list of
  12. locks held by a locker (for using during transaction commit/abort).
  13. Locks (__db_lock):
  14. Describes a particular object lock held on behalf of a particular
  15. locker id.
  16. Objects and Lockers reference Locks.
  17. These structures are organized via two synchronized hash tables.  Each
  18. hash table consists of two physical arrays: the array of actual hash
  19. buckets and an array of mutexes so we can lock individual buckets, rather
  20. than the whole table.
  21. One hash table contains Objects and the other hash table contains Lockers.
  22. Objects contain two lists of locks, waiters and holders: holders currently
  23. hold a lock on the Object, waiters are lock waiting to be granted.
  24. Lockers are a single linked list that connects the Locks held on behalf
  25. of the specific locker ID.
  26. In the diagram below:
  27. Locker ID #1 holds a lock on Object #1 (L1) and Object #2 (L5), and is
  28. waiting on a lock on Object #1 (L3).
  29. Locker ID #2 holds a lock on Object #1 (L2) and is waiting on a lock for
  30. Object #2 (L7).
  31. Locker ID #3 is waiting for a lock on Object #2 (L6).
  32. OBJECT                   -----------------------
  33. HASH                     |                     |
  34.                              ----|-------------        |
  35. ________    _______  |   |   ________ |        |
  36. | |-->| O1  |--|---|-->|  O2  | |        |
  37. |_______|   |_____|  |   |   |______| V        |
  38. | |    W  H--->L1->L2   W  H--->L5       | holders
  39. |_______|    |       |   |    |                V
  40. | |    ------->L3      ------->L6------>L7 waiters
  41. |_______|           /                 
  42. . .          /                   
  43. . .          |                    
  44. . .          |                     -----------
  45. |_______|          |          --------------        |
  46. | |      ____|____                ___|_____  _|______
  47. |_______|      |       |                |       |  |      |
  48. | |      | LID1  |                |  LID2 |  | LID3 |
  49. |_______|      |_______|                |_______|  |______|
  50.    ^                        ^        ^
  51.    |                        |        |
  52. ___|________________________|________|___
  53.        LOCKER |    |    |    |    |    |    |    |    |
  54.        HASH |    |    |    |    |    |    |    |    |
  55. |    |    |    |    |    |    |    |    |
  56. |____|____|____|____|____|____|____|____|
  57. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  58. 2. Synchronization
  59. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  60. There are four types of mutexes in the subsystem.
  61. Object mutexes;
  62. These map one-to-one to each bucket in the Object hash table.
  63. Holding a mutex on an Object bucket secures all the Objects in
  64. that bucket as well as the Lock structures linked from those
  65. Objects.  All fields in the Locks EXCEPT the Locker links (the
  66. links that attach Locks by Locker ID) are protected by these
  67. mutexes.
  68. Locker mutexes:
  69. These map one-to-one to each bucket in the Locker hash table.
  70. Holding a mutex on a Locker bucket secures the Locker structures
  71. and the Locker links in the Locks.
  72. Memory mutex:
  73. This mutex allows calls to allocate/free memory, i.e. calls to
  74. __db_shalloc and __db_shalloc_free, as well as manipulation of
  75. the Object, Locker and Lock free lists.
  76. Region mutex:
  77. This mutex is currently only used to protect the locker ids.
  78. It may also be needed later to provide exclusive access to
  79. the region for deadlock detection.
  80. Creating or removing a Lock requires locking both the Object lock and the
  81. Locker lock (and eventually the shalloc lock to return the item to the
  82. free list).
  83. The locking hierarchy is as follows:
  84. The Region mutex may never be acquired after any other mutex.
  85. The Object mutex may be acquired after the Region mutex.
  86. The Locker mutex may be acquired after the Region and Object
  87. mutexes.
  88. The Memory mutex may be acquired after any mutex.
  89. So, if both and Object mutex and a Locker mutex are going to be acquired,
  90. the Object mutex must be acquired first.
  91. The Memory mutex may be acquired after any other mutex, but no other mutexes
  92. can be acquired once the Memory mutex is held.
  93. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  94. 3. The algorithms:
  95. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  96. The locking subsystem supports four basic operations:
  97. Get a Lock (lock_get)
  98. Release a Lock (lock_put)
  99. Release all the Locks on a specific Object (lock_vec)
  100. Release all the Locks for a specific Locker (lock_vec)
  101. Get a lock:
  102. Acquire Object bucket mutex.
  103. Acquire Locker bucket mutex.
  104. Acquire Memory mutex.
  105. If the Object does not exist
  106. Take an Object off the freelist.
  107. If the Locker doesn't exist
  108. Take a Locker off the freelist.
  109. Take a Lock off the free list.
  110. Release Memory mutex.
  111. Add Lock to the Object list.
  112. Add Lock to the Locker list.
  113. Release Locker bucket mutex
  114. If the lock cannot be granted
  115. Release Object bucket mutex
  116. Acquire lock mutex (blocks)
  117. Acquire Object bucket mutex
  118. If lock acquisition did not succeed (e.g, deadlock)
  119. Acquire Locker bucket mutex
  120. If locker should be destroyed
  121. Remove locker from hash table
  122. Acquire Memory mutex
  123. Return locker to free list
  124. Release Memory mutex
  125. Release Locker bucket mutex
  126. If object should be released
  127. Acquire Memory mutex
  128. Return object to free list
  129. Release Memory mutex
  130. Release Object bucket mutex
  131. Release a lock:
  132. Acquire Object bucket mutex.
  133. (Requires that we be able to find the Object hash bucket
  134. without looking inside the Lock itself.)
  135. If releasing a single lock and the user provided generation number
  136. doesn't match the Lock's generation number, the Lock has been reused
  137. and we return failure.
  138. Enter lock_put_internal:
  139. if the Lock is still on the Object's lists:
  140. Increment Lock's generation number.
  141. Remove Lock from the Object's list (NULL link fields).
  142. Promote locks for the Object.
  143. Enter locker_list_removal
  144. Acquire Locker bucket mutex.
  145. If Locker doesn't exist:
  146. Release Locker bucket mutex
  147. Release Object bucket mutex
  148. Return error.
  149. Else if Locker marked as deleted:
  150. dont_release = TRUE
  151. Else
  152. Remove Lock from Locker list.
  153. If Locker has no more locks
  154. Remove Locker from table.
  155. Acquire Memory mutex.
  156. Return Locker to free list
  157. Release Memory mutex
  158. Release Locker bucket mutex.
  159. Exit locker_list_removal
  160. If (!dont_release)
  161. Acquire Memory mutex
  162. Return Lock to free list
  163. Release Memory mutex
  164. Exit lock_put_internal
  165. Release Object bucket mutex
  166. Release all the Locks on a specific Object (lock_vec, DB_PUT_ALL_OBJ):
  167. Acquire Object bucket mutex.
  168. For each lock on the waiter list:
  169. lock_put_internal
  170. For each lock on the holder list:
  171. lock_put_internal
  172. Release Object bucket mutex.
  173. Release all the Locks for a specific Locker (lock_vec, DB_PUT_ALL):
  174. Acquire Locker bucket mutex.
  175. Mark Locker deleted.
  176. Release Locker mutex.
  177. For each lock on the Locker's list:
  178. Remove from locker's list
  179. (The lock could get put back on the free list in
  180. lock_put and then could get reallocated and the
  181. act of setting its locker links could clobber us.)
  182. Perform "Release a Lock" above: skip locker_list_removal.
  183. Acquire Locker bucket mutex.
  184. Remove Locker
  185. Release Locker mutex.
  186. Acquire Memory mutex
  187. Return Locker to free list
  188. Release Memory mutex
  189. Deadlock detection (lock_detect):
  190. For each bucket in Object table
  191. Acquire the Object bucket mutex.
  192. create waitsfor
  193. For each bucket in Object table
  194. Release the Object mutex.
  195. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  196. FAQ:
  197. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  198. Q: Why do you need generation numbers?
  199. A: If a lock has been released due to a transaction abort (potentially in a
  200.    different process), and then lock is released by a thread of control
  201.    unaware of the abort, the lock might have potentially been re-allocated
  202.    to a different object.  The generation numbers detect this problem.
  203.    Note, we assume that reads/writes of lock generation numbers are atomic,
  204.    if they are not, it is theoretically possible that a re-allocated lock
  205.    could be mistaken for another lock.
  206. Q: Why is is safe to walk the Locker list without holding any mutexes at
  207.    all?
  208. A: Locks are created with both the Object and Locker bucket mutexes held.
  209.    Once created, they removed in two ways:
  210.    a) when a specific Lock is released, in which case, the Object and
  211.    Locker bucket mutexes are again held, and
  212.    b) when all Locks for a specific Locker Id is released.
  213.    In case b), the Locker bucket mutex is held while the Locker chain is
  214.    marked as "destroyed", which blocks any further access to the Locker
  215.    chain.  Then, each individual Object bucket mutex is acquired when each
  216.    individual Lock is removed.
  217. Q: What are the implications of doing fine grain locking?
  218. A: Since we no longer globally lock the entire region, lock_vec will no
  219.    longer be atomic.  We still execute the items in a lock_vec in order,
  220.    so things like lock-coupling still work, but you can't make any
  221.    guarantees about atomicity.
  222. Q: How do I configure for FINE_GRAIN locking?
  223. A: We currently do not support any automatic configuration for FINE_GRAIN
  224.    locking.  When we do, will need to document that atomicity discussion
  225.    listed above (it is bug-report #553).