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