MySQL  8.0.20
Source Code Documentation
lock0lock.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2020, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 
25 *****************************************************************************/
26 
27 /** @file include/lock0lock.h
28  The transaction lock system
29 
30  Created 5/7/1996 Heikki Tuuri
31  *******************************************************/
32 
33 #ifndef lock0lock_h
34 #define lock0lock_h
35 
36 #include "buf0types.h"
37 #include "dict0types.h"
38 #include "hash0hash.h"
39 #include "lock0types.h"
40 #include "mtr0types.h"
41 #include "que0types.h"
42 #include "rem0types.h"
43 #include "srv0srv.h"
44 #include "trx0types.h"
45 #include "univ.i"
46 #include "ut0vec.h"
47 #ifndef UNIV_HOTBACKUP
48 #include "gis0rtree.h"
49 #endif /* UNIV_HOTBACKUP */
50 #include "lock0prdt.h"
51 
52 /**
53 @page PAGE_INNODB_LOCK_SYS Innodb Lock-sys
54 
55 
56 @section sect_lock_sys_introduction Introduction
57 
58 The Lock-sys orchestrates access to tables and rows. Each table, and each row,
59 can be thought of as a resource, and a transaction may request access right for
60 a resource. As two transactions operating on a single resource can lead to
61 problems if the two operations conflict with each other, each lock request also
62 specifies the way the transaction intends to use it, by providing a `mode`. For
63 example a LOCK_X mode, means that transaction needs exclusive access
64 (presumably, it will modify the resource), and LOCK_S mode means that a
65 transaction can share the resource with other transaction which also use LOCK_S
66 mode. There are many different possible modes beside these two, and the logic of
67 checking if given two modes are in conflict is a responsibility of the Lock-sys.
68 A lock request, is called "a lock" for short.
69 A lock can be WAITING or GRANTED.
70 
71 So, a lock, conceptually is a tuple identifying:
72 - requesting transaction
73 - resource (a particular row, a particular table)
74 - mode (LOCK_X, LOCK_S,...)
75 - state (WAITING or GRANTED)
76 
77 @remark
78 In current implementation the "resource" and "mode" are not cleanly separated as
79 for example LOCK_GAP and LOCK_REC_NOT_GAP are often called "modes" even though
80 their semantic is to specify which "sub-resource" (the gap before the row, or
81 the row itself) the transaction needs to access.
82 
83 @remark
84 The Lock-sys identifies records by their page_no (the identifier of the page
85 which contains the record) and the heap_no (the position in page's internal
86 array of allocated records), as opposed to table, index and primary key. This
87 becomes important in case of B-tree merges, splits, or reallocation of variable-
88 length records, all of which need to notify the Lock-sys to reflect the change.
89 
90 Conceptually, the Lock-sys maintains a separate queue for each resource, thus
91 one can analyze and reason about its operations in the scope of a single queue.
92 
93 @remark
94 In practice, locks for gaps and rows are treated as belonging to the same queue.
95 Moreover, to save space locks of a transaction which refer to several rows on
96 the same page might be stored in a single data structure, and thus the physical
97 queue corresponds to a whole page, and not to a single row.
98 Also, each predicate lock (from GIS) is tied to a page, not a record.
99 Finally, the lock queue is implemented by reusing chain links in the hash table,
100 which means that pages with equal hash are held together in a single linked
101 list for their hash bucket.
102 Therefore care must be taken to filter the subset of locks which refer to a
103 given resource when accessing these data structures.
104 
105 The life cycle of a lock is usually as follows:
106 
107 -# The transaction requests the lock, which can either be immediately GRANTED,
108  or, in case of a conflict with an existing lock, goes to the WAITING state.
109 -# In case the lock is WAITING the thread (voluntarily) goes to sleep.
110 -# A WAITING lock either becomes GRANTED (once the conflicting transactions
111  finished and it is our turn) or (in case of a rollback) it gets canceled.
112 -# Once the transaction is finishing (due to commit or rollback) it releases all
113  of its locks.
114 
115 @remark For performance reasons, in Read Committed and weaker Isolation Levels
116 there is also a Step in between 3 and 4 in which we release some of the read
117 locks on gaps, which is done to minimize risk of deadlocks during replication.
118 
119 When a lock is released (due to cancellation in Step 3, or clean up in Step 4),
120 the Lock-sys inspects the corresponding lock queue to see if one or more of the
121 WAITING locks in it can now be granted. If so, some locks become GRANTED and the
122 Lock-sys signals their threads to wake up.
123 
124 
125 @section sect_lock_sys_scheduling The scheduling algorithm
126 
127 We use a variant of the algorithm described in paper "Contention-Aware Lock
128 Scheduling for Transactional Databases" by Boyu Tian, Jiamin Huang, Barzan
129 Mozafari and Grant Schoenebeck.
130 The algorithm, "CATS" for short, analyzes the Wait-for graph, and assigns a
131 weight to each WAITING transaction, equal to the number of transactions which
132 it (transitively) blocks. The idea being that favoring heavy transactions will
133 help to make more progress by helping more transactions to become eventually
134 runnable.
135 
136 The actual implementation of this theoretical idea is currently as follows.
137 
138 -# Locks can be thought of being in 2 logical groups (Granted & Waiting)
139  maintained in the same queue.
140 
141  -# Granted locks are added at the HEAD of the queue.
142  -# Waiting locks are added at the TAIL of the queue.
143  .
144  The queue looks like:
145  ```
146  |
147 Grows <---- [HEAD] [G7 -- G3 -- G2 -- G1] -|- [W4 -- W5 -- W6] [TAIL] ---> Grows
148  Grant Group | Wait Group
149 
150  G - Granted W - waiting,
151  suffix number is the chronological order of requests.
152  ```
153  @remark
154  - In the Wait Group the locks are in chronological order. We will not assert
155  this invariant as there is no significance of the order (and hence the
156  position) as the locks are re-ordered based on CATS weight while making a
157  choice for grant, and CATS weights change constantly to reflect current
158  shape of the Wait-for graph.
159  - In the Grant Group the locks are in reverse chronological order. We will
160  assert this invariant. CATS algorithm doesn't need it, but deadlock
161  detection does, as explained further below.
162 -# When a new lock request comes, we check for conflict with all (GRANTED and
163  WAITING) locks already in the queue.
164  -# If there is a conflicting lock already in the queue, then the new lock
165  request is put into WAITING state and appended at the TAIL. The
166  transaction which requested the conflicting lock found is said to be the
167  Blocking Transaction for the incoming transaction. As each transaction
168  can have at most one WAITING lock, it also can have at most one Blocking
169  Transaction, and thus we store the information about Blocking Transaction
170  (if any) in the transaction object itself (as opposed to: separately for
171  each lock request).
172  -# If there is no conflict, the request can be GRANTED, and lock is
173  prepended at the HEAD.
174 
175 -# When we release a lock, locks which conflict with it need to be checked again
176 if they can now be granted. Note that if there are multiple locks which could be
177 granted, the order in which we decide to grant has an impact on who will have to
178 wait: granting a lock to one transaction, can prevent another waiting
179 transaction from being granted if their request conflict with each other.
180 At the minimum, the Lock-sys must guarantee that a newly GRANTED lock,
181 does not conflict with any other GRANTED lock.
182 Therefore, we will specify the order in which the Lock-sys checks the WAITING
183 locks one by one, and assume that such check involves checking if there is any
184 conflict with already GRANTED locks - if so, the lock remains WAITING, we update
185 the Blocking Transaction of the lock to be the newly identified conflicting
186 transaction, and we check a next lock from the sorted list, otherwise, we grant
187 it (and thus it is checked against in subsequent checks).
188 The Lock-sys uses CATS weight for ordering: it favors transactions with highest
189 CATS weight.
190 Moreover, only the locks which point to the transaction currently releasing the
191 lock as their Blocking Transaction participate as candidates for granting a
192 lock.
193 
194 @remark
195 For each WAITING lock the Blocking Transaction always points to a transaction
196 which has a conflicting lock request, so if the Blocking Transaction is not the
197 one which releases the lock right now, then we know that there is still at least
198 one conflicting transaction. However, there is a subtle issue here: when we
199 request a lock in point 2. we check for conflicts with both GRANTED and WAITING
200 locks, while in point 3. we only check for conflicts with GRANTED locks. So, the
201 Blocking Transaction might be a WAITING one identified in point 2., so we
202 might be tempted to ignore it in point 3. Such "bypassing of waiters" is
203 intentionally prevented to avoid starvation of a WAITING LOCK_X, by a steady
204 stream of LOCK_S requests. Respecting the rule that a Blocking Transaction has
205 to finish before a lock can be granted implies that at least one of WAITING
206 LOCK_Xs will be granted before a LOCK_S can be granted.
207 
208 @remark
209 High Priority transactions in Wait Group are unconditionally kept ahead while
210 sorting the wait queue. The HP is a concept related to Group Replication, and
211 currently has nothing to do with CATS weight.
212 
213 @subsection subsect_lock_sys_blocking How do we choose the Blocking Transaction?
214 
215 It is done differently for new lock requests in point 2. and differently for
216 old lock requests in point 3.
217 
218 For new lock requests, we simply scan the whole queue in its natural order,
219 and the first conflicting lock is chosen. In particular, a WAITING transaction
220 can be chosen, if it is conflicting, and there are no GRATNED conflicting locks.
221 
222 For old lock requests we scan only the Grant Group, and we do so in the
223 chronological order, starting from the oldest lock requests [G1,G2,G3,G7] that
224 is from the middle of the queue towards HEAD. In particular we also check
225 against the locks which recently become GRANTED as they were processed before us
226 in the sorting order, and we do so in a chronological order as well.
227 
228 @remark
229 The idea here is that if we chose G1 as the Blocking Transaction and if there
230 existed a dead lock with another conflicting transaction G3, the deadlock
231 detection would not be postponed indefinitely while new GRANTED locks are
232 added as they are going to be added to HEAD only.
233 In other words: each of the conflicting locks in the Grant Group will eventually
234 be set as the Blocking Transaction at some point in time, and thus it will
235 become visible for the deadlock detection.
236 If, by contrast, we were always picking the first one in the natural order, it
237 might happen that we never get to assign G3 as the Blocking Transaction
238 because new conflicting locks appear in front of the queue (and are released).
239 That might lead to the deadlock with G3 never being noticed.
240 
241 */
242 
243 // Forward declaration
244 class ReadView;
245 
246 extern bool innobase_deadlock_detect;
247 
248 /** Gets the size of a lock struct.
249  @return size in bytes */
250 ulint lock_get_size(void);
251 /** Creates the lock system at database start. */
252 void lock_sys_create(
253  ulint n_cells); /*!< in: number of slots in lock hash table */
254 /** Resize the lock hash table.
255 @param[in] n_cells number of slots in lock hash table */
256 void lock_sys_resize(ulint n_cells);
257 
258 /** Closes the lock system at database shutdown. */
259 void lock_sys_close(void);
260 /** Gets the heap_no of the smallest user record on a page.
261  @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
262 UNIV_INLINE
263 ulint lock_get_min_heap_no(const buf_block_t *block); /*!< in: buffer block */
264 /** Updates the lock table when we have reorganized a page. NOTE: we copy
265  also the locks set on the infimum of the page; the infimum may carry
266  locks if an update of a record is occurring on the page, and its locks
267  were temporarily stored on the infimum. */
269  const buf_block_t *block, /*!< in: old index page, now
270  reorganized */
271  const buf_block_t *oblock); /*!< in: copy of the old, not
272  reorganized page */
273 /** Moves the explicit locks on user records to another page if a record
274  list end is moved to another page. */
276  const buf_block_t *new_block, /*!< in: index page to move to */
277  const buf_block_t *block, /*!< in: index page */
278  const rec_t *rec); /*!< in: record on page: this
279  is the first record moved */
280 /** Moves the explicit locks on user records to another page if a record
281  list start is moved to another page. */
283  const buf_block_t *new_block, /*!< in: index page to move to */
284  const buf_block_t *block, /*!< in: index page */
285  const rec_t *rec, /*!< in: record on page:
286  this is the first
287  record NOT copied */
288  const rec_t *old_end); /*!< in: old
289  previous-to-last
290  record on new_page
291  before the records
292  were copied */
293 /** Updates the lock table when a page is split to the right. */
295  const buf_block_t *right_block, /*!< in: right page */
296  const buf_block_t *left_block); /*!< in: left page */
297 /** Updates the lock table when a page is merged to the right. */
299  const buf_block_t *right_block, /*!< in: right page to
300  which merged */
301  const rec_t *orig_succ, /*!< in: original
302  successor of infimum
303  on the right page
304  before merge */
305  const buf_block_t *left_block); /*!< in: merged index
306  page which will be
307  discarded */
308 /** Updates the lock table when the root page is copied to another in
309  btr_root_raise_and_insert. Note that we leave lock structs on the
310  root page, even though they do not make sense on other than leaf
311  pages: the reason is that in a pessimistic update the infimum record
312  of the root page will act as a dummy carrier of the locks of the record
313  to be updated. */
315  const buf_block_t *block, /*!< in: index page to which copied */
316  const buf_block_t *root); /*!< in: root page */
317 /** Updates the lock table when a page is copied to another and the original
318  page is removed from the chain of leaf pages, except if page is the root! */
320  const buf_block_t *new_block, /*!< in: index page to
321  which copied */
322  const buf_block_t *block); /*!< in: index page;
323  NOT the root! */
324 /** Updates the lock table when a page is split to the left. */
326  const buf_block_t *right_block, /*!< in: right page */
327  const buf_block_t *left_block); /*!< in: left page */
328 /** Updates the lock table when a page is merged to the left. */
330  const buf_block_t *left_block, /*!< in: left page to
331  which merged */
332  const rec_t *orig_pred, /*!< in: original predecessor
333  of supremum on the left page
334  before merge */
335  const buf_block_t *right_block); /*!< in: merged index page
336  which will be discarded */
337 /** Resets the original locks on heir and replaces them with gap type locks
338  inherited from rec. */
340  const buf_block_t *heir_block, /*!< in: block containing the
341  record which inherits */
342  const buf_block_t *block, /*!< in: block containing the
343  record from which inherited;
344  does NOT reset the locks on
345  this record */
346  ulint heir_heap_no, /*!< in: heap_no of the
347  inheriting record */
348  ulint heap_no); /*!< in: heap_no of the
349  donating record */
350 /** Updates the lock table when a page is discarded. */
352  const buf_block_t *heir_block, /*!< in: index page
353  which will inherit the locks */
354  ulint heir_heap_no, /*!< in: heap_no of the record
355  which will inherit the locks */
356  const buf_block_t *block); /*!< in: index page
357  which will be discarded */
358 /** Updates the lock table when a new user record is inserted. */
359 void lock_update_insert(
360  const buf_block_t *block, /*!< in: buffer block containing rec */
361  const rec_t *rec); /*!< in: the inserted record */
362 /** Updates the lock table when a record is removed. */
363 void lock_update_delete(
364  const buf_block_t *block, /*!< in: buffer block containing rec */
365  const rec_t *rec); /*!< in: the record to be removed */
366 /** Stores on the page infimum record the explicit locks of another record.
367  This function is used to store the lock state of a record when it is
368  updated and the size of the record changes in the update. The record
369  is in such an update moved, perhaps to another page. The infimum record
370  acts as a dummy carrier record, taking care of lock releases while the
371  actual record is being moved. */
373  const buf_block_t *block, /*!< in: buffer block containing rec */
374  const rec_t *rec); /*!< in: record whose lock state
375  is stored on the infimum
376  record of the same page; lock
377  bits are reset on the
378  record */
379 /** Restores the state of explicit lock requests on a single record, where the
380  state was stored on the infimum of the page. */
382  const buf_block_t *block, /*!< in: buffer block containing rec */
383  const rec_t *rec, /*!< in: record whose lock state
384  is restored */
385  const buf_block_t *donator); /*!< in: page (rec is not
386  necessarily on this page)
387  whose infimum stored the lock
388  state; lock bits are reset on
389  the infimum */
390 
391 /** Determines if there are explicit record locks on a page.
392  @return an explicit record lock on the page, or NULL if there are none */
393 lock_t *lock_rec_expl_exist_on_page(space_id_t space, /*!< in: space id */
394  page_no_t page_no) /*!< in: page number */
395  MY_ATTRIBUTE((warn_unused_result));
396 /** Checks if locks of other transactions prevent an immediate insert of
397  a record. If they do, first tests if the query thread should anyway
398  be suspended for some reason; if not, then puts the transaction and
399  the query thread to the lock wait state and inserts a waiting request
400  for a gap x-lock to the lock queue.
401  @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
403  ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is
404  set, does nothing */
405  const rec_t *rec, /*!< in: record after which to insert */
406  buf_block_t *block, /*!< in/out: buffer block of rec */
407  dict_index_t *index, /*!< in: index */
408  que_thr_t *thr, /*!< in: query thread */
409  mtr_t *mtr, /*!< in/out: mini-transaction */
410  ibool *inherit) /*!< out: set to TRUE if the new
411  inserted record maybe should inherit
412  LOCK_GAP type locks from the successor
413  record */
414  MY_ATTRIBUTE((warn_unused_result));
415 
416 /** Checks if locks of other transactions prevent an immediate modify (update,
417  delete mark, or delete unmark) of a clustered index record. If they do,
418  first tests if the query thread should anyway be suspended for some
419  reason; if not, then puts the transaction and the query thread to the
420  lock wait state and inserts a waiting request for a record x-lock to the
421  lock queue.
422  @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
424  ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
425  bit is set, does nothing */
426  const buf_block_t *block, /*!< in: buffer block of rec */
427  const rec_t *rec, /*!< in: record which should be
428  modified */
429  dict_index_t *index, /*!< in: clustered index */
430  const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
431  que_thr_t *thr) /*!< in: query thread */
432  MY_ATTRIBUTE((warn_unused_result));
433 /** Checks if locks of other transactions prevent an immediate modify
434  (delete mark or delete unmark) of a secondary index record.
435  @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
437  ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
438  bit is set, does nothing */
439  buf_block_t *block, /*!< in/out: buffer block of rec */
440  const rec_t *rec, /*!< in: record which should be
441  modified; NOTE: as this is a secondary
442  index, we always have to modify the
443  clustered index record first: see the
444  comment below */
445  dict_index_t *index, /*!< in: secondary index */
446  que_thr_t *thr, /*!< in: query thread
447  (can be NULL if BTR_NO_LOCKING_FLAG) */
448  mtr_t *mtr) /*!< in/out: mini-transaction */
449  MY_ATTRIBUTE((warn_unused_result));
450 
451 /** Called to inform lock-sys that a statement processing for a trx has just
452 finished.
453 @param[in] trx transaction which has finished processing a statement */
454 void lock_on_statement_end(trx_t *trx);
455 
456 /** Used to specify the intended duration of a record lock. */
457 enum class lock_duration_t {
458  /** Keep the lock according to the rules of particular isolation level, in
459  particular in case of READ COMMITTED or less restricive modes, do not inherit
460  the lock if the record is purged. */
461  REGULAR = 0,
462  /** Keep the lock around for at least the duration of the current statement,
463  in particular make sure it is inherited as gap lock if the record is purged.*/
464  AT_LEAST_STATEMENT = 1,
465 };
466 
467 /** Like lock_clust_rec_read_check_and_lock(), but reads a
468 secondary index record.
469 @param[in] duration If equal to AT_LEAST_STATEMENT, then makes sure
470  that the lock will be kept around and inherited
471  for at least the duration of current statement.
472  If equal to REGULAR the life-cycle of the lock
473  will depend on isolation level rules.
474 @param[in] block buffer block of rec
475 @param[in] rec user record or page supremum record which should
476  be read or passed over by a read cursor
477 @param[in] index secondary index
478 @param[in] offsets rec_get_offsets(rec, index)
479 @param[in] sel_mode select mode: SELECT_ORDINARY,
480  SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
481 @param[in] mode mode of the lock which the read cursor should
482  set on records: LOCK_S or LOCK_X; the latter is
483  possible in SELECT FOR UPDATE
484 @param[in] gap_mode LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
485 @param[in,out] thr query thread
486 @return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
487 DB_SKIP_LOCKED, or DB_LOCK_NOWAIT */
489  const buf_block_t *block,
490  const rec_t *rec, dict_index_t *index,
491  const ulint *offsets,
492  select_mode sel_mode, lock_mode mode,
493  ulint gap_mode, que_thr_t *thr);
494 
495 /** Checks if locks of other transactions prevent an immediate read, or passing
496 over by a read cursor, of a clustered index record. If they do, first tests
497 if the query thread should anyway be suspended for some reason; if not, then
498 puts the transaction and the query thread to the lock wait state and inserts a
499 waiting request for a record lock to the lock queue. Sets the requested mode
500 lock on the record.
501 @param[in] duration If equal to AT_LEAST_STATEMENT, then makes sure
502  that the lock will be kept around and inherited
503  for at least the duration of current statement.
504  If equal to REGULAR the life-cycle of the lock
505  will depend on isolation level rules.
506 @param[in] block buffer block of rec
507 @param[in] rec user record or page supremum record which should
508  be read or passed over by a read cursor
509 @param[in] index secondary index
510 @param[in] offsets rec_get_offsets(rec, index)
511 @param[in] sel_mode select mode: SELECT_ORDINARY,
512  SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
513 @param[in] mode mode of the lock which the read cursor should
514  set on records: LOCK_S or LOCK_X; the latter is
515  possible in SELECT FOR UPDATE
516 @param[in] gap_mode LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
517 @param[in,out] thr query thread
518 @return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
519 DB_SKIP_LOCKED, or DB_LOCK_NOWAIT */
521  lock_duration_t duration, const buf_block_t *block, const rec_t *rec,
522  dict_index_t *index, const ulint *offsets, select_mode sel_mode,
523  lock_mode mode, ulint gap_mode, que_thr_t *thr);
524 
525 /** Checks if locks of other transactions prevent an immediate read, or passing
526  over by a read cursor, of a clustered index record. If they do, first tests
527  if the query thread should anyway be suspended for some reason; if not, then
528  puts the transaction and the query thread to the lock wait state and inserts a
529  waiting request for a record lock to the lock queue. Sets the requested mode
530  lock on the record. This is an alternative version of
531  lock_clust_rec_read_check_and_lock() that does not require the parameter
532  "offsets".
533  @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
535  const buf_block_t *block, /*!< in: buffer block of rec */
536  const rec_t *rec, /*!< in: user record or page
537  supremum record which should
538  be read or passed over by a
539  read cursor */
540  dict_index_t *index, /*!< in: clustered index */
541  lock_mode mode, /*!< in: mode of the lock which
542  the read cursor should set on
543  records: LOCK_S or LOCK_X; the
544  latter is possible in
545  SELECT FOR UPDATE */
546  ulint gap_mode, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
547  LOCK_REC_NOT_GAP */
548  que_thr_t *thr) /*!< in: query thread */
549  MY_ATTRIBUTE((warn_unused_result));
550 /** Checks that a record is seen in a consistent read.
551  @return true if sees, or false if an earlier version of the record
552  should be retrieved */
554  const rec_t *rec, /*!< in: user record which should be read or
555  passed over by a read cursor */
556  dict_index_t *index, /*!< in: clustered index */
557  const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
558  ReadView *view); /*!< in: consistent read view */
559 /** Checks that a non-clustered index record is seen in a consistent read.
560 
561  NOTE that a non-clustered index page contains so little information on
562  its modifications that also in the case false, the present version of
563  rec may be the right, but we must check this from the clustered index
564  record.
565 
566  @return true if certainly sees, or false if an earlier version of the
567  clustered index record might be needed */
569  const rec_t *rec, /*!< in: user record which
570  should be read or passed over
571  by a read cursor */
572  const dict_index_t *index, /*!< in: index */
573  const ReadView *view) /*!< in: consistent read view */
574  MY_ATTRIBUTE((warn_unused_result));
575 /** Locks the specified database table in the mode given. If the lock cannot
576  be granted immediately, the query thread is put to wait.
577  @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
578 dberr_t lock_table(ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set,
579  does nothing */
580  dict_table_t *table, /*!< in/out: database table
581  in dictionary cache */
582  lock_mode mode, /*!< in: lock mode */
583  que_thr_t *thr) /*!< in: query thread */
584  MY_ATTRIBUTE((warn_unused_result));
585 /** Creates a table IX lock object for a resurrected transaction. */
586 void lock_table_ix_resurrect(dict_table_t *table, /*!< in/out: table */
587  trx_t *trx); /*!< in/out: transaction */
588 
589 /** Sets a lock on a table based on the given mode.
590 @param[in] table table to lock
591 @param[in,out] trx transaction
592 @param[in] mode LOCK_X or LOCK_S
593 @return error code or DB_SUCCESS. */
594 dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, enum lock_mode mode)
595  MY_ATTRIBUTE((nonnull, warn_unused_result));
596 
597 /** Removes a granted record lock of a transaction from the queue and grants
598  locks to other transactions waiting in the queue if they now are entitled
599  to a lock. */
600 void lock_rec_unlock(
601  trx_t *trx, /*!< in/out: transaction that has
602  set a record lock */
603  const buf_block_t *block, /*!< in: buffer block containing rec */
604  const rec_t *rec, /*!< in: record */
605  lock_mode lock_mode); /*!< in: LOCK_S or LOCK_X */
606 /** Releases a transaction's locks, and releases possible other transactions
607  waiting because of these locks. Change the state of the transaction to
608  TRX_STATE_COMMITTED_IN_MEMORY. */
609 void lock_trx_release_locks(trx_t *trx); /*!< in/out: transaction */
610 
611 /** Release read locks of a transacion. It is called during XA
612 prepare to release locks early.
613 @param[in,out] trx transaction
614 @param[in] only_gap release only GAP locks */
615 void lock_trx_release_read_locks(trx_t *trx, bool only_gap);
616 
617 /** Iterate over the granted locks which conflict with trx->lock.wait_lock and
618 prepare the hit list for ASYNC Rollback.
619 
620 If the transaction is waiting for some other lock then wake up
621 with deadlock error. Currently we don't mark following transactions
622 for ASYNC Rollback.
623 
624 1. Read only transactions
625 2. Background transactions
626 3. Other High priority transactions
627 @param[in] trx High Priority transaction
628 @param[in,out] hit_list List of transactions which need to be rolled back */
629 void lock_make_trx_hit_list(trx_t *trx, hit_list_t &hit_list);
630 
631 /** Removes locks on a table to be dropped.
632  If remove_also_table_sx_locks is TRUE then table-level S and X locks are
633  also removed in addition to other table-level and record-level locks.
634  No lock, that is going to be removed, is allowed to be a wait lock. */
636  dict_table_t *table, /*!< in: table to be dropped
637  or discarded */
638  ibool remove_also_table_sx_locks); /*!< in: also removes
639  table S and X locks */
640 
641 /** Calculates the fold value of a page file address: used in inserting or
642  searching for a lock in the hash table.
643  @return folded value */
644 UNIV_INLINE
645 ulint lock_rec_fold(space_id_t space, /*!< in: space */
646  page_no_t page_no) /*!< in: page number */
647  MY_ATTRIBUTE((const));
648 
649 /** Calculates the hash value of a page file address: used in inserting or
650 searching for a lock in the hash table.
651 @param[in] space space
652 @param[in] page_no page number
653 @return hashed value */
654 UNIV_INLINE
655 ulint lock_rec_hash(space_id_t space, page_no_t page_no);
656 
657 /** Get the lock hash table */
658 UNIV_INLINE
659 hash_table_t *lock_hash_get(ulint mode); /*!< in: lock mode */
660 
661 /** Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED,
662  if none found.
663  @return bit index == heap number of the record, or ULINT_UNDEFINED if
664  none found */
665 ulint lock_rec_find_set_bit(const lock_t *lock); /*!< in: record lock with at
666  least one bit set */
667 
668 /** Looks for the next set bit in the record lock bitmap.
669 @param[in] lock record lock with at least one bit set
670 @param[in] heap_no current set bit
671 @return The next bit index == heap number following heap_no, or ULINT_UNDEFINED
672 if none found */
673 ulint lock_rec_find_next_set_bit(const lock_t *lock, ulint heap_no);
674 
675 /** Checks if a lock request lock1 has to wait for request lock2.
676  @return TRUE if lock1 has to wait for lock2 to be removed */
677 bool lock_has_to_wait(const lock_t *lock1, /*!< in: waiting lock */
678  const lock_t *lock2); /*!< in: another lock; NOTE that it
679  is assumed that this has a lock bit
680  set on the same record as in lock1
681  if the locks are record locks */
682 /** Reports that a transaction id is insensible, i.e., in the future. */
684  trx_id_t trx_id, /*!< in: trx id */
685  const rec_t *rec, /*!< in: user record */
686  const dict_index_t *index, /*!< in: index */
687  const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
688  trx_id_t max_trx_id); /*!< in: trx_sys_get_max_trx_id() */
689 
690 /** Prints info of locks for all transactions.
691 @return false if not able to obtain lock mutex and exits without
692 printing info */
694  FILE *file, /*!< in: file where to print */
695  ibool nowait) /*!< in: whether to wait for the lock mutex */
696  MY_ATTRIBUTE((warn_unused_result));
697 
698 /** Prints transaction lock wait and MVCC state.
699 @param[in,out] file file where to print
700 @param[in] trx transaction */
701 void lock_trx_print_wait_and_mvcc_state(FILE *file, const trx_t *trx);
702 
703 /** Prints info of locks for each transaction. This function assumes that the
704  caller holds the lock mutex and more importantly it will release the lock
705  mutex on behalf of the caller. (This should be fixed in the future). */
707  FILE *file); /*!< in: file where to print */
708 /** Return approximate number or record locks (bits set in the bitmap) for
709  this transaction. Since delete-marked records may be removed, the
710  record count will not be precise.
711  The caller must be holding lock_sys->mutex. */
713  const trx_lock_t *trx_lock) /*!< in: transaction locks */
714  MY_ATTRIBUTE((warn_unused_result));
715 
716 /** Return the number of table locks for a transaction.
717  The caller must be holding trx->mutex.
718 @param[in] trx the transaction for which we want the number of table locks */
719 ulint lock_number_of_tables_locked(const trx_t *trx)
720  MY_ATTRIBUTE((warn_unused_result));
721 
722 /** Gets the type of a lock. Non-inline version for using outside of the
723  lock module.
724  @return LOCK_TABLE or LOCK_REC */
725 uint32_t lock_get_type(const lock_t *lock); /*!< in: lock */
726 
727 /** Gets the id of the transaction owning a lock.
728 @param[in] lock A lock of the transaction we are interested in
729 @return the transaction's id */
730 trx_id_t lock_get_trx_id(const lock_t *lock);
731 
732 /** Gets the immutable id of the transaction owning a lock
733 @param[in] lock A lock of the transaction we are interested in
734 @return the transaction's immutable id */
735 uint64_t lock_get_trx_immutable_id(const lock_t *lock);
736 
737 /** Gets the immutable id of this lock.
738 @param[in] lock The lock we are interested in
739 @return The lock's immutable id */
740 uint64_t lock_get_immutable_id(const lock_t *lock);
741 
742 /** Get the performance schema event (thread_id, event_id)
743 that created the lock.
744 @param[in] lock Lock
745 @param[out] thread_id Thread ID that created the lock
746 @param[out] event_id Event ID that created the lock
747 */
748 void lock_get_psi_event(const lock_t *lock, ulonglong *thread_id,
749  ulonglong *event_id);
750 
751 /** Get the first lock of a trx lock list.
752 @param[in] trx_lock the trx lock
753 @return The first lock
754 */
755 const lock_t *lock_get_first_trx_locks(const trx_lock_t *trx_lock);
756 
757 /** Get the next lock of a trx lock list.
758 @param[in] lock the current lock
759 @return The next lock
760 */
761 const lock_t *lock_get_next_trx_locks(const lock_t *lock);
762 
763 /** Gets the mode of a lock in a human readable string.
764  The string should not be free()'d or modified.
765  @return lock mode */
766 const char *lock_get_mode_str(const lock_t *lock); /*!< in: lock */
767 
768 /** Gets the type of a lock in a human readable string.
769  The string should not be free()'d or modified.
770  @return lock type */
771 const char *lock_get_type_str(const lock_t *lock); /*!< in: lock */
772 
773 /** Gets the id of the table on which the lock is.
774  @return id of the table */
775 table_id_t lock_get_table_id(const lock_t *lock); /*!< in: lock */
776 
777 /** Determine which table a lock is associated with.
778 @param[in] lock the lock
779 @return name of the table */
780 const table_name_t &lock_get_table_name(const lock_t *lock);
781 
782 /** For a record lock, gets the index on which the lock is.
783  @return index */
784 const dict_index_t *lock_rec_get_index(const lock_t *lock); /*!< in: lock */
785 
786 /** For a record lock, gets the name of the index on which the lock is.
787  The string should not be free()'d or modified.
788  @return name of the index */
789 const char *lock_rec_get_index_name(const lock_t *lock); /*!< in: lock */
790 
791 /** For a record lock, gets the tablespace number on which the lock is.
792  @return tablespace number */
793 space_id_t lock_rec_get_space_id(const lock_t *lock); /*!< in: lock */
794 
795 /** For a record lock, gets the page number on which the lock is.
796  @return page number */
797 page_no_t lock_rec_get_page_no(const lock_t *lock); /*!< in: lock */
798 /** Check if there are any locks (table or rec) against table.
799  @return true if locks exist */
801  const dict_table_t *table); /*!< in: check if there are any locks
802  held on records in this table or on the
803  table itself */
804 
805 /** A thread which wakes up threads whose lock wait may have lasted too long. */
807 
808 /** Notifies the thread which analyzes wait-for-graph that there was
809  at least one new edge added or modified ( trx->blocking_trx has changed ),
810  so that the thread will know it has to analyze it. */
812 
813 /** Puts a user OS thread to wait for a lock to be released. If an error
814  occurs during the wait trx->error_state associated with thr is
815  != DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
816  are possible errors. DB_DEADLOCK is returned if selective deadlock
817  resolution chose this transaction as a victim. */
818 void lock_wait_suspend_thread(que_thr_t *thr); /*!< in: query thread associated
819  with the user OS thread */
820 /** Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
821  function should be called at the the end of an SQL statement, by the
822  connection thread that owns the transaction (trx->mysql_thd). */
823 void lock_unlock_table_autoinc(trx_t *trx); /*!< in/out: transaction */
824 /** Check whether the transaction has already been rolled back because it
825  was selected as a deadlock victim, or if it has to wait then cancel
826  the wait lock.
827  @return DB_DEADLOCK, DB_LOCK_WAIT or DB_SUCCESS */
828 dberr_t lock_trx_handle_wait(trx_t *trx); /*!< in/out: trx lock state */
829 /** Initialise the trx lock list. */
831  trx_lock_list_t *lock_list); /*!< List to initialise */
832 
833 /** Set the lock system timeout event. */
835 #ifdef UNIV_DEBUG
836 /** Checks that a transaction id is sensible, i.e., not in the future.
837  @return true if ok */
839  trx_id_t trx_id, /*!< in: trx id */
840  const rec_t *rec, /*!< in: user record */
841  const dict_index_t *index, /*!< in: index */
842  const ulint *offsets) /*!< in: rec_get_offsets(rec, index) */
843  MY_ATTRIBUTE((warn_unused_result));
844 /** Check if the transaction holds an exclusive lock on a record.
845 @param[in] thr query thread of the transaction
846 @param[in] table table to check
847 @param[in] block buffer block of the record
848 @param[in] heap_no record heap number
849 @return whether the locks are held */
850 bool lock_trx_has_rec_x_lock(que_thr_t *thr, const dict_table_t *table,
851  const buf_block_t *block, ulint heap_no)
852  MY_ATTRIBUTE((warn_unused_result));
853 #endif /* UNIV_DEBUG */
854 
855 /**
856 Allocate cached locks for the transaction.
857 @param trx allocate cached record locks for this transaction */
858 void lock_trx_alloc_locks(trx_t *trx);
859 
860 /** Lock modes and types */
861 /* @{ */
862 #define LOCK_MODE_MASK \
863  0xFUL /*!< mask used to extract mode from the \
864  type_mode field in a lock */
865 /** Lock types */
866 /* @{ */
867 #define LOCK_TABLE 16 /*!< table lock */
868 #define LOCK_REC 32 /*!< record lock */
869 #define LOCK_TYPE_MASK \
870  0xF0UL /*!< mask used to extract lock type from the \
871  type_mode field in a lock */
872 #if LOCK_MODE_MASK & LOCK_TYPE_MASK
873 #error "LOCK_MODE_MASK & LOCK_TYPE_MASK"
874 #endif
875 
876 #define LOCK_WAIT \
877  256 /*!< Waiting lock flag; when set, it \
878  means that the lock has not yet been \
879  granted, it is just waiting for its \
880  turn in the wait queue */
881 /* Precise modes */
882 #define LOCK_ORDINARY \
883  0 /*!< this flag denotes an ordinary \
884  next-key lock in contrast to LOCK_GAP \
885  or LOCK_REC_NOT_GAP */
886 #define LOCK_GAP \
887  512 /*!< when this bit is set, it means that the \
888  lock holds only on the gap before the record; \
889  for instance, an x-lock on the gap does not \
890  give permission to modify the record on which \
891  the bit is set; locks of this type are created \
892  when records are removed from the index chain \
893  of records */
894 #define LOCK_REC_NOT_GAP \
895  1024 /*!< this bit means that the lock is only on \
896  the index record and does NOT block inserts \
897  to the gap before the index record; this is \
898  used in the case when we retrieve a record \
899  with a unique key, and is also used in \
900  locking plain SELECTs (not part of UPDATE \
901  or DELETE) when the user has set the READ \
902  COMMITTED isolation level */
903 #define LOCK_INSERT_INTENTION \
904  2048 /*!< this bit is set when we place a waiting \
905  gap type record lock request in order to let \
906  an insert of an index record to wait until \
907  there are no conflicting locks by other \
908  transactions on the gap; note that this flag \
909  remains set when the waiting lock is granted, \
910  or if the lock is inherited to a neighboring \
911  record */
912 #define LOCK_PREDICATE 8192 /*!< Predicate lock */
913 #define LOCK_PRDT_PAGE 16384 /*!< Page lock */
914 
915 #if (LOCK_WAIT | LOCK_GAP | LOCK_REC_NOT_GAP | LOCK_INSERT_INTENTION | \
916  LOCK_PREDICATE | LOCK_PRDT_PAGE) & \
917  LOCK_MODE_MASK
918 #error
919 #endif
920 #if (LOCK_WAIT | LOCK_GAP | LOCK_REC_NOT_GAP | LOCK_INSERT_INTENTION | \
921  LOCK_PREDICATE | LOCK_PRDT_PAGE) & \
922  LOCK_TYPE_MASK
923 #error
924 #endif
925 /* @} */
926 
927 /** Lock operation struct */
928 struct lock_op_t {
929  dict_table_t *table; /*!< table to be locked */
930  lock_mode mode; /*!< lock mode */
931 };
932 
933 typedef ib_mutex_t LockMutex;
934 
935 /** The lock system struct */
936 struct lock_sys_t {
937  char pad1[INNOBASE_CACHE_LINE_SIZE];
938  /*!< padding to prevent other
939  memory update hotspots from
940  residing on the same memory
941  cache line */
942  LockMutex mutex; /*!< Mutex protecting the
943  locks */
944  hash_table_t *rec_hash; /*!< hash table of the record
945  locks */
946  hash_table_t *prdt_hash; /*!< hash table of the predicate
947  lock */
948  hash_table_t *prdt_page_hash; /*!< hash table of the page
949  lock */
950 
951  char pad2[INNOBASE_CACHE_LINE_SIZE]; /*!< Padding */
952  LockMutex wait_mutex; /*!< Mutex protecting the
953  next two fields */
954  srv_slot_t *waiting_threads; /*!< Array of user threads
955  suspended while waiting for
956  locks within InnoDB, protected
957  by the lock_sys->wait_mutex */
958  srv_slot_t *last_slot; /*!< highest slot ever used
959  in the waiting_threads array,
960  protected by
961  lock_sys->wait_mutex */
962 
963  ibool rollback_complete;
964  /*!< TRUE if rollback of all
965  recovered transactions is
966  complete. Protected by
967  lock_sys->mutex */
968 
969  ulint n_lock_max_wait_time; /*!< Max wait time */
970 
971  os_event_t timeout_event; /*!< Set to the event that is
972  created in the lock wait monitor
973  thread. A value of 0 means the
974  thread is not active */
976 #ifdef UNIV_DEBUG
977  /** Lock timestamp counter */
978  uint64_t m_seq;
979 #endif /* UNIV_DEBUG */
980 };
982 /*********************************************************************/ /**
983 This function is kind of wrapper to lock_rec_convert_impl_to_expl_for_trx()
984 function with functionailty added to facilitate lock conversion from implicit
985 to explicit for partial rollback cases
986 @param[in] block buffer block of rec
987 @param[in] rec user record on page
988 @param[in] index index of record
989 @param[in] offsets rec_get_offsets(rec, index)
990 @param[in,out] trx active transaction
991 @param[in] heap_no rec heap number to lock */
993  const rec_t *rec, dict_index_t *index,
994  const ulint *offsets, trx_t *trx,
995  ulint heap_no);
997 /** Removes a record lock request, waiting or granted, from the queue. */
998 void lock_rec_discard(lock_t *in_lock); /*!< in: record lock object: all
999  record locks which are contained
1000  in this lock object are removed */
1001 
1002 /** Moves the explicit locks on user records to another page if a record
1003  list start is moved to another page. */
1004 void lock_rtr_move_rec_list(const buf_block_t *new_block, /*!< in: index page to
1005  move to */
1006  const buf_block_t *block, /*!< in: index page */
1007  rtr_rec_move_t *rec_move, /*!< in: recording records
1008  moved */
1009  ulint num_move); /*!< in: num of rec to move */
1010 
1011 /** Removes record lock objects set on an index page which is discarded. This
1012  function does not move locks, or check for waiting locks, therefore the
1013  lock bitmaps must already be reset when this function is called. */
1015  const buf_block_t *block); /*!< in: page to be discarded */
1016 
1017 /** Reset the nth bit of a record lock.
1018 @param[in,out] lock record lock
1019 @param[in] i index of the bit that will be reset
1020 @param[in] type whether the lock is in wait mode */
1021 void lock_rec_trx_wait(lock_t *lock, ulint i, ulint type);
1022 
1023 /** The lock system */
1024 extern lock_sys_t *lock_sys;
1025 
1026 /** Test if lock_sys->mutex can be acquired without waiting. */
1027 #define lock_mutex_enter_nowait() (lock_sys->mutex.trylock(__FILE__, __LINE__))
1028 
1029 /** Test if lock_sys->mutex is owned by the current thread. */
1030 #define lock_mutex_own() (lock_sys->mutex.is_owned())
1031 
1032 /** Acquire the lock_sys->mutex. */
1033 #define lock_mutex_enter() \
1034  do { \
1035  mutex_enter(&lock_sys->mutex); \
1036  } while (0)
1037 
1038 /** Release the lock_sys->mutex. */
1039 #define lock_mutex_exit() \
1040  do { \
1041  lock_sys->mutex.exit(); \
1042  } while (0)
1043 
1044 /** Test if lock_sys->wait_mutex is owned. */
1045 #define lock_wait_mutex_own() (lock_sys->wait_mutex.is_owned())
1046 
1047 /** Acquire the lock_sys->wait_mutex. */
1048 #define lock_wait_mutex_enter() \
1049  do { \
1050  mutex_enter(&lock_sys->wait_mutex); \
1051  } while (0)
1052 
1053 /** Release the lock_sys->wait_mutex. */
1054 #define lock_wait_mutex_exit() \
1055  do { \
1056  lock_sys->wait_mutex.exit(); \
1057  } while (0)
1058 
1059 #include "lock0lock.ic"
1061 #endif
Record manager global types.
unsigned long long int ulonglong
Definition: my_inttypes.h:55
void lock_update_copy_and_discard(const buf_block_t *new_block, const buf_block_t *block)
Updates the lock table when a page is copied to another and the original page is removed from the cha...
Definition: lock0lock.cc:2951
A vector of pointers to data items.
ulint lock_number_of_rows_locked(const trx_lock_t *trx_lock)
Return approximate number or record locks (bits set in the bitmap) for this transaction.
Definition: lock0lock.cc:916
uint32 page_no_t
Page number.
Definition: api0api.h:57
const char * lock_get_type_str(const lock_t *lock)
Gets the type of a lock in a human readable string.
Definition: lock0lock.cc:5957
void lock_trx_alloc_locks(trx_t *trx)
Allocate cached locks for the transaction.
Definition: lock0lock.cc:6511
void lock_wait_timeout_thread()
A thread which wakes up threads whose lock wait may have lasted too long.
Definition: lock0wait.cc:1415
dberr_t lock_clust_rec_read_check_and_lock_alt(const buf_block_t *block, const rec_t *rec, dict_index_t *index, lock_mode mode, ulint gap_mode, que_thr_t *thr)
Checks if locks of other transactions prevent an immediate read, or passing over by a read cursor...
Definition: lock0lock.cc:5725
void lock_move_rec_list_end(const buf_block_t *new_block, const buf_block_t *block, const rec_t *rec)
Moves the explicit locks on user records to another page if a record list end is moved to another pag...
Definition: lock0lock.cc:2608
Lock operation struct.
Definition: lock0lock.h:955
const char * lock_rec_get_index_name(const lock_t *lock)
For a record lock, gets the name of the index on which the lock is.
Definition: lock0lock.cc:6017
R-tree header file.
Definition: trx0trx.h:800
Lock struct; protected by lock_sys->mutex.
Definition: lock0priv.h:132
const lock_t * lock_get_first_trx_locks(const trx_lock_t *trx_lock)
Get the first lock of a trx lock list.
Definition: lock0lock.cc:5867
const dict_index_t * lock_rec_get_index(const lock_t *lock)
For a record lock, gets the index on which the lock is.
Definition: lock0lock.cc:6006
Read view lists the trx ids of those transactions for which a consistent read should not see the modi...
Definition: read0types.h:47
pthread_mutex_t mutex
Definition: memcached.c:384
The buffer control block structure.
Definition: buf0buf.h:1321
The transaction lock system global types.
lock_duration_t
Used to specify the intended duration of a record lock.
Definition: lock0lock.h:457
void lock_unlock_table_autoinc(trx_t *trx)
Unlocks AUTO_INC type locks that were possibly reserved by a trx.
Definition: lock0lock.cc:6070
void lock_update_discard(const buf_block_t *heir_block, ulint heir_heap_no, const buf_block_t *block)
Updates the lock table when a page is discarded.
Definition: lock0lock.cc:3064
ulint lock_rec_find_next_set_bit(const lock_t *lock, ulint heap_no)
Looks for the next set bit in the record lock bitmap.
Definition: lock0lock.cc:587
space_id_t lock_rec_get_space_id(const lock_t *lock)
For a record lock, gets the tablespace number on which the lock is.
Definition: lock0lock.cc:6027
uint64_t lock_get_trx_immutable_id(const lock_t *lock)
Gets the immutable id of the transaction owning a lock.
Definition: lock0lock.cc:5834
void lock_on_statement_end(trx_t *trx)
Called to inform lock-sys that a statement processing for a trx has just finished.
Definition: lock0lock.cc:2282
select_mode
Definition: lock0types.h:44
Data structure for a database table.
Definition: dict0mem.h:1520
trx_id_t lock_get_trx_id(const lock_t *lock)
Gets the id of the transaction owning a lock.
Definition: lock0lock.cc:5838
bool innobase_deadlock_detect
Definition: lock0lock.cc:67
void lock_update_merge_right(const buf_block_t *right_block, const rec_t *orig_succ, const buf_block_t *left_block)
Updates the lock table when a page is merged to the right.
Definition: lock0lock.cc:2889
uint64_t lock_get_immutable_id(const lock_t *lock)
Gets the immutable id of this lock.
Definition: lock0lock.cc:5842
const std::string FILE("FILE")
UNIV_INLINE hash_table_t * lock_hash_get(ulint mode)
Get the lock hash table.
ulint lock_get_size(void)
Gets the size of a lock struct.
Definition: lock0lock.cc:407
lock_t * lock_rec_expl_exist_on_page(space_id_t space, page_no_t page_no)
Determines if there are explicit record locks on a page.
Definition: lock0lock.cc:635
page_no_t lock_rec_get_page_no(const lock_t *lock)
For a record lock, gets the page number on which the lock is.
Definition: lock0lock.cc:6036
const lock_t * lock_get_next_trx_locks(const lock_t *lock)
Get the next lock of a trx lock list.
Definition: lock0lock.cc:5879
The predicate lock system.
void lock_update_insert(const buf_block_t *block, const rec_t *rec)
Updates the lock table when a new user record is inserted.
Definition: lock0lock.cc:3122
bool lock_table_has_locks(const dict_table_t *table)
Check if there are any locks (table or rec) against table.
Definition: lock0lock.cc:6262
dberr_t lock_sec_rec_read_check_and_lock(lock_duration_t duration, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, select_mode sel_mode, lock_mode mode, ulint gap_mode, que_thr_t *thr)
Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record.
Definition: lock0lock.cc:5609
Keep the lock around for at least the duration of the current statement, in particular make sure it i...
The server main program.
Query graph global types.
dberr_t lock_trx_handle_wait(trx_t *trx)
Check whether the transaction has already been rolled back because it was selected as a deadlock vict...
Definition: lock0lock.cc:6194
bool lock_has_to_wait(const lock_t *lock1, const lock_t *lock2)
Checks if a lock request lock1 has to wait for request lock2.
Definition: lock0lock.cc:535
ulint lock_number_of_tables_locked(const trx_t *trx)
Return the number of table locks for a transaction.
Definition: lock0lock.cc:924
dberr_t lock_table(ulint flags, dict_table_t *table, lock_mode mode, que_thr_t *thr)
Locks the specified database table in the mode given.
Definition: lock0lock.cc:3524
void lock_update_root_raise(const buf_block_t *block, const buf_block_t *root)
Updates the lock table when the root page is copied to another in btr_root_raise_and_insert.
Definition: lock0lock.cc:2936
ulint lock_rec_find_set_bit(const lock_t *lock)
Looks for a set bit in a record lock bitmap.
Definition: lock0lock.cc:570
void lock_trx_release_locks(trx_t *trx)
Releases a transaction&#39;s locks, and releases possible other transactions waiting because of these loc...
Definition: lock0lock.cc:6122
UNIV_INLINE ulint lock_get_min_heap_no(const buf_block_t *block)
Gets the heap_no of the smallest user record on a page.
void lock_report_trx_id_insanity(trx_id_t trx_id, const rec_t *rec, const dict_index_t *index, const ulint *offsets, trx_id_t max_trx_id)
Reports that a transaction id is insensible, i.e., in the future.
Definition: lock0lock.cc:176
lock_sys_t * lock_sys
The lock system.
Definition: lock0lock.cc:165
Definition: hash0hash.h:401
void lock_trx_lock_list_init(trx_lock_list_t *lock_list)
Initialise the trx lock list.
Definition: lock0lock.cc:6296
void lock_update_split_right(const buf_block_t *right_block, const buf_block_t *left_block)
Updates the lock table when a page is split to the right.
Definition: lock0lock.cc:2865
void lock_update_split_left(const buf_block_t *right_block, const buf_block_t *left_block)
Updates the lock table when a page is split to the left.
Definition: lock0lock.cc:2969
void lock_rec_trx_wait(lock_t *lock, ulint i, ulint type)
Reset the nth bit of a record lock.
Definition: lock0lock.cc:625
Data dictionary global types.
uint32_t lock_get_type(const lock_t *lock)
Gets the type of a lock.
Definition: lock0lock.cc:5829
dberr_t lock_clust_rec_read_check_and_lock(lock_duration_t duration, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, select_mode sel_mode, lock_mode mode, ulint gap_mode, que_thr_t *thr)
Checks if locks of other transactions prevent an immediate read, or passing over by a read cursor...
Definition: lock0lock.cc:5665
void lock_trx_release_read_locks(trx_t *trx, bool only_gap)
Release read locks of a transacion.
Definition: lock0lock.cc:3971
Table name wrapper for pretty-printing.
Definition: dict0mem.h:446
static std::mutex lock
Definition: net_ns.cc:55
byte rec_t
Definition: rem0types.h:39
bool lock_print_info_summary(FILE *file, ibool nowait)
Prints info of locks for all transactions.
Definition: lock0lock.cc:4398
UNIV_INLINE ulint lock_rec_fold(space_id_t space, page_no_t page_no)
Calculates the fold value of a page file address: used in inserting or searching for a lock in the ha...
void lock_update_merge_left(const buf_block_t *left_block, const rec_t *orig_pred, const buf_block_t *right_block)
Updates the lock table when a page is merged to the left.
Definition: lock0lock.cc:2987
const table_name_t & lock_get_table_name(const lock_t *lock)
Determine which table a lock is associated with.
Definition: lock0lock.cc:6000
#define INNOBASE_CACHE_LINE_SIZE
CPU cache line size.
Definition: ut0counter.h:52
The lock system struct.
Definition: lock0lock.h:963
ib_mutex_t LockMutex
Definition: lock0lock.h:960
dberr_t
Definition: db0err.h:38
The database buffer pool global types for the directory.
dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, enum lock_mode mode)
Sets a lock on a table based on the given mode.
Definition: lock0lock.cc:3766
Definition: gis0type.h:166
Definition: que0que.h:246
void lock_rec_reset_and_inherit_gap_locks(const buf_block_t *heir_block, const buf_block_t *block, ulint heir_heap_no, ulint heap_no)
Resets the original locks on heir and replaces them with gap type locks inherited from rec...
Definition: lock0lock.cc:3042
std::vector< TrxVersion, ut_allocator< TrxVersion > > hit_list_t
Definition: trx0types.h:629
bool lock_clust_rec_cons_read_sees(const rec_t *rec, dict_index_t *index, const ulint *offsets, ReadView *view)
Checks that a record is seen in a consistent read.
Definition: lock0lock.cc:219
void lock_table_ix_resurrect(dict_table_t *table, trx_t *trx)
Creates a table IX lock object for a resurrected transaction.
Definition: lock0lock.cc:3630
void lock_wait_suspend_thread(que_thr_t *thr)
Puts a user OS thread to wait for a lock to be released.
Definition: lock0wait.cc:194
bool lock_trx_has_rec_x_lock(que_thr_t *thr, const dict_table_t *table, const buf_block_t *block, ulint heap_no)
Check if the transaction holds an exclusive lock on a record.
Definition: lock0lock.cc:6307
Transaction system global type definitions.
void lock_sys_create(ulint n_cells)
Creates the lock system at database start.
Definition: lock0lock.cc:288
ib_id_t table_id_t
Table or partition identifier (unique within an InnoDB instance).
Definition: dict0types.h:215
void lock_wait_request_check_for_cycles()
Notifies the thread which analyzes wait-for-graph that there was at least one new edge added or modif...
Definition: lock0wait.cc:187
void lock_update_delete(const buf_block_t *block, const rec_t *rec)
Updates the lock table when a record is removed.
Definition: lock0lock.cc:3146
uint32 space_id_t
Tablespace identifier.
Definition: api0api.h:59
void lock_print_info_all_transactions(FILE *file)
Prints info of locks for each transaction.
Definition: lock0lock.cc:4747
dberr_t lock_rec_insert_check_and_lock(ulint flags, const rec_t *rec, buf_block_t *block, dict_index_t *index, que_thr_t *thr, mtr_t *mtr, ibool *inherit)
Checks if locks of other transactions prevent an immediate insert of a record.
Definition: lock0lock.cc:5212
dberr_t lock_sec_rec_modify_check_and_lock(ulint flags, buf_block_t *block, const rec_t *rec, dict_index_t *index, que_thr_t *thr, mtr_t *mtr)
Checks if locks of other transactions prevent an immediate modify (delete mark or delete unmark) of a...
Definition: lock0lock.cc:5535
dberr_t lock_clust_rec_modify_check_and_lock(ulint flags, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, que_thr_t *thr)
Checks if locks of other transactions prevent an immediate modify (update, delete mark...
Definition: lock0lock.cc:5482
void lock_rec_unlock(trx_t *trx, const buf_block_t *block, const rec_t *rec, lock_mode lock_mode)
Removes a granted record lock of a transaction from the queue and grants locks to other transactions ...
Definition: lock0lock.cc:3834
void lock_move_reorganize_page(const buf_block_t *block, const buf_block_t *oblock)
Updates the lock table when we have reorganized a page.
Definition: lock0lock.cc:2485
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:144
bool lock_check_trx_id_sanity(trx_id_t trx_id, const rec_t *rec, const dict_index_t *index, const ulint *offsets)
Checks that a transaction id is sensible, i.e., not in the future.
Definition: lock0lock.cc:198
void lock_sys_resize(ulint n_cells)
Resize the lock hash table.
Definition: lock0lock.cc:328
void lock_set_timeout_event()
Set the lock system timeout event.
Definition: lock0lock.cc:6303
const char * lock_get_mode_str(const lock_t *lock)
Gets the mode of a lock in a human readable string.
Definition: lock0lock.cc:5900
void lock_make_trx_hit_list(trx_t *trx, hit_list_t &hit_list)
Iterate over the granted locks which conflict with trx->lock.wait_lock and prepare the hit list for A...
Definition: lock0lock.cc:1772
table_id_t lock_get_table_id(const lock_t *lock)
Gets the id of the table on which the lock is.
Definition: lock0lock.cc:5988
InnoDB condition variable.
Definition: os0event.cc:66
void lock_move_rec_list_start(const buf_block_t *new_block, const buf_block_t *block, const rec_t *rec, const rec_t *old_end)
Moves the explicit locks on user records to another page if a record list start is moved to another p...
Definition: lock0lock.cc:2698
void lock_rtr_move_rec_list(const buf_block_t *new_block, const buf_block_t *block, rtr_rec_move_t *rec_move, ulint num_move)
Moves the explicit locks on user records to another page if a record list start is moved to another p...
Definition: lock0lock.cc:2792
void lock_rec_restore_from_page_infimum(const buf_block_t *block, const rec_t *rec, const buf_block_t *donator)
Restores the state of explicit lock requests on a single record, where the state was stored on the in...
Definition: lock0lock.cc:3204
Definition: os0file.h:85
void lock_get_psi_event(const lock_t *lock, ulonglong *thread_id, ulonglong *event_id)
Get the performance schema event (thread_id, event_id) that created the lock.
Definition: lock0lock.cc:5852
void lock_rec_store_on_page_infimum(const buf_block_t *block, const rec_t *rec)
Stores on the page infimum record the explicit locks of another record.
Definition: lock0lock.cc:3183
Keep the lock according to the rules of particular isolation level, in particular in case of READ COM...
static int flags[50]
Definition: hp_test1.cc:39
The simple hash table utility.
bool lock_sec_rec_cons_read_sees(const rec_t *rec, const dict_index_t *index, const ReadView *view)
Checks that a non-clustered index record is seen in a consistent read.
Definition: lock0lock.cc:256
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:169
lock_mode
Definition: lock0types.h:51
Latching protocol for trx_lock_t::que_state.
Definition: trx0trx.h:552
void lock_rec_discard(lock_t *in_lock)
Removes a record lock request, waiting or granted, from the queue.
Definition: lock0lock.cc:2164
void lock_trx_print_wait_and_mvcc_state(FILE *file, const trx_t *trx)
Prints transaction lock wait and MVCC state.
Definition: lock0lock.cc:4603
void lock_remove_all_on_table(dict_table_t *table, ibool remove_also_table_sx_locks)
Removes locks on a table to be dropped.
Definition: lock0lock.cc:4181
void lock_rec_free_all_from_discard_page(const buf_block_t *block)
Removes record lock objects set on an index page which is discarded.
Definition: lock0lock.cc:2226
UNIV_INLINE ulint lock_rec_hash(space_id_t space, page_no_t page_no)
Calculates the hash value of a page file address: used in inserting or searching for a lock in the ha...
void lock_rec_convert_active_impl_to_expl(const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, trx_t *trx, ulint heap_no)
This function is kind of wrapper to lock_rec_convert_impl_to_expl_for_trx() function with functionail...
Definition: lock0lock.cc:5466
Thread slot in the thread table.
Definition: srv0srv.h:1165
Mini-transaction buffer global types.
static my_thread_id thread_id
Definition: my_thr_init.cc:62
void lock_sys_close(void)
Closes the lock system at database shutdown.
Definition: lock0lock.cc:374
Data structure for an index.
Definition: dict0mem.h:879