MySQL 8.0.31
Source Code Documentation
lock0lock.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1996, 2022, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 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 "lock0latches.h"
51#include "lock0prdt.h"
52
53/**
54@page PAGE_INNODB_LOCK_SYS Innodb Lock-sys
55
56
57@section sect_lock_sys_introduction Introduction
58
59The Lock-sys orchestrates access to tables and rows. Each table, and each row,
60can be thought of as a resource, and a transaction may request access right for
61a resource. As two transactions operating on a single resource can lead to
62problems if the two operations conflict with each other, each lock request also
63specifies the way the transaction intends to use it, by providing a `mode`. For
64example a LOCK_X mode, means that transaction needs exclusive access
65(presumably, it will modify the resource), and LOCK_S mode means that a
66transaction can share the resource with other transaction which also use LOCK_S
67mode. There are many different possible modes beside these two, and the logic of
68checking if given two modes are in conflict is a responsibility of the Lock-sys.
69A lock request, is called "a lock" for short.
70A lock can be WAITING or GRANTED.
71
72So, a lock, conceptually is a tuple identifying:
73- requesting transaction
74- resource (a particular row, a particular table)
75- mode (LOCK_X, LOCK_S,...)
76- state (WAITING or GRANTED)
77
78@remark
79In current implementation the "resource" and "mode" are not cleanly separated as
80for example LOCK_GAP and LOCK_REC_NOT_GAP are often called "modes" even though
81their semantic is to specify which "sub-resource" (the gap before the row, or
82the row itself) the transaction needs to access.
83
84@remark
85The Lock-sys identifies records by their page_no (the identifier of the page
86which contains the record) and the heap_no (the position in page's internal
87array of allocated records), as opposed to table, index and primary key. This
88becomes important in case of B-tree merges, splits, or reallocation of variable-
89length records, all of which need to notify the Lock-sys to reflect the change.
90
91Conceptually, the Lock-sys maintains a separate queue for each resource, thus
92one can analyze and reason about its operations in the scope of a single queue.
93
94@remark
95In practice, locks for gaps and rows are treated as belonging to the same queue.
96Moreover, to save space locks of a transaction which refer to several rows on
97the same page might be stored in a single data structure, and thus the physical
98queue corresponds to a whole page, and not to a single row.
99Also, each predicate lock (from GIS) is tied to a page, not a record.
100Finally, the lock queue is implemented by reusing chain links in the hash table,
101which means that pages with equal hash are held together in a single linked
102list for their hash cell.
103Therefore care must be taken to filter the subset of locks which refer to a
104given resource when accessing these data structures.
105
106The life cycle of a lock is usually as follows:
107
108-# The transaction requests the lock, which can either be immediately GRANTED,
109 or, in case of a conflict with an existing lock, goes to the WAITING state.
110-# In case the lock is WAITING the thread (voluntarily) goes to sleep.
111-# A WAITING lock either becomes GRANTED (once the conflicting transactions
112 finished and it is our turn) or (in case of a rollback) it gets canceled.
113-# Once the transaction is finishing (due to commit or rollback) it releases all
114 of its locks.
115
116@remark For performance reasons, in Read Committed and weaker Isolation Levels
117there is also a Step in between 3 and 4 in which we release some of the read
118locks on gaps, which is done to minimize risk of deadlocks during replication.
119
120When a lock is released (due to cancellation in Step 3, or clean up in Step 4),
121the Lock-sys inspects the corresponding lock queue to see if one or more of the
122WAITING locks in it can now be granted. If so, some locks become GRANTED and the
123Lock-sys signals their threads to wake up.
124
125
126@section sect_lock_sys_scheduling The scheduling algorithm
127
128We use a variant of the algorithm described in paper "Contention-Aware Lock
129Scheduling for Transactional Databases" by Boyu Tian, Jiamin Huang, Barzan
130Mozafari and Grant Schoenebeck.
131The algorithm, "CATS" for short, analyzes the Wait-for graph, and assigns a
132weight to each WAITING transaction, equal to the number of transactions which
133it (transitively) blocks. The idea being that favoring heavy transactions will
134help to make more progress by helping more transactions to become eventually
135runnable.
136
137The actual implementation of this theoretical idea is currently as follows.
138
139-# Locks can be thought of being in 2 logical groups (Granted & Waiting)
140 maintained in the same queue.
141
142 -# Granted locks are added at the HEAD of the queue.
143 -# Waiting locks are added at the TAIL of the queue.
144 .
145 The queue looks like:
146 ```
147 |
148Grows <---- [HEAD] [G7 -- G3 -- G2 -- G1] -|- [W4 -- W5 -- W6] [TAIL] ---> Grows
149 Grant Group | Wait Group
150
151 G - Granted W - waiting,
152 suffix number is the chronological order of requests.
153 ```
154 @remark
155 - In the Wait Group the locks are in chronological order. We will not assert
156 this invariant as there is no significance of the order (and hence the
157 position) as the locks are re-ordered based on CATS weight while making a
158 choice for grant, and CATS weights change constantly to reflect current
159 shape of the Wait-for graph.
160 - In the Grant Group the locks are in reverse chronological order. We will
161 assert this invariant. CATS algorithm doesn't need it, but deadlock
162 detection does, as explained further below.
163-# When a new lock request comes, we check for conflict with all (GRANTED and
164 WAITING) locks already in the queue.
165 -# If there is a conflicting lock already in the queue, then the new lock
166 request is put into WAITING state and appended at the TAIL. The
167 transaction which requested the conflicting lock found is said to be the
168 Blocking Transaction for the incoming transaction. As each transaction
169 can have at most one WAITING lock, it also can have at most one Blocking
170 Transaction, and thus we store the information about Blocking Transaction
171 (if any) in the transaction object itself (as opposed to: separately for
172 each lock request).
173 -# If there is no conflict, the request can be GRANTED, and lock is
174 prepended at the HEAD.
175
176-# When we release a lock, locks which conflict with it need to be checked again
177if they can now be granted. Note that if there are multiple locks which could be
178granted, the order in which we decide to grant has an impact on who will have to
179wait: granting a lock to one transaction, can prevent another waiting
180transaction from being granted if their request conflict with each other.
181At the minimum, the Lock-sys must guarantee that a newly GRANTED lock,
182does not conflict with any other GRANTED lock.
183Therefore, we will specify the order in which the Lock-sys checks the WAITING
184locks one by one, and assume that such check involves checking if there is any
185conflict with already GRANTED locks - if so, the lock remains WAITING, we update
186the Blocking Transaction of the lock to be the newly identified conflicting
187transaction, and we check a next lock from the sorted list, otherwise, we grant
188it (and thus it is checked against in subsequent checks).
189The Lock-sys uses CATS weight for ordering: it favors transactions with highest
190CATS weight.
191Moreover, only the locks which point to the transaction currently releasing the
192lock as their Blocking Transaction participate as candidates for granting a
193lock.
194
195@remark
196For each WAITING lock the Blocking Transaction always points to a transaction
197which has a conflicting lock request, so if the Blocking Transaction is not the
198one which releases the lock right now, then we know that there is still at least
199one conflicting transaction. However, there is a subtle issue here: when we
200request a lock in point 2. we check for conflicts with both GRANTED and WAITING
201locks, while in point 3. we only check for conflicts with GRANTED locks. So, the
202Blocking Transaction might be a WAITING one identified in point 2., so we
203might be tempted to ignore it in point 3. Such "bypassing of waiters" is
204intentionally prevented to avoid starvation of a WAITING LOCK_X, by a steady
205stream of LOCK_S requests. Respecting the rule that a Blocking Transaction has
206to finish before a lock can be granted implies that at least one of WAITING
207LOCK_Xs will be granted before a LOCK_S can be granted.
208
209@remark
210High Priority transactions in Wait Group are unconditionally kept ahead while
211sorting the wait queue. The HP is a concept related to Group Replication, and
212currently has nothing to do with CATS weight.
213
214@subsection subsect_lock_sys_blocking How do we choose the Blocking Transaction?
215
216It is done differently for new lock requests in point 2. and differently for
217old lock requests in point 3.
218
219For new lock requests, we simply scan the whole queue in its natural order,
220and the first conflicting lock is chosen. In particular, a WAITING transaction
221can be chosen, if it is conflicting, and there are no GRATNED conflicting locks.
222
223For old lock requests we scan only the Grant Group, and we do so in the
224chronological order, starting from the oldest lock requests [G1,G2,G3,G7] that
225is from the middle of the queue towards HEAD. In particular we also check
226against the locks which recently become GRANTED as they were processed before us
227in the sorting order, and we do so in a chronological order as well.
228
229@remark
230The idea here is that if we chose G1 as the Blocking Transaction and if there
231existed a dead lock with another conflicting transaction G3, the deadlock
232detection would not be postponed indefinitely while new GRANTED locks are
233added as they are going to be added to HEAD only.
234In other words: each of the conflicting locks in the Grant Group will eventually
235be set as the Blocking Transaction at some point in time, and thus it will
236become visible for the deadlock detection.
237If, by contrast, we were always picking the first one in the natural order, it
238might happen that we never get to assign G3 as the Blocking Transaction
239because new conflicting locks appear in front of the queue (and are released).
240That might lead to the deadlock with G3 never being noticed.
241
242*/
243
244// Forward declaration
245class ReadView;
246
247extern bool innobase_deadlock_detect;
248
249/** Gets the size of a lock struct.
250 @return size in bytes */
251ulint lock_get_size(void);
252/** Creates the lock system at database start. */
253void lock_sys_create(
254 ulint n_cells); /*!< in: number of slots in lock hash table */
255
256/** Resize the lock hash tables.
257@param[in] n_cells number of slots in lock hash table */
258void lock_sys_resize(ulint n_cells);
259
260/** Closes the lock system at database shutdown. */
261void lock_sys_close(void);
262/** Gets the heap_no of the smallest user record on a page.
263 @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
265 const buf_block_t *block); /*!< in: buffer block */
266/** Updates the lock table when we have reorganized a page. NOTE: we copy
267 also the locks set on the infimum of the page; the infimum may carry
268 locks if an update of a record is occurring on the page, and its locks
269 were temporarily stored on the infimum. */
271 const buf_block_t *block, /*!< in: old index page, now
272 reorganized */
273 const buf_block_t *oblock); /*!< in: copy of the old, not
274 reorganized page */
275
276/** Moves the explicit locks on user records to another page if a record
277list end is moved to another page.
278@param[in] new_block Index page to move to
279@param[in] block Index page
280@param[in,out] rec Record on page: this is the first record moved */
281void lock_move_rec_list_end(const buf_block_t *new_block,
282 const buf_block_t *block, const rec_t *rec);
283
284/** Moves the explicit locks on user records to another page if a record
285 list start is moved to another page.
286@param[in] new_block Index page to move to
287@param[in] block Index page
288@param[in,out] rec Record on page: this is the first record not copied
289@param[in] old_end Old previous-to-last record on new_page before the records
290were copied */
291void lock_move_rec_list_start(const buf_block_t *new_block,
292 const buf_block_t *block, const rec_t *rec,
293 const rec_t *old_end);
294
295/** Updates the lock table when a page is split to the right.
296@param[in] right_block Right page
297@param[in] left_block Left page */
298void lock_update_split_right(const buf_block_t *right_block,
299 const buf_block_t *left_block);
300
301/** Updates the lock table when a page is merged to the right.
302@param[in] right_block Right page to which merged
303@param[in] orig_succ Original successor of infimum on the right page before
304merge
305@param[in] left_block Merged index page which will be discarded */
306void lock_update_merge_right(const buf_block_t *right_block,
307 const rec_t *orig_succ,
308 const buf_block_t *left_block);
309
310/** Updates the lock table when the root page is copied to another in
311 btr_root_raise_and_insert. Note that we leave lock structs on the
312 root page, even though they do not make sense on other than leaf
313 pages: the reason is that in a pessimistic update the infimum record
314 of the root page will act as a dummy carrier of the locks of the record
315 to be updated. */
317 const buf_block_t *block, /*!< in: index page to which copied */
318 const buf_block_t *root); /*!< in: root page */
319
320/** Updates the lock table when a page is copied to another and the original
321 page is removed from the chain of leaf pages, except if page is the root!
322@param[in] new_block Index page to which copied
323@param[in] block Index page; not the root! */
324void lock_update_copy_and_discard(const buf_block_t *new_block,
325 const buf_block_t *block);
326
327/** Requests the Lock System to update record locks regarding the gap between
328the last record of the left_page and the first record of the right_page when the
329caller is about to prepended a new record as the first record on the right page,
330even though it should "naturally" be inserted as the last record of the
331left_page according to the information in the higher levels of the index.
332
333That is, we assume that the lowest common ancestor of the left_page and the
334right_page routes the key of the new record to the left_page, but a heuristic
335which tries to avoid overflowing the left_page has chosen to prepend the new
336record to the right_page instead. Said ancestor performs this routing by
337comparing the key of the record to a "split point" - the key associated with the
338right_page's subtree, such that all records larger than that split point are to
339be found in the right_page (or some even further page). Ideally this should be
340the minimum key in this whole subtree, however due to the way we optimize the
341DELETE and INSERT operations, we often do not update this information, so that
342such "split point" can actually be smaller than the real minimum. Still, even if
343not up-to-date, its value is always correct, in that it really separates the
344subtrees (keys smaller than "split point" are not in left_page and larger are
345not in right_page).
346
347The reason this is important to Lock System, is that the gap between the last
348record on the left_page and the first record on the right_page is represented as
349two gaps:
3501. The gap between the last record on the left_page and the "split point",
351represented as the gap before the supremum pseudo-record of the left_page.
3522. The gap between the "split point" and the first record of the right_page,
353represented as the gap before the first user record of the right_page.
354
355Thus, inserting the new record, and subsequently adjusting "split points" in its
356ancestors to values smaller or equal to the new records' key, will mean that gap
357will be sliced at a different place ("moved to the left"): fragment of the 1st
358gap will now become treated as 2nd. Therefore, Lock System must copy any GRANTED
359locks from 1st gap to the 2nd gap. Any WAITING locks must be of INSERT_INTENTION
360type (as no other GAP locks ever wait for anything) and can stay at 1st gap, as
361their only purpose is to notify the requester they can retry insertion, and
362there's no correctness requirement to avoid waking them up too soon.
363
364@param[in] right_block Right page
365@param[in] left_block Left page */
366void lock_update_split_point(const buf_block_t *right_block,
367 const buf_block_t *left_block);
368
369/** Updates the lock table when a page is split to the left.
370@param[in] right_block Right page
371@param[in] left_block Left page */
372void lock_update_split_left(const buf_block_t *right_block,
373 const buf_block_t *left_block);
374
375/** Updates the lock table when a page is merged to the left.
376@param[in] left_block Left page to which merged
377@param[in] orig_pred Original predecessor of supremum on the left page before
378merge
379@param[in] right_block Merged index page which will be discarded */
380void lock_update_merge_left(const buf_block_t *left_block,
381 const rec_t *orig_pred,
382 const buf_block_t *right_block);
383
384/** Resets the original locks on heir and replaces them with gap type locks
385 inherited from rec.
386@param[in] heir_block Block containing the record which inherits
387@param[in] block Block containing the record from which inherited; does not
388reset the locks on this record
389@param[in] heir_heap_no Heap_no of the inheriting record
390@param[in] heap_no Heap_no of the donating record */
392 const buf_block_t *block,
393 ulint heir_heap_no, ulint heap_no);
394
395/** Updates the lock table when a page is discarded.
396@param[in] heir_block Index page which will inherit the locks
397@param[in] heir_heap_no Heap_no of the record which will inherit the locks
398@param[in] block Index page which will be discarded */
399void lock_update_discard(const buf_block_t *heir_block, ulint heir_heap_no,
400 const buf_block_t *block);
401
402/** Updates the lock table when a new user record is inserted.
403@param[in] block Buffer block containing rec
404@param[in] rec The inserted record */
405void lock_update_insert(const buf_block_t *block, const rec_t *rec);
406
407/** Updates the lock table when a record is removed.
408@param[in] block Buffer block containing rec
409@param[in] rec The record to be removed */
410void lock_update_delete(const buf_block_t *block, const rec_t *rec);
411
412/** Stores on the page infimum record the explicit locks of another record.
413 This function is used to store the lock state of a record when it is
414 updated and the size of the record changes in the update. The record
415 is in such an update moved, perhaps to another page. The infimum record
416 acts as a dummy carrier record, taking care of lock releases while the
417 actual record is being moved. */
419 const buf_block_t *block, /*!< in: buffer block containing rec */
420 const rec_t *rec); /*!< in: record whose lock state
421 is stored on the infimum
422 record of the same page; lock
423 bits are reset on the
424 record */
425
426/** Restores the state of explicit lock requests on a single record, where the
427 state was stored on the infimum of the page.
428@param[in] block Buffer block containing rec
429@param[in] rec Record whose lock state is restored
430@param[in] donator Page (rec is not necessarily on this page) whose infimum
431stored the lock state; lock bits are reset on the infimum */
433 const rec_t *rec,
434 const buf_block_t *donator);
435
436/** Determines if there are explicit record locks on a page.
437@param[in] page_id space id and page number
438@return true iff an explicit record lock on the page exists */
439[[nodiscard]] bool lock_rec_expl_exist_on_page(const page_id_t &page_id);
440/** Checks if locks of other transactions prevent an immediate insert of
441 a record. If they do, first tests if the query thread should anyway
442 be suspended for some reason; if not, then puts the transaction and
443 the query thread to the lock wait state and inserts a waiting request
444 for a gap x-lock to the lock queue.
445 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
447 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is
448 set, does nothing */
449 const rec_t *rec, /*!< in: record after which to insert */
450 buf_block_t *block, /*!< in/out: buffer block of rec */
451 dict_index_t *index, /*!< in: index */
452 que_thr_t *thr, /*!< in: query thread */
453 mtr_t *mtr, /*!< in/out: mini-transaction */
454 bool *inherit); /*!< out: set to true if the new
455 inserted record maybe should inherit
456 LOCK_GAP type locks from the successor
457 record */
458
459/** Checks if locks of other transactions prevent an immediate modify (update,
460 delete mark, or delete unmark) of a clustered index record. If they do,
461 first tests if the query thread should anyway be suspended for some
462 reason; if not, then puts the transaction and the query thread to the
463 lock wait state and inserts a waiting request for a record x-lock to the
464 lock queue.
465 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
467 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
468 bit is set, does nothing */
469 const buf_block_t *block, /*!< in: buffer block of rec */
470 const rec_t *rec, /*!< in: record which should be
471 modified */
472 dict_index_t *index, /*!< in: clustered index */
473 const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
474 que_thr_t *thr); /*!< in: query thread */
475/** Checks if locks of other transactions prevent an immediate modify
476 (delete mark or delete unmark) of a secondary index record.
477 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
479 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
480 bit is set, does nothing */
481 buf_block_t *block, /*!< in/out: buffer block of rec */
482 const rec_t *rec, /*!< in: record which should be
483 modified; NOTE: as this is a secondary
484 index, we always have to modify the
485 clustered index record first: see the
486 comment below */
487 dict_index_t *index, /*!< in: secondary index */
488 que_thr_t *thr, /*!< in: query thread
489 (can be NULL if BTR_NO_LOCKING_FLAG) */
490 mtr_t *mtr); /*!< in/out: mini-transaction */
491
492/** Called to inform lock-sys that a statement processing for a trx has just
493finished.
494@param[in] trx transaction which has finished processing a statement */
496
497/** Used to specify the intended duration of a record lock. */
498enum class lock_duration_t {
499 /** Keep the lock according to the rules of particular isolation level, in
500 particular in case of READ COMMITTED or less restricive modes, do not inherit
501 the lock if the record is purged. */
502 REGULAR = 0,
503 /** Keep the lock around for at least the duration of the current statement,
504 in particular make sure it is inherited as gap lock if the record is purged.*/
506};
507
508/** Like lock_clust_rec_read_check_and_lock(), but reads a
509secondary index record.
510@param[in] duration If equal to AT_LEAST_STATEMENT, then makes sure
511 that the lock will be kept around and inherited
512 for at least the duration of current statement.
513 If equal to REGULAR the life-cycle of the lock
514 will depend on isolation level rules.
515@param[in] block buffer block of rec
516@param[in] rec user record or page supremum record which should
517 be read or passed over by a read cursor
518@param[in] index secondary index
519@param[in] offsets rec_get_offsets(rec, index)
520@param[in] sel_mode select mode: SELECT_ORDINARY,
521 SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
522@param[in] mode mode of the lock which the read cursor should
523 set on records: LOCK_S or LOCK_X; the latter is
524 possible in SELECT FOR UPDATE
525@param[in] gap_mode LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
526@param[in,out] thr query thread
527@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
528DB_SKIP_LOCKED, or DB_LOCK_NOWAIT */
530 const buf_block_t *block,
531 const rec_t *rec, dict_index_t *index,
532 const ulint *offsets,
533 select_mode sel_mode, lock_mode mode,
534 ulint gap_mode, que_thr_t *thr);
535
536/** Checks if locks of other transactions prevent an immediate read, or passing
537over by a read cursor, of a clustered index record. If they do, first tests
538if the query thread should anyway be suspended for some reason; if not, then
539puts the transaction and the query thread to the lock wait state and inserts a
540waiting request for a record lock to the lock queue. Sets the requested mode
541lock on the record.
542@param[in] duration If equal to AT_LEAST_STATEMENT, then makes sure
543 that the lock will be kept around and inherited
544 for at least the duration of current statement.
545 If equal to REGULAR the life-cycle of the lock
546 will depend on isolation level rules.
547@param[in] block buffer block of rec
548@param[in] rec user record or page supremum record which should
549 be read or passed over by a read cursor
550@param[in] index secondary index
551@param[in] offsets rec_get_offsets(rec, index)
552@param[in] sel_mode select mode: SELECT_ORDINARY,
553 SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
554@param[in] mode mode of the lock which the read cursor should
555 set on records: LOCK_S or LOCK_X; the latter is
556 possible in SELECT FOR UPDATE
557@param[in] gap_mode LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
558@param[in,out] thr query thread
559@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
560DB_SKIP_LOCKED, or DB_LOCK_NOWAIT */
562 lock_duration_t duration, const buf_block_t *block, const rec_t *rec,
563 dict_index_t *index, const ulint *offsets, select_mode sel_mode,
564 lock_mode mode, ulint gap_mode, que_thr_t *thr);
565
566/** Checks if locks of other transactions prevent an immediate read, or passing
567 over by a read cursor, of a clustered index record. If they do, first tests
568 if the query thread should anyway be suspended for some reason; if not, then
569 puts the transaction and the query thread to the lock wait state and inserts a
570 waiting request for a record lock to the lock queue. Sets the requested mode
571 lock on the record. This is an alternative version of
572 lock_clust_rec_read_check_and_lock() that does not require the parameter
573 "offsets".
574 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
576 const buf_block_t *block, /*!< in: buffer block of rec */
577 const rec_t *rec, /*!< in: user record or page
578 supremum record which should
579 be read or passed over by a
580 read cursor */
581 dict_index_t *index, /*!< in: clustered index */
582 lock_mode mode, /*!< in: mode of the lock which
583 the read cursor should set on
584 records: LOCK_S or LOCK_X; the
585 latter is possible in
586 SELECT FOR UPDATE */
587 ulint gap_mode, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
588 LOCK_REC_NOT_GAP */
589 que_thr_t *thr); /*!< in: query thread */
590/** Checks that a record is seen in a consistent read.
591 @return true if sees, or false if an earlier version of the record
592 should be retrieved */
594 const rec_t *rec, /*!< in: user record which should be read or
595 passed over by a read cursor */
596 dict_index_t *index, /*!< in: clustered index */
597 const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
598 ReadView *view); /*!< in: consistent read view */
599/** Checks that a non-clustered index record is seen in a consistent read.
600
601 NOTE that a non-clustered index page contains so little information on
602 its modifications that also in the case false, the present version of
603 rec may be the right, but we must check this from the clustered index
604 record.
605
606 @return true if certainly sees, or false if an earlier version of the
607 clustered index record might be needed */
608[[nodiscard]] bool lock_sec_rec_cons_read_sees(
609 const rec_t *rec, /*!< in: user record which
610 should be read or passed over
611 by a read cursor */
612 const dict_index_t *index, /*!< in: index */
613 const ReadView *view); /*!< in: consistent read view */
614/** Locks the specified database table in the mode given. If the lock cannot
615 be granted immediately, the query thread is put to wait.
616 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
617[[nodiscard]] dberr_t lock_table(
618 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set,
619 does nothing */
620 dict_table_t *table, /*!< in/out: database table
621 in dictionary cache */
622 lock_mode mode, /*!< in: lock mode */
623 que_thr_t *thr); /*!< in: query thread */
624
625/** Creates a table IX lock object for a resurrected transaction.
626@param[in,out] table Table
627@param[in,out] trx Transaction */
629
630/** Sets a lock on a table based on the given mode.
631@param[in] table table to lock
632@param[in,out] trx transaction
633@param[in] mode LOCK_X or LOCK_S
634@return error code or DB_SUCCESS. */
635[[nodiscard]] dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx,
636 enum lock_mode mode)
637 MY_ATTRIBUTE((nonnull));
638
639/** Removes a granted record lock of a transaction from the queue and grants
640 locks to other transactions waiting in the queue if they now are entitled
641 to a lock. */
642void lock_rec_unlock(
643 trx_t *trx, /*!< in/out: transaction that has
644 set a record lock */
645 const buf_block_t *block, /*!< in: buffer block containing rec */
646 const rec_t *rec, /*!< in: record */
647 lock_mode lock_mode); /*!< in: LOCK_S or LOCK_X */
648/** Releases a transaction's locks, and releases possible other transactions
649 waiting because of these locks. Change the state of the transaction to
650 TRX_STATE_COMMITTED_IN_MEMORY. */
651void lock_trx_release_locks(trx_t *trx); /*!< in/out: transaction */
652
653/** Release read locks of a transaction. It is called during XA
654prepare to release locks early.
655@param[in,out] trx transaction
656@param[in] only_gap release only GAP locks */
657void lock_trx_release_read_locks(trx_t *trx, bool only_gap);
658
659/** Iterate over the granted locks which conflict with trx->lock.wait_lock and
660prepare the hit list for ASYNC Rollback.
661
662If the transaction is waiting for some other lock then wake up
663with deadlock error. Currently we don't mark following transactions
664for ASYNC Rollback.
665
6661. Read only transactions
6672. Background transactions
6683. Other High priority transactions
669@param[in] trx High Priority transaction
670@param[in,out] hit_list List of transactions which need to be rolled back */
671void lock_make_trx_hit_list(trx_t *trx, hit_list_t &hit_list);
672
673/** Removes locks on a table to be dropped.
674 If remove_also_table_sx_locks is true then table-level S and X locks are
675 also removed in addition to other table-level and record-level locks.
676 No lock, that is going to be removed, is allowed to be a wait lock. */
678 dict_table_t *table, /*!< in: table to be dropped
679 or discarded */
680 bool remove_also_table_sx_locks); /*!< in: also removes
681 table S and X locks */
682
683/** Calculates the hash value of a page file address: used in inserting or
684searching for a lock in the hash table or getting global shard index.
685@param page_id specifies the page
686@return hash value */
687static inline uint64_t lock_rec_hash_value(const page_id_t &page_id);
688
689/** Get the lock hash table */
690static inline hash_table_t *lock_hash_get(ulint mode); /*!< in: lock mode */
691
692/** Looks for a set bit in a record lock bitmap.
693Returns ULINT_UNDEFINED, if none found.
694@param[in] lock A record lock
695@return bit index == heap number of the record, or ULINT_UNDEFINED if none
696found */
698
699/** Looks for the next set bit in the record lock bitmap.
700@param[in] lock record lock with at least one bit set
701@param[in] heap_no current set bit
702@return The next bit index == heap number following heap_no, or ULINT_UNDEFINED
703if none found */
705
706/** Checks if a lock request lock1 has to wait for request lock2.
707@param[in] lock1 A waiting lock
708@param[in] lock2 Another lock;
709 NOTE that it is assumed that this has a lock bit set on the
710 same record as in lock1 if the locks are record lock
711@return true if lock1 has to wait for lock2 to be removed */
712bool lock_has_to_wait(const lock_t *lock1, const lock_t *lock2);
713
714namespace locksys {
715/** An object which can be passed to consecutive calls to
716rec_lock_has_to_wait(trx, mode, lock, is_supremum, trx_locks_cache) for the same
717trx and heap_no (which is implicitly the bit common to all lock objects passed)
718which can be used by this function to cache some partial results. */
720 private:
721 bool m_computed{false};
723#ifdef UNIV_DEBUG
727#endif /* UNIV_DEBUG*/
728 public:
729 /* Checks if trx has a granted lock which is blocking the waiting_lock.
730 @param[in] trx The trx object for which we want to know if one of
731 its granted locks is one of the locks directly
732 blocking the waiting_lock.
733 It must not change between invocations of this
734 method.
735 @param[in] waiting_lock A waiting record lock. Multiple calls to this method
736 must query the same heap_no and page_id. Currently
737 only X and X|REC_NOT_GAP are supported.
738 @return true iff the trx holds a granted record lock which is one of the
739 reasons waiting_lock has to wait.
740 */
741 bool has_granted_blocker(const trx_t *trx, const lock_t *waiting_lock);
742};
743
744/** Checks if a lock request lock1 has to wait for request lock2. It returns the
745same result as @see lock_has_to_wait(lock1, lock2), but in case these are record
746locks, it might use lock1_cache object to speed up the computation.
747If the same lock1_cache is passed to multiple calls of this method, then lock1
748also needs to be the same.
749@param[in] lock1 A waiting lock
750@param[in] lock2 Another lock;
751 NOTE that it is assumed that this has a lock bit set
752 on the same record as in lock1 if the locks are record
753 locks.
754@param[in] lock1_cache An object which can be passed to consecutive calls to
755 this function for the same lock1 which can be used by
756 this function to cache some partial results.
757@return true if lock1 has to wait for lock2 to be removed */
758bool has_to_wait(const lock_t *lock1, const lock_t *lock2,
759 Trx_locks_cache &lock1_cache);
760} // namespace locksys
761
762/** Reports that a transaction id is insensible, i.e., in the future.
763@param[in] trx_id Trx id
764@param[in] rec User record
765@param[in] index Index
766@param[in] offsets Rec_get_offsets(rec, index)
767@param[in] next_trx_id value received from trx_sys_get_next_trx_id_or_no() */
768void lock_report_trx_id_insanity(trx_id_t trx_id, const rec_t *rec,
769 const dict_index_t *index,
770 const ulint *offsets, trx_id_t next_trx_id);
771
772/** Prints info of locks for all transactions.
773@param[in] file file where to print */
775
776/** Prints transaction lock wait and MVCC state.
777@param[in,out] file file where to print
778@param[in] trx transaction */
780
781/** Prints info of locks for each transaction. This function assumes that the
782caller holds the exclusive global latch and more importantly it may release and
783reacquire it on behalf of the caller. (This should be fixed in the future).
784@param[in,out] file the file where to print */
786
787/** Return approximate number or record locks (bits set in the bitmap) for
788 this transaction. Since delete-marked records may be removed, the
789 record count will not be precise.
790 The caller must be holding exclusive global lock_sys latch.
791 @param[in] trx_lock transaction locks
792 */
793[[nodiscard]] ulint lock_number_of_rows_locked(const trx_lock_t *trx_lock);
794
795/** Return the number of table locks for a transaction.
796 The caller must be holding trx->mutex.
797@param[in] trx the transaction for which we want the number of table locks */
798[[nodiscard]] ulint lock_number_of_tables_locked(const trx_t *trx);
799
800/** Gets the type of a lock. Non-inline version for using outside of the
801 lock module.
802 @return LOCK_TABLE or LOCK_REC */
803uint32_t lock_get_type(const lock_t *lock); /*!< in: lock */
804
805/** Gets the id of the transaction owning a lock.
806@param[in] lock A lock of the transaction we are interested in
807@return the transaction's id */
809
810/** Gets the immutable id of the transaction owning a lock
811@param[in] lock A lock of the transaction we are interested in
812@return the transaction's immutable id */
813uint64_t lock_get_trx_immutable_id(const lock_t *lock);
814
815/** Gets the immutable id of this lock.
816@param[in] lock The lock we are interested in
817@return The lock's immutable id */
818uint64_t lock_get_immutable_id(const lock_t *lock);
819
820/** Get the performance schema event (thread_id, event_id)
821that created the lock.
822@param[in] lock Lock
823@param[out] thread_id Thread ID that created the lock
824@param[out] event_id Event ID that created the lock
825*/
827 ulonglong *event_id);
828
829/** Get the first lock of a trx lock list.
830@param[in] trx_lock the trx lock
831@return The first lock
832*/
833const lock_t *lock_get_first_trx_locks(const trx_lock_t *trx_lock);
834
835/** Get the next lock of a trx lock list.
836@param[in] lock the current lock
837@return The next lock
838*/
840
841/** Gets the mode of a lock in a human readable string.
842 The string should not be free()'d or modified.
843 @return lock mode */
844const char *lock_get_mode_str(const lock_t *lock); /*!< in: lock */
845
846/** Gets the type of a lock in a human readable string.
847 The string should not be free()'d or modified.
848 @return lock type */
849const char *lock_get_type_str(const lock_t *lock); /*!< in: lock */
850
851/** Gets the id of the table on which the lock is.
852 @return id of the table */
853table_id_t lock_get_table_id(const lock_t *lock); /*!< in: lock */
854
855/** Determine which table a lock is associated with.
856@param[in] lock the lock
857@return name of the table */
859
860/** For a record lock, gets the index on which the lock is.
861 @return index */
862const dict_index_t *lock_rec_get_index(const lock_t *lock); /*!< in: lock */
863
864/** For a record lock, gets the name of the index on which the lock is.
865 The string should not be free()'d or modified.
866 @return name of the index */
867const char *lock_rec_get_index_name(const lock_t *lock); /*!< in: lock */
868
869/** For a record lock, gets the tablespace number and page number on which the
870lock is.
871 @return tablespace number */
872page_id_t lock_rec_get_page_id(const lock_t *lock); /*!< in: lock */
873
874/** Check if there are any locks (table or rec) against table.
875Returned value might be obsolete.
876@param[in] table the table
877@return true if there were any locks held on records in this table or on the
878table itself at some point in time during the call */
879bool lock_table_has_locks(const dict_table_t *table);
880
881/** A thread which wakes up threads whose lock wait may have lasted too long. */
883
884/** Notifies the thread which analyzes wait-for-graph that there was
885 at least one new edge added or modified ( trx->blocking_trx has changed ),
886 so that the thread will know it has to analyze it. */
888
889/** Puts a user OS thread to wait for a lock to be released. If an error
890 occurs during the wait trx->error_state associated with thr is != DB_SUCCESS
891 when we return. DB_INTERRUPTED, DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
892 are possible errors. DB_DEADLOCK is returned if selective deadlock
893 resolution chose this transaction as a victim. */
894void lock_wait_suspend_thread(que_thr_t *thr); /*!< in: query thread associated
895 with the user OS thread */
896/** Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
897 function should be called at the the end of an SQL statement, by the
898 connection thread that owns the transaction (trx->mysql_thd). */
899void lock_unlock_table_autoinc(trx_t *trx); /*!< in/out: transaction */
900
901/** Cancels the waiting lock request of the trx, if any.
902If the transaction has already committed (trx->version has changed) or is no
903longer waiting for a lock (trx->lock.blocking_trx is nullptr) this function
904will not cancel the waiting lock.
905
906@note There is a possibility of ABA in which a waiting lock request was already
907granted or canceled and then the trx requested another lock and started waiting
908for it - in such case this function might either cancel or not the second
909request depending on timing. Currently all usages of this function ensure that
910this is impossible:
911- innodb_kill_connection ensures trx_is_interrupted(trx), thus upon first wake
912up it will realize it has to report an error and rollback
913- HP transaction marks the trx->in_innodb & TRX_FORCE_ROLLBACK flag which is
914checked when the trx attempts RecLock::add_to_waitq and reports DB_DEADLOCK
915
916@param[in] trx_version The trx we want to wake up and its expected
917 version
918@return true iff the function did release a waiting lock
919*/
921
922/** Set the lock system timeout event. */
924
925/** Checks that a transaction id is sensible, i.e., not in the future.
926Emits an error otherwise.
927@param[in] trx_id The trx id to check, found in user record or secondary
928 index page header
929@param[in] rec The user record which contained the trx_id in its header
930 or in header of its page
931@param[in] index The index which contained the rec
932@param[in] offsets The result of rec_get_offsets(rec, index)
933@return true iff ok */
934bool lock_check_trx_id_sanity(trx_id_t trx_id, const rec_t *rec,
935 const dict_index_t *index, const ulint *offsets);
936
937#ifdef UNIV_DEBUG
938/** Check if the transaction holds an exclusive lock on a record.
939@param[in] thr query thread of the transaction
940@param[in] table table to check
941@param[in] block buffer block of the record
942@param[in] heap_no record heap number
943@return whether the locks are held */
944[[nodiscard]] bool lock_trx_has_rec_x_lock(que_thr_t *thr,
945 const dict_table_t *table,
946 const buf_block_t *block,
947 ulint heap_no);
948
949/** Validates the lock system.
950 @return true if ok */
951bool lock_validate();
952#endif /* UNIV_DEBUG */
953
954/**
955Allocate cached locks for the transaction.
956@param trx allocate cached record locks for this transaction */
957void lock_trx_alloc_locks(trx_t *trx);
958
959/** Lock modes and types */
960/** @{ */
961/** mask used to extract mode from the type_mode field in a lock */
962constexpr uint32_t LOCK_MODE_MASK = 0xF;
963/** Lock types */
964/** table lock */
965constexpr uint32_t LOCK_TABLE = 16;
966/** record lock */
967constexpr uint32_t LOCK_REC = 32;
968/** mask used to extract lock type from the type_mode field in a lock */
969constexpr uint32_t LOCK_TYPE_MASK = 0xF0UL;
970static_assert((LOCK_MODE_MASK & LOCK_TYPE_MASK) == 0,
971 "LOCK_MODE_MASK & LOCK_TYPE_MASK");
972
973/** Waiting lock flag; when set, it means that the lock has not yet been
974 granted, it is just waiting for its turn in the wait queue */
975constexpr uint32_t LOCK_WAIT = 256;
976/* Precise modes */
977/** this flag denotes an ordinary next-key lock in contrast to LOCK_GAP or
978 LOCK_REC_NOT_GAP */
979constexpr uint32_t LOCK_ORDINARY = 0;
980/** when this bit is set, it means that the lock holds only on the gap before
981 the record; for instance, an x-lock on the gap does not give permission to
982 modify the record on which the bit is set; locks of this type are created
983 when records are removed from the index chain of records */
984constexpr uint32_t LOCK_GAP = 512;
985/** this bit means that the lock is only on the index record and does NOT
986 block inserts to the gap before the index record; this is used in the case
987 when we retrieve a record with a unique key, and is also used in locking
988 plain SELECTs (not part of UPDATE or DELETE) when the user has set the READ
989 COMMITTED isolation level */
990constexpr uint32_t LOCK_REC_NOT_GAP = 1024;
991/** this bit is set when we place a waiting gap type record lock request in
992 order to let an insert of an index record to wait until there are no
993 conflicting locks by other transactions on the gap; note that this flag
994 remains set when the waiting lock is granted, or if the lock is inherited to
995 a neighboring record */
996constexpr uint32_t LOCK_INSERT_INTENTION = 2048;
997/** Predicate lock */
998constexpr uint32_t LOCK_PREDICATE = 8192;
999/** Page lock */
1000constexpr uint32_t LOCK_PRDT_PAGE = 16384;
1001
1002static_assert(
1005 LOCK_MODE_MASK) == 0,
1006 "(LOCK_WAIT | LOCK_GAP | LOCK_REC_NOT_GAP | LOCK_INSERT_INTENTION | "
1007 "LOCK_PREDICATE | LOCK_PRDT_PAGE) & LOCK_TYPE_MASK");
1008/** @} */
1009
1010/** Lock operation struct */
1012 dict_table_t *table; /*!< table to be locked */
1013 lock_mode mode; /*!< lock mode */
1014};
1015
1016typedef ib_mutex_t Lock_mutex;
1017
1018/** The lock system struct */
1020 /** The latches protecting queues of record and table locks */
1022
1023 /** The hash table of the record (LOCK_REC) locks, except for predicate
1024 (LOCK_PREDICATE) and predicate page (LOCK_PRDT_PAGE) locks */
1026
1027 /** The hash table of predicate (LOCK_PREDICATE) locks */
1029
1030 /** The hash table of the predicate page (LOCK_PRD_PAGE) locks */
1032
1033 /** Padding to avoid false sharing of wait_mutex field */
1035
1036 /** The mutex protecting the next two fields */
1038
1039 /** Array of user threads suspended while waiting for locks within InnoDB.
1040 Protected by the lock_sys->wait_mutex. */
1042
1043 /** The highest slot ever used in the waiting_threads array.
1044 Protected by lock_sys->wait_mutex. */
1046
1047 /** true if rollback of all recovered transactions is complete.
1048 Protected by exclusive global lock_sys latch. */
1050
1051 /** Max lock wait time observed, for innodb_row_lock_time_max reporting. */
1052 std::chrono::steady_clock::duration n_lock_max_wait_time;
1053
1054 /** Set to the event that is created in the lock wait monitor thread. A value
1055 of 0 means the thread is not active */
1057
1058#ifdef UNIV_DEBUG
1059 /** Lock timestamp counter, used to assign lock->m_seq on creation. */
1060 std::atomic<uint64_t> m_seq;
1061#endif /* UNIV_DEBUG */
1062};
1063
1064/** If a transaction has an implicit x-lock on a record, but no explicit x-lock
1065set on the record, sets one for it.
1066@param[in] block buffer block of rec
1067@param[in] rec user record on page
1068@param[in] index index of record
1069@param[in] offsets rec_get_offsets(rec, index) */
1070void lock_rec_convert_impl_to_expl(const buf_block_t *block, const rec_t *rec,
1071 dict_index_t *index, const ulint *offsets);
1072
1073/** Removes a record lock request, waiting or granted, from the queue. */
1074void lock_rec_discard(lock_t *in_lock); /*!< in: record lock object: all
1075 record locks which are contained
1076 in this lock object are removed */
1077
1078/** Moves the explicit locks on user records to another page if a record
1079 list start is moved to another page.
1080@param[in] new_block Index page to move to
1081@param[in] block Index page
1082@param[in] rec_move Recording records moved
1083@param[in] num_move Num of rec to move */
1084void lock_rtr_move_rec_list(const buf_block_t *new_block,
1085 const buf_block_t *block, rtr_rec_move_t *rec_move,
1086 ulint num_move);
1087
1088/** Removes record lock objects set on an index page which is discarded. This
1089 function does not move locks, or check for waiting locks, therefore the
1090 lock bitmaps must already be reset when this function is called. */
1092 const buf_block_t *block); /*!< in: page to be discarded */
1093
1094/** Reset the nth bit of a record lock.
1095@param[in,out] lock record lock
1096@param[in] i index of the bit that will be reset
1097@param[in] type whether the lock is in wait mode */
1099
1100/** The lock system */
1101extern lock_sys_t *lock_sys;
1102
1103#ifdef UNIV_DEBUG
1104/** Test if lock_sys->wait_mutex is owned. */
1105static inline bool lock_wait_mutex_own() {
1106 return lock_sys->wait_mutex.is_owned();
1107}
1108#endif
1109
1110/** Acquire the lock_sys->wait_mutex. */
1111static inline void lock_wait_mutex_enter() {
1113}
1114/** Release the lock_sys->wait_mutex. */
1115static inline void lock_wait_mutex_exit() { lock_sys->wait_mutex.exit(); }
1116
1117#include "lock0lock.ic"
1118
1119namespace locksys {
1120
1121/* OWNERSHIP TESTS */
1122#ifdef UNIV_DEBUG
1123
1124/**
1125Tests if lock_sys latch is exclusively owned by the current thread.
1126@return true iff the current thread owns exclusive global lock_sys latch
1127*/
1129
1130/**
1131Tests if lock_sys latch is owned in shared mode by the current thread.
1132@return true iff the current thread owns shared global lock_sys latch
1133*/
1135
1136/**
1137Tests if given page shard can be safely accessed by the current thread.
1138@param page_id specifies the page
1139@return true iff the current thread owns exclusive global lock_sys latch or both
1140a shared global lock_sys latch and mutex protecting the page shard
1141*/
1142bool owns_page_shard(const page_id_t &page_id);
1143
1144/**
1145Test if given table shard can be safely accessed by the current thread.
1146@param table the table
1147@return true iff the current thread owns exclusive global lock_sys latch or
1148both a shared global lock_sys latch and mutex protecting the table shard
1149*/
1150bool owns_table_shard(const dict_table_t &table);
1151
1152/** Checks if shard which contains lock is latched (or that an exclusive latch
1153on whole lock_sys is held) by current thread
1154@param[in] lock lock which belongs to a shard we want to check
1155@return true iff the current thread owns exclusive global lock_sys latch or
1156both a shared global lock_sys latch and mutex protecting the shard
1157containing the specified lock */
1158bool owns_lock_shard(const lock_t *lock);
1159
1160#endif /* UNIV_DEBUG */
1161
1162} // namespace locksys
1163
1164#include "lock0guards.h"
1165
1166#endif
The database buffer pool global types for the directory.
Read view lists the trx ids of those transactions for which a consistent read should not see the modi...
Definition: read0types.h:47
Definition: hash0hash.h:373
The class which handles the logic of latching of lock_sys queues themselves.
Definition: lock0latches.h:102
An object which can be passed to consecutive calls to rec_lock_has_to_wait(trx, mode,...
Definition: lock0lock.h:719
page_id_t m_cached_page_id
Definition: lock0lock.h:725
bool m_computed
Definition: lock0lock.h:721
bool has_granted_blocker(const trx_t *trx, const lock_t *waiting_lock)
Definition: lock0lock.cc:845
const trx_t * m_cached_trx
Definition: lock0lock.h:724
bool m_has_s_lock_on_record
Definition: lock0lock.h:722
size_t m_cached_heap_no
Definition: lock0lock.h:726
Page identifier.
Definition: buf0types.h:206
dberr_t
Definition: db0err.h:38
Data dictionary global types.
ib_id_t table_id_t
Table or partition identifier (unique within an InnoDB instance).
Definition: dict0types.h:217
R-tree header file.
The simple hash table utility.
static int flags[50]
Definition: hp_test1.cc:39
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:229
constexpr uint32_t LOCK_PRDT_PAGE
Page lock.
Definition: lock0lock.h:1000
uint64_t lock_get_trx_immutable_id(const lock_t *lock)
Gets the immutable id of the transaction owning a lock.
Definition: lock0lock.cc:5876
const char * lock_get_type_str(const lock_t *lock)
Gets the type of a lock in a human readable string.
Definition: lock0lock.cc:6001
uint64_t lock_get_immutable_id(const lock_t *lock)
Gets the immutable id of this lock.
Definition: lock0lock.cc:5884
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:3175
void lock_trx_release_locks(trx_t *trx)
Releases a transaction's locks, and releases possible other transactions waiting because of these loc...
Definition: lock0lock.cc:6146
bool lock_rec_expl_exist_on_page(const page_id_t &page_id)
Determines if there are explicit record locks on a page.
Definition: lock0lock.cc:728
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:3256
void lock_sys_close(void)
Closes the lock system at database shutdown.
Definition: lock0lock.cc:379
constexpr uint32_t LOCK_MODE_MASK
Lock modes and types.
Definition: lock0lock.h:962
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:2044
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 next_trx_id)
Reports that a transaction id is insensible, i.e., in the future.
Definition: lock0lock.cc:201
static void lock_wait_mutex_exit()
Release the lock_sys->wait_mutex.
Definition: lock0lock.h:1115
uint32_t lock_get_type(const lock_t *lock)
Gets the type of a lock.
Definition: lock0lock.cc:5871
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:3997
void lock_print_info_summary(FILE *file)
Prints info of locks for all transactions.
Definition: lock0lock.cc:4626
constexpr uint32_t LOCK_PREDICATE
Predicate lock.
Definition: lock0lock.h:998
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:3305
constexpr uint32_t LOCK_WAIT
Waiting lock flag; when set, it means that the lock has not yet been granted, it is just waiting for ...
Definition: lock0lock.h:975
static ulint lock_get_min_heap_no(const buf_block_t *block)
Gets the heap_no of the smallest user record on a page.
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:6049
static uint64_t lock_rec_hash_value(const page_id_t &page_id)
Calculates the hash value of a page file address: used in inserting or searching for a lock in the ha...
ulint lock_get_size(void)
Gets the size of a lock struct.
Definition: lock0lock.cc:414
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:3003
bool lock_validate()
Validates the lock system.
Definition: lock0lock.cc:5299
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:266
constexpr uint32_t LOCK_ORDINARY
this flag denotes an ordinary next-key lock in contrast to LOCK_GAP or LOCK_REC_NOT_GAP
Definition: lock0lock.h:979
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:5775
void lock_unlock_table_autoinc(trx_t *trx)
Unlocks AUTO_INC type locks that were possibly reserved by a trx.
Definition: lock0lock.cc:6092
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:2470
void lock_sys_resize(ulint n_cells)
Resize the lock hash tables.
Definition: lock0lock.cc:339
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:3363
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:5715
void lock_sys_create(ulint n_cells)
Creates the lock system at database start.
Definition: lock0lock.cc:298
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:683
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:6060
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
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:2826
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:3148
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:5666
const table_name_t & lock_get_table_name(const lock_t *lock)
Determine which table a lock is associated with.
Definition: lock0lock.cc:6043
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:195
void lock_rec_convert_impl_to_expl(const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets)
If a transaction has an implicit x-lock on a record, but no explicit x-lock set on the record,...
Definition: lock0lock.cc:5507
const lock_t * lock_get_next_trx_locks(const lock_t *lock)
Get the next lock of a trx lock list.
Definition: lock0lock.cc:5922
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:6031
bool innobase_deadlock_detect
Definition: lock0lock.cc:69
void lock_wait_timeout_thread()
A thread which wakes up threads whose lock wait may have lasted too long.
Definition: lock0wait.cc:1432
void lock_trx_release_read_locks(trx_t *trx, bool only_gap)
Release read locks of a transaction.
Definition: lock0lock.cc:4257
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:2917
ulint lock_number_of_tables_locked(const trx_t *trx)
Return the number of table locks for a transaction.
Definition: lock0lock.cc:1120
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:3797
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:3929
constexpr uint32_t LOCK_TYPE_MASK
mask used to extract lock type from the type_mode field in a lock
Definition: lock0lock.h:969
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:3099
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: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:3074
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, bool *inherit)
Checks if locks of other transactions prevent an immediate insert of a record.
Definition: lock0lock.cc:5342
constexpr uint32_t LOCK_INSERT_INTENTION
this bit is set when we place a waiting gap type record lock request in order to let an insert of an ...
Definition: lock0lock.h:996
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:3194
constexpr uint32_t LOCK_TABLE
Lock types.
Definition: lock0lock.h:965
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:3331
void lock_trx_print_wait_and_mvcc_state(FILE *file, const trx_t *trx)
Prints transaction lock wait and MVCC state.
Definition: lock0lock.cc:4815
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:3132
ib_mutex_t Lock_mutex
Definition: lock0lock.h:1016
page_id_t lock_rec_get_page_id(const lock_t *lock)
For a record lock, gets the tablespace number and page number on which the lock is.
Definition: lock0lock.cc:6068
bool lock_cancel_if_waiting_and_release(TrxVersion trx_version)
Cancels the waiting lock request of the trx, if any.
Definition: lock0lock.cc:6199
static void lock_wait_mutex_enter()
Acquire the lock_sys->wait_mutex.
Definition: lock0lock.h:1111
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:5556
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:212
const char * lock_get_mode_str(const lock_t *lock)
Gets the mode of a lock in a human readable string.
Definition: lock0lock.cc:5944
void lock_print_info_all_transactions(FILE *file)
Prints info of locks for each transaction.
Definition: lock0lock.cc:4957
trx_id_t lock_get_trx_id(const lock_t *lock)
Gets the id of the transaction owning a lock.
Definition: lock0lock.cc:5880
static bool lock_wait_mutex_own()
Test if lock_sys->wait_mutex is owned.
Definition: lock0lock.h:1105
lock_sys_t * lock_sys
The lock system.
Definition: lock0lock.cc:191
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:2520
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:2716
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:5894
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:3242
ulint lock_rec_find_set_bit(const lock_t *lock)
Looks for a set bit in a record lock bitmap.
Definition: lock0lock.cc:647
static hash_table_t * lock_hash_get(ulint mode)
Get the lock hash table.
void lock_update_split_point(const buf_block_t *right_block, const buf_block_t *left_block)
Requests the Lock System to update record locks regarding the gap between the last record of the left...
Definition: lock0lock.cc:3159
void lock_rec_trx_wait(lock_t *lock, ulint i, ulint type)
Reset the nth bit of a record lock.
Definition: lock0lock.cc:720
lock_duration_t
Used to specify the intended duration of a record lock.
Definition: lock0lock.h:498
@ AT_LEAST_STATEMENT
Keep the lock around for at least the duration of the current statement, in particular make sure it i...
@ REGULAR
Keep the lock according to the rules of particular isolation level, in particular in case of READ COM...
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:5608
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:3693
constexpr uint32_t LOCK_GAP
when this bit is set, it means that the lock holds only on the gap before the record; for instance,...
Definition: lock0lock.h:984
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:197
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:3386
constexpr uint32_t LOCK_REC_NOT_GAP
this bit means that the lock is only on the index record and does NOT block inserts to the gap before...
Definition: lock0lock.h:990
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:614
void lock_rec_discard(lock_t *in_lock)
Removes a record lock request, waiting or granted, from the queue.
Definition: lock0lock.cc:2419
void lock_remove_all_on_table(dict_table_t *table, bool remove_also_table_sx_locks)
Removes locks on a table to be dropped.
Definition: lock0lock.cc:4450
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:1111
void lock_set_timeout_event()
Set the lock system timeout event.
Definition: lock0lock.cc:6292
constexpr uint32_t LOCK_REC
record lock
Definition: lock0lock.h:967
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:5909
void lock_trx_alloc_locks(trx_t *trx)
Allocate cached locks for the transaction.
Definition: lock0lock.cc:6499
The transaction lock system.
The predicate lock system.
The transaction lock system global types.
select_mode
Definition: lock0types.h:44
lock_mode
Definition: lock0types.h:51
Mini-transaction buffer global types.
unsigned long long int ulonglong
Definition: my_inttypes.h:55
static my_thread_id thread_id
Definition: my_thr_init.cc:62
const std::string FILE("FILE")
Definition: os0file.h:85
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:78
Definition: lock0guards.h:33
bool owns_page_shard(const page_id_t &page_id)
Tests if given page shard can be safely accessed by the current thread.
Definition: lock0lock.cc:167
bool owns_table_shard(const dict_table_t &table)
Test if given table shard can be safely accessed by the current thread.
Definition: lock0lock.cc:171
bool owns_shared_global_latch()
Tests if lock_sys latch is owned in shared mode by the current thread.
Definition: lock0lock.cc:163
bool owns_lock_shard(const lock_t *lock)
Checks if shard which contains lock is latched (or that an exclusive latch on whole lock_sys is held)...
Definition: lock0lock.cc:175
bool owns_exclusive_global_latch()
Tests if lock_sys latch is exclusively owned by the current thread.
Definition: lock0lock.cc:159
bool has_to_wait(const lock_t *lock1, const lock_t *lock2, Trx_locks_cache &lock1_cache)
Checks if a lock request lock1 has to wait for request lock2.
Definition: lock0lock.cc:597
mode
Definition: file_handle.h:59
constexpr size_t INNODB_CACHE_LINE_SIZE
CPU cache line size.
Definition: ut0cpu_cache.h:40
Query graph global types.
Record manager global types.
byte rec_t
Definition: rem0types.h:40
required string type
Definition: replication_group_member_actions.proto:33
The server main program.
Definition: trx0types.h:597
The buffer control block structure.
Definition: buf0buf.h:1664
Data structure for an index.
Definition: dict0mem.h:1021
Data structure for a database table.
Definition: dict0mem.h:1884
Lock operation struct.
Definition: lock0lock.h:1011
dict_table_t * table
table to be locked
Definition: lock0lock.h:1012
lock_mode mode
lock mode
Definition: lock0lock.h:1013
The lock system struct.
Definition: lock0lock.h:1019
locksys::Latches latches
The latches protecting queues of record and table locks.
Definition: lock0lock.h:1021
hash_table_t * prdt_page_hash
The hash table of the predicate page (LOCK_PRD_PAGE) locks.
Definition: lock0lock.h:1031
char pad2[ut::INNODB_CACHE_LINE_SIZE]
Padding to avoid false sharing of wait_mutex field.
Definition: lock0lock.h:1034
hash_table_t * rec_hash
The hash table of the record (LOCK_REC) locks, except for predicate (LOCK_PREDICATE) and predicate pa...
Definition: lock0lock.h:1025
srv_slot_t * last_slot
The highest slot ever used in the waiting_threads array.
Definition: lock0lock.h:1045
bool rollback_complete
true if rollback of all recovered transactions is complete.
Definition: lock0lock.h:1049
srv_slot_t * waiting_threads
Array of user threads suspended while waiting for locks within InnoDB.
Definition: lock0lock.h:1041
hash_table_t * prdt_hash
The hash table of predicate (LOCK_PREDICATE) locks.
Definition: lock0lock.h:1028
Lock_mutex wait_mutex
The mutex protecting the next two fields.
Definition: lock0lock.h:1037
std::chrono::steady_clock::duration n_lock_max_wait_time
Max lock wait time observed, for innodb_row_lock_time_max reporting.
Definition: lock0lock.h:1052
os_event_t timeout_event
Set to the event that is created in the lock wait monitor thread.
Definition: lock0lock.h:1056
std::atomic< uint64_t > m_seq
Lock timestamp counter, used to assign lock->m_seq on creation.
Definition: lock0lock.h:1060
Lock struct; protected by lock_sys latches.
Definition: lock0priv.h:135
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:181
InnoDB condition variable.
Definition: os0event.cc:62
Definition: que0que.h:241
Definition: gis0type.h:166
Thread slot in the thread table.
Definition: srv0srv.h:1213
Table name wrapper for pretty-printing.
Definition: dict0mem.h:455
Latching protocol for trx_lock_t::que_state.
Definition: trx0trx.h:406
Definition: trx0trx.h:680
Transaction system global type definitions.
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:137
std::vector< TrxVersion, ut::allocator< TrxVersion > > hit_list_t
Definition: trx0types.h:604
Version control for database, common definitions, and include files.
unsigned long int ulint
Definition: univ.i:407
#define mutex_enter(M)
Definition: ut0mutex.h:116
A vector of pointers to data items.