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