MySQL 8.0.40
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/** Allocates memory suitable for holding a lock_t from specified heap.
252The allocated memory has additional bitmap_bytes right after the returned
253lock_t instance for holding the bitmap used by LOCK_REC type.
254@param[in] heap
255 The heap to allocate the memory from
256@param[in] bitmap_bytes
257 The number of bytes to reserve right after the lock_t struct
258 for the bitmap. Defaults to 0, which is ok for LOCK_TABLE.
259@return A pointer to the memory allocated from the heap, aligned as lock_t,
260and of size sizeof(lock_t)+bitmap_bytes. Note that it can contain garbage,
261so it is caller's responsibility to initialize lock_t and the bitmap. */
262lock_t *lock_alloc_from_heap(mem_heap_t *heap, size_t bitmap_bytes = 0);
263
264/** Creates the lock system at database start. */
265void lock_sys_create(
266 ulint n_cells); /*!< in: number of slots in lock hash table */
267
268/** Resize the lock hash tables.
269@param[in] n_cells number of slots in lock hash table */
270void lock_sys_resize(ulint n_cells);
271
272/** Closes the lock system at database shutdown. */
273void lock_sys_close(void);
274/** Gets the heap_no of the smallest user record on a page.
275 @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
277 const buf_block_t *block); /*!< in: buffer block */
278/** Updates the lock table when we have reorganized a page. NOTE: we copy
279 also the locks set on the infimum of the page; the infimum may carry
280 locks if an update of a record is occurring on the page, and its locks
281 were temporarily stored on the infimum. */
283 const buf_block_t *block, /*!< in: old index page, now
284 reorganized */
285 const buf_block_t *oblock); /*!< in: copy of the old, not
286 reorganized page */
287
288/** Moves the explicit locks on user records to another page if a record
289list end is moved to another page.
290@param[in] new_block Index page to move to
291@param[in] block Index page
292@param[in,out] rec Record on page: this is the first record moved */
293void lock_move_rec_list_end(const buf_block_t *new_block,
294 const buf_block_t *block, const rec_t *rec);
295
296/** Moves the explicit locks on user records to another page if a record
297 list start is moved to another page.
298@param[in] new_block Index page to move to
299@param[in] block Index page
300@param[in,out] rec Record on page: this is the first record not copied
301@param[in] old_end Old previous-to-last record on new_page before the records
302were copied */
303void lock_move_rec_list_start(const buf_block_t *new_block,
304 const buf_block_t *block, const rec_t *rec,
305 const rec_t *old_end);
306
307/** Updates the lock table when a page is split to the right.
308@param[in] right_block Right page
309@param[in] left_block Left page */
310void lock_update_split_right(const buf_block_t *right_block,
311 const buf_block_t *left_block);
312
313/** Updates the lock table when a page is merged to the right.
314@param[in] right_block Right page to which merged
315@param[in] orig_succ Original successor of infimum on the right page before
316merge
317@param[in] left_block Merged index page which will be discarded */
318void lock_update_merge_right(const buf_block_t *right_block,
319 const rec_t *orig_succ,
320 const buf_block_t *left_block);
321
322/** Updates the lock table when the root page is copied to another in
323 btr_root_raise_and_insert. Note that we leave lock structs on the
324 root page, even though they do not make sense on other than leaf
325 pages: the reason is that in a pessimistic update the infimum record
326 of the root page will act as a dummy carrier of the locks of the record
327 to be updated. */
329 const buf_block_t *block, /*!< in: index page to which copied */
330 const buf_block_t *root); /*!< in: root page */
331
332/** Updates the lock table when a page is copied to another and the original
333 page is removed from the chain of leaf pages, except if page is the root!
334@param[in] new_block Index page to which copied
335@param[in] block Index page; not the root! */
336void lock_update_copy_and_discard(const buf_block_t *new_block,
337 const buf_block_t *block);
338
339/** Requests the Lock System to update record locks regarding the gap between
340the last record of the left_page and the first record of the right_page when the
341caller is about to prepended a new record as the first record on the right page,
342even though it should "naturally" be inserted as the last record of the
343left_page according to the information in the higher levels of the index.
344
345That is, we assume that the lowest common ancestor of the left_page and the
346right_page routes the key of the new record to the left_page, but a heuristic
347which tries to avoid overflowing the left_page has chosen to prepend the new
348record to the right_page instead. Said ancestor performs this routing by
349comparing the key of the record to a "split point" - the key associated with the
350right_page's subtree, such that all records larger than that split point are to
351be found in the right_page (or some even further page). Ideally this should be
352the minimum key in this whole subtree, however due to the way we optimize the
353DELETE and INSERT operations, we often do not update this information, so that
354such "split point" can actually be smaller than the real minimum. Still, even if
355not up-to-date, its value is always correct, in that it really separates the
356subtrees (keys smaller than "split point" are not in left_page and larger are
357not in right_page).
358
359The reason this is important to Lock System, is that the gap between the last
360record on the left_page and the first record on the right_page is represented as
361two gaps:
3621. The gap between the last record on the left_page and the "split point",
363represented as the gap before the supremum pseudo-record of the left_page.
3642. The gap between the "split point" and the first record of the right_page,
365represented as the gap before the first user record of the right_page.
366
367Thus, inserting the new record, and subsequently adjusting "split points" in its
368ancestors to values smaller or equal to the new records' key, will mean that gap
369will be sliced at a different place ("moved to the left"): fragment of the 1st
370gap will now become treated as 2nd. Therefore, Lock System must copy any GRANTED
371locks from 1st gap to the 2nd gap. Any WAITING locks must be of INSERT_INTENTION
372type (as no other GAP locks ever wait for anything) and can stay at 1st gap, as
373their only purpose is to notify the requester they can retry insertion, and
374there's no correctness requirement to avoid waking them up too soon.
375
376@param[in] right_block Right page
377@param[in] left_block Left page */
378void lock_update_split_point(const buf_block_t *right_block,
379 const buf_block_t *left_block);
380
381/** Updates the lock table when a page is split to the left.
382@param[in] right_block Right page
383@param[in] left_block Left page */
384void lock_update_split_left(const buf_block_t *right_block,
385 const buf_block_t *left_block);
386
387/** Updates the lock table when a page is merged to the left.
388@param[in] left_block Left page to which merged
389@param[in] orig_pred Original predecessor of supremum on the left page before
390merge
391@param[in] right_block Merged index page which will be discarded */
392void lock_update_merge_left(const buf_block_t *left_block,
393 const rec_t *orig_pred,
394 const buf_block_t *right_block);
395
396/** Resets the original locks on heir and replaces them with gap type locks
397 inherited from rec.
398@param[in] heir_block Block containing the record which inherits
399@param[in] block Block containing the record from which inherited; does not
400reset the locks on this record
401@param[in] heir_heap_no Heap_no of the inheriting record
402@param[in] heap_no Heap_no of the donating record */
404 const buf_block_t *block,
405 ulint heir_heap_no, ulint heap_no);
406
407/** Updates the lock table when a page is discarded.
408@param[in] heir_block Index page which will inherit the locks
409@param[in] heir_heap_no Heap_no of the record which will inherit the locks
410@param[in] block Index page which will be discarded */
411void lock_update_discard(const buf_block_t *heir_block, ulint heir_heap_no,
412 const buf_block_t *block);
413
414/** Updates the lock table when a new user record is inserted.
415@param[in] block Buffer block containing rec
416@param[in] rec The inserted record */
417void lock_update_insert(const buf_block_t *block, const rec_t *rec);
418
419/** Updates the lock table when a record is removed.
420@param[in] block Buffer block containing rec
421@param[in] rec The record to be removed */
422void lock_update_delete(const buf_block_t *block, const rec_t *rec);
423
424/** Stores on the page infimum record the explicit locks of another record.
425 This function is used to store the lock state of a record when it is
426 updated and the size of the record changes in the update. The record
427 is in such an update moved, perhaps to another page. The infimum record
428 acts as a dummy carrier record, taking care of lock releases while the
429 actual record is being moved. */
431 const buf_block_t *block, /*!< in: buffer block containing rec */
432 const rec_t *rec); /*!< in: record whose lock state
433 is stored on the infimum
434 record of the same page; lock
435 bits are reset on the
436 record */
437
438/** Restores the state of explicit lock requests on a single record, where the
439 state was stored on the infimum of the page.
440@param[in] block Buffer block containing rec
441@param[in] rec Record whose lock state is restored
442@param[in] donator Page (rec is not necessarily on this page) whose infimum
443stored the lock state; lock bits are reset on the infimum */
445 const rec_t *rec,
446 const buf_block_t *donator);
447
448/** Determines if there are explicit record locks on a page.
449@param[in] page_id space id and page number
450@return true iff an explicit record lock on the page exists */
451[[nodiscard]] bool lock_rec_expl_exist_on_page(const page_id_t &page_id);
452/** Checks if locks of other transactions prevent an immediate insert of
453 a record. If they do, first tests if the query thread should anyway
454 be suspended for some reason; if not, then puts the transaction and
455 the query thread to the lock wait state and inserts a waiting request
456 for a gap x-lock to the lock queue.
457 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
459 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is
460 set, does nothing */
461 const rec_t *rec, /*!< in: record after which to insert */
462 buf_block_t *block, /*!< in/out: buffer block of rec */
463 dict_index_t *index, /*!< in: index */
464 que_thr_t *thr, /*!< in: query thread */
465 mtr_t *mtr, /*!< in/out: mini-transaction */
466 bool *inherit); /*!< out: set to true if the new
467 inserted record maybe should inherit
468 LOCK_GAP type locks from the successor
469 record */
470
471/** Checks if locks of other transactions prevent an immediate modify (update,
472 delete mark, or delete unmark) of a clustered index record. If they do,
473 first tests if the query thread should anyway be suspended for some
474 reason; if not, then puts the transaction and the query thread to the
475 lock wait state and inserts a waiting request for a record x-lock to the
476 lock queue.
477 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
479 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
480 bit is set, does nothing */
481 const buf_block_t *block, /*!< in: buffer block of rec */
482 const rec_t *rec, /*!< in: record which should be
483 modified */
484 dict_index_t *index, /*!< in: clustered index */
485 const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
486 que_thr_t *thr); /*!< in: query thread */
487/** Checks if locks of other transactions prevent an immediate modify
488 (delete mark or delete unmark) of a secondary index record.
489 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
491 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
492 bit is set, does nothing */
493 buf_block_t *block, /*!< in/out: buffer block of rec */
494 const rec_t *rec, /*!< in: record which should be
495 modified; NOTE: as this is a secondary
496 index, we always have to modify the
497 clustered index record first: see the
498 comment below */
499 dict_index_t *index, /*!< in: secondary index */
500 que_thr_t *thr, /*!< in: query thread
501 (can be NULL if BTR_NO_LOCKING_FLAG) */
502 mtr_t *mtr); /*!< in/out: mini-transaction */
503
504/** Called to inform lock-sys that a statement processing for a trx has just
505finished.
506@param[in] trx transaction which has finished processing a statement */
508
509/** Used to specify the intended duration of a record lock. */
510enum class lock_duration_t {
511 /** Keep the lock according to the rules of particular isolation level, in
512 particular in case of READ COMMITTED or less restricive modes, do not inherit
513 the lock if the record is purged. */
514 REGULAR = 0,
515 /** Keep the lock around for at least the duration of the current statement,
516 in particular make sure it is inherited as gap lock if the record is purged.*/
518};
519
520/** Like lock_clust_rec_read_check_and_lock(), but reads a
521secondary index record.
522@param[in] duration If equal to AT_LEAST_STATEMENT, then makes sure
523 that the lock will be kept around and inherited
524 for at least the duration of current statement.
525 If equal to REGULAR the life-cycle of the lock
526 will depend on isolation level rules.
527@param[in] block buffer block of rec
528@param[in] rec user record or page supremum record which should
529 be read or passed over by a read cursor
530@param[in] index secondary index
531@param[in] offsets rec_get_offsets(rec, index)
532@param[in] sel_mode select mode: SELECT_ORDINARY,
533 SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
534@param[in] mode mode of the lock which the read cursor should
535 set on records: LOCK_S or LOCK_X; the latter is
536 possible in SELECT FOR UPDATE
537@param[in] gap_mode LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
538@param[in,out] thr query thread
539@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
540DB_SKIP_LOCKED, or DB_LOCK_NOWAIT */
542 const buf_block_t *block,
543 const rec_t *rec, dict_index_t *index,
544 const ulint *offsets,
545 select_mode sel_mode, lock_mode mode,
546 ulint gap_mode, que_thr_t *thr);
547
548/** Checks if locks of other transactions prevent an immediate read, or passing
549over by a read cursor, of a clustered index record. If they do, first tests
550if the query thread should anyway be suspended for some reason; if not, then
551puts the transaction and the query thread to the lock wait state and inserts a
552waiting request for a record lock to the lock queue. Sets the requested mode
553lock on the record.
554@param[in] duration If equal to AT_LEAST_STATEMENT, then makes sure
555 that the lock will be kept around and inherited
556 for at least the duration of current statement.
557 If equal to REGULAR the life-cycle of the lock
558 will depend on isolation level rules.
559@param[in] block buffer block of rec
560@param[in] rec user record or page supremum record which should
561 be read or passed over by a read cursor
562@param[in] index secondary index
563@param[in] offsets rec_get_offsets(rec, index)
564@param[in] sel_mode select mode: SELECT_ORDINARY,
565 SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
566@param[in] mode mode of the lock which the read cursor should
567 set on records: LOCK_S or LOCK_X; the latter is
568 possible in SELECT FOR UPDATE
569@param[in] gap_mode LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
570@param[in,out] thr query thread
571@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
572DB_SKIP_LOCKED, or DB_LOCK_NOWAIT */
574 lock_duration_t duration, const buf_block_t *block, const rec_t *rec,
575 dict_index_t *index, const ulint *offsets, select_mode sel_mode,
576 lock_mode mode, ulint gap_mode, que_thr_t *thr);
577
578/** Checks if locks of other transactions prevent an immediate read, or passing
579 over by a read cursor, of a clustered index record. If they do, first tests
580 if the query thread should anyway be suspended for some reason; if not, then
581 puts the transaction and the query thread to the lock wait state and inserts a
582 waiting request for a record lock to the lock queue. Sets the requested mode
583 lock on the record. This is an alternative version of
584 lock_clust_rec_read_check_and_lock() that does not require the parameter
585 "offsets".
586 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
588 const buf_block_t *block, /*!< in: buffer block of rec */
589 const rec_t *rec, /*!< in: user record or page
590 supremum record which should
591 be read or passed over by a
592 read cursor */
593 dict_index_t *index, /*!< in: clustered index */
594 lock_mode mode, /*!< in: mode of the lock which
595 the read cursor should set on
596 records: LOCK_S or LOCK_X; the
597 latter is possible in
598 SELECT FOR UPDATE */
599 ulint gap_mode, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
600 LOCK_REC_NOT_GAP */
601 que_thr_t *thr); /*!< in: query thread */
602/** Checks that a record is seen in a consistent read.
603 @return true if sees, or false if an earlier version of the record
604 should be retrieved */
606 const rec_t *rec, /*!< in: user record which should be read or
607 passed over by a read cursor */
608 dict_index_t *index, /*!< in: clustered index */
609 const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
610 ReadView *view); /*!< in: consistent read view */
611/** Checks that a non-clustered index record is seen in a consistent read.
612
613 NOTE that a non-clustered index page contains so little information on
614 its modifications that also in the case false, the present version of
615 rec may be the right, but we must check this from the clustered index
616 record.
617
618 @return true if certainly sees, or false if an earlier version of the
619 clustered index record might be needed */
620[[nodiscard]] bool lock_sec_rec_cons_read_sees(
621 const rec_t *rec, /*!< in: user record which
622 should be read or passed over
623 by a read cursor */
624 const dict_index_t *index, /*!< in: index */
625 const ReadView *view); /*!< in: consistent read view */
626/** Locks the specified database table in the mode given. If the lock cannot
627 be granted immediately, the query thread is put to wait.
628 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */
629[[nodiscard]] dberr_t lock_table(
630 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set,
631 does nothing */
632 dict_table_t *table, /*!< in/out: database table
633 in dictionary cache */
634 lock_mode mode, /*!< in: lock mode */
635 que_thr_t *thr); /*!< in: query thread */
636
637/** Creates a table IX lock object for a resurrected transaction.
638@param[in,out] table Table
639@param[in,out] trx Transaction */
641
642/** Sets a lock on a table based on the given mode.
643@param[in] table table to lock
644@param[in,out] trx transaction
645@param[in] mode LOCK_X or LOCK_S
646@return error code or DB_SUCCESS. */
647[[nodiscard]] dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx,
648 enum lock_mode mode)
649 MY_ATTRIBUTE((nonnull));
650
651/** Removes a granted record lock of a transaction from the queue and grants
652 locks to other transactions waiting in the queue if they now are entitled
653 to a lock. */
654void lock_rec_unlock(
655 trx_t *trx, /*!< in/out: transaction that has
656 set a record lock */
657 const buf_block_t *block, /*!< in: buffer block containing rec */
658 const rec_t *rec, /*!< in: record */
659 lock_mode lock_mode); /*!< in: LOCK_S or LOCK_X */
660/** Releases a transaction's locks, and releases possible other transactions
661 waiting because of these locks. Change the state of the transaction to
662 TRX_STATE_COMMITTED_IN_MEMORY. */
663void lock_trx_release_locks(trx_t *trx); /*!< in/out: transaction */
664
665/** Release read locks of a transaction. It is called during XA
666prepare to release locks early.
667@param[in,out] trx transaction
668@param[in] only_gap release only GAP locks */
669void lock_trx_release_read_locks(trx_t *trx, bool only_gap);
670
671/** Iterate over the granted locks which conflict with trx->lock.wait_lock and
672prepare the hit list for ASYNC Rollback.
673
674If the transaction is waiting for some other lock then wake up
675with deadlock error. Currently we don't mark following transactions
676for ASYNC Rollback.
677
6781. Read only transactions
6792. Background transactions
6803. Other High priority transactions
681@param[in] trx High Priority transaction
682@param[in,out] hit_list List of transactions which need to be rolled back */
683void lock_make_trx_hit_list(trx_t *trx, hit_list_t &hit_list);
684
685/** Removes locks on a table to be dropped.
686 If remove_also_table_sx_locks is true then table-level S and X locks are
687 also removed in addition to other table-level and record-level locks.
688 No lock, that is going to be removed, is allowed to be a wait lock. */
690 dict_table_t *table, /*!< in: table to be dropped
691 or discarded */
692 bool remove_also_table_sx_locks); /*!< in: also removes
693 table S and X locks */
694
695/** Calculates the hash value of a page file address: used in inserting or
696searching for a lock in the hash table or getting global shard index.
697@param page_id specifies the page
698@return hash value */
699static inline uint64_t lock_rec_hash_value(const page_id_t &page_id);
700
701/** Looks for a set bit in a record lock bitmap.
702Returns ULINT_UNDEFINED, if none found.
703@param[in] lock A record lock
704@return bit index == heap number of the record, or ULINT_UNDEFINED if none
705found */
707
708/** Looks for the next set bit in the record lock bitmap.
709@param[in] lock record lock with at least one bit set
710@param[in] heap_no current set bit
711@return The next bit index == heap number following heap_no, or ULINT_UNDEFINED
712if none found */
714
715/** Checks if a lock request lock1 has to wait for request lock2.
716@param[in] lock1 A waiting lock
717@param[in] lock2 Another lock;
718 NOTE that it is assumed that this has a lock bit set on the
719 same record as in lock1 if the locks are record lock
720@return true if lock1 has to wait for lock2 to be removed */
721bool lock_has_to_wait(const lock_t *lock1, const lock_t *lock2);
722
723namespace locksys {
724/** An object which can be passed to consecutive calls to
725rec_lock_has_to_wait(trx, mode, lock, is_supremum, trx_locks_cache) for the same
726trx and heap_no (which is implicitly the bit common to all lock objects passed)
727which can be used by this function to cache some partial results. */
729 private:
730 bool m_computed{false};
732#ifdef UNIV_DEBUG
736#endif /* UNIV_DEBUG*/
737 public:
738 /* Checks if trx has a granted lock which is blocking the waiting_lock.
739 @param[in] trx The trx object for which we want to know if one of
740 its granted locks is one of the locks directly
741 blocking the waiting_lock.
742 It must not change between invocations of this
743 method.
744 @param[in] waiting_lock A waiting record lock. Multiple calls to this method
745 must query the same heap_no and page_id. Currently
746 only X and X|REC_NOT_GAP are supported.
747 @return true iff the trx holds a granted record lock which is one of the
748 reasons waiting_lock has to wait.
749 */
750 bool has_granted_blocker(const trx_t *trx, const lock_t *waiting_lock);
751};
752
753/** Checks if a lock request lock1 has to wait for request lock2. It returns the
754same result as @see lock_has_to_wait(lock1, lock2), but in case these are record
755locks, it might use lock1_cache object to speed up the computation.
756If the same lock1_cache is passed to multiple calls of this method, then lock1
757also needs to be the same.
758@param[in] lock1 A waiting lock
759@param[in] lock2 Another lock;
760 NOTE that it is assumed that this has a lock bit set
761 on the same record as in lock1 if the locks are record
762 locks.
763@param[in] lock1_cache An object which can be passed to consecutive calls to
764 this function for the same lock1 which can be used by
765 this function to cache some partial results.
766@return true if lock1 has to wait for lock2 to be removed */
767bool has_to_wait(const lock_t *lock1, const lock_t *lock2,
768 Trx_locks_cache &lock1_cache);
769} // namespace locksys
770
771/** Reports that a transaction id is insensible, i.e., in the future.
772@param[in] trx_id Trx id
773@param[in] rec User record
774@param[in] index Index
775@param[in] offsets Rec_get_offsets(rec, index)
776@param[in] next_trx_id value received from trx_sys_get_next_trx_id_or_no() */
777void lock_report_trx_id_insanity(trx_id_t trx_id, const rec_t *rec,
778 const dict_index_t *index,
779 const ulint *offsets, trx_id_t next_trx_id);
780
781/** Prints info of locks for all transactions.
782@param[in] file file where to print */
784
785/** Prints transaction lock wait and MVCC state.
786@param[in,out] file file where to print
787@param[in] trx transaction */
789
790/** Prints info of locks for each transaction. This function assumes that the
791caller holds the exclusive global latch and more importantly it may release and
792reacquire it on behalf of the caller. (This should be fixed in the future).
793@param[in,out] file the file where to print */
795
796/** Return approximate number or record locks (bits set in the bitmap) for
797 this transaction. Since delete-marked records may be removed, the
798 record count will not be precise.
799 The caller must be holding exclusive global lock_sys latch.
800 @param[in] trx_lock transaction locks
801 */
802[[nodiscard]] ulint lock_number_of_rows_locked(const trx_lock_t *trx_lock);
803
804/** Return the number of table locks for a transaction.
805 The caller must be holding trx->mutex.
806@param[in] trx the transaction for which we want the number of table locks */
807[[nodiscard]] ulint lock_number_of_tables_locked(const trx_t *trx);
808
809/** Gets the type of a lock. Non-inline version for using outside of the
810 lock module.
811 @return LOCK_TABLE or LOCK_REC */
812uint32_t lock_get_type(const lock_t *lock); /*!< in: lock */
813
814/** Gets the id of the transaction owning a lock.
815@param[in] lock A lock of the transaction we are interested in
816@return the transaction's id */
818
819/** Get the performance schema event (thread_id, event_id)
820that created the lock.
821@param[in] lock Lock
822@param[out] thread_id Thread ID that created the lock
823@param[out] event_id Event ID that created the lock
824*/
826 ulonglong *event_id);
827
828/** Gets the mode of a lock in a human readable string.
829 The string should not be free()'d or modified.
830 @return lock mode */
831const char *lock_get_mode_str(const lock_t *lock); /*!< in: lock */
832
833/** Gets the type of a lock in a human readable string.
834 The string should not be free()'d or modified.
835 @return lock type */
836const char *lock_get_type_str(const lock_t *lock); /*!< in: lock */
837
838/** Gets the id of the table on which the lock is.
839 @return id of the table */
840table_id_t lock_get_table_id(const lock_t *lock); /*!< in: lock */
841
842/** Determine which table a lock is associated with.
843@param[in] lock the lock
844@return name of the table */
846
847/** For a record lock, gets the index on which the lock is.
848 @return index */
849const dict_index_t *lock_rec_get_index(const lock_t *lock); /*!< in: lock */
850
851/** For a record lock, gets the name of the index on which the lock is.
852 The string should not be free()'d or modified.
853 @return name of the index */
854const char *lock_rec_get_index_name(const lock_t *lock); /*!< in: lock */
855
856/** For a record lock, gets the tablespace number and page number on which the
857lock is.
858 @return tablespace number */
859page_id_t lock_rec_get_page_id(const lock_t *lock); /*!< in: lock */
860
861/** Check if there are any locks (table or rec) against table.
862Returned value might be obsolete.
863@param[in] table the table
864@return true if there were any locks held on records in this table or on the
865table itself at some point in time during the call */
866bool lock_table_has_locks(const dict_table_t *table);
867
868/** A thread which wakes up threads whose lock wait may have lasted too long. */
870
871/** Notifies the thread which analyzes wait-for-graph that there was
872 at least one new edge added or modified ( trx->blocking_trx has changed ),
873 so that the thread will know it has to analyze it. */
875
876/** Puts a user OS thread to wait for a lock to be released. If an error
877 occurs during the wait trx->error_state associated with thr is != DB_SUCCESS
878 when we return. DB_INTERRUPTED, DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
879 are possible errors. DB_DEADLOCK is returned if selective deadlock
880 resolution chose this transaction as a victim. */
881void lock_wait_suspend_thread(que_thr_t *thr); /*!< in: query thread associated
882 with the user OS thread */
883/** Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
884 function should be called at the the end of an SQL statement, by the
885 connection thread that owns the transaction (trx->mysql_thd). */
886void lock_unlock_table_autoinc(trx_t *trx); /*!< in/out: transaction */
887
888/** Cancels the waiting lock request of the trx, if any.
889If the transaction has already committed (trx->version has changed) or is no
890longer waiting for a lock (trx->lock.blocking_trx is nullptr) this function
891will not cancel the waiting lock.
892
893@note There is a possibility of ABA in which a waiting lock request was already
894granted or canceled and then the trx requested another lock and started waiting
895for it - in such case this function might either cancel or not the second
896request depending on timing. Currently all usages of this function ensure that
897this is impossible:
898- innodb_kill_connection ensures trx_is_interrupted(trx), thus upon first wake
899up it will realize it has to report an error and rollback
900- HP transaction marks the trx->in_innodb & TRX_FORCE_ROLLBACK flag which is
901checked when the trx attempts RecLock::add_to_waitq and reports DB_DEADLOCK
902
903@param[in] trx_version The trx we want to wake up and its expected
904 version
905@return true iff the function did release a waiting lock
906*/
908
909/** Set the lock system timeout event. */
911
912/** Checks that a transaction id is sensible, i.e., not in the future.
913Emits an error otherwise.
914@param[in] trx_id The trx id to check, found in user record or secondary
915 index page header
916@param[in] rec The user record which contained the trx_id in its header
917 or in header of its page
918@param[in] index The index which contained the rec
919@param[in] offsets The result of rec_get_offsets(rec, index)
920@return true iff ok */
921bool lock_check_trx_id_sanity(trx_id_t trx_id, const rec_t *rec,
922 const dict_index_t *index, const ulint *offsets);
923
924#ifdef UNIV_DEBUG
925/** Check if the transaction holds an exclusive lock on a record.
926@param[in] thr query thread of the transaction
927@param[in] table table to check
928@param[in] block buffer block of the record
929@param[in] heap_no record heap number
930@return whether the locks are held */
931[[nodiscard]] bool lock_trx_has_rec_x_lock(que_thr_t *thr,
932 const dict_table_t *table,
933 const buf_block_t *block,
934 ulint heap_no);
935
936/** Validates the lock system.
937 @return true if ok */
938bool lock_validate();
939#endif /* UNIV_DEBUG */
940
941/**
942Allocate cached locks for the transaction.
943@param trx allocate cached record locks for this transaction */
944void lock_trx_alloc_locks(trx_t *trx);
945
946/** Lock modes and types */
947/** @{ */
948/** mask used to extract mode from the type_mode field in a lock */
949constexpr uint32_t LOCK_MODE_MASK = 0xF;
950/** Lock types */
951/** table lock */
952constexpr uint32_t LOCK_TABLE = 16;
953/** record lock */
954constexpr uint32_t LOCK_REC = 32;
955/** mask used to extract lock type from the type_mode field in a lock */
956constexpr uint32_t LOCK_TYPE_MASK = 0xF0UL;
957static_assert((LOCK_MODE_MASK & LOCK_TYPE_MASK) == 0,
958 "LOCK_MODE_MASK & LOCK_TYPE_MASK");
959
960/** Waiting lock flag; when set, it means that the lock has not yet been
961 granted, it is just waiting for its turn in the wait queue */
962constexpr uint32_t LOCK_WAIT = 256;
963/* Precise modes */
964/** this flag denotes an ordinary next-key lock in contrast to LOCK_GAP or
965 LOCK_REC_NOT_GAP */
966constexpr uint32_t LOCK_ORDINARY = 0;
967/** when this bit is set, it means that the lock holds only on the gap before
968 the record; for instance, an x-lock on the gap does not give permission to
969 modify the record on which the bit is set; locks of this type are created
970 when records are removed from the index chain of records */
971constexpr uint32_t LOCK_GAP = 512;
972/** this bit means that the lock is only on the index record and does NOT
973 block inserts to the gap before the index record; this is used in the case
974 when we retrieve a record with a unique key, and is also used in locking
975 plain SELECTs (not part of UPDATE or DELETE) when the user has set the READ
976 COMMITTED isolation level */
977constexpr uint32_t LOCK_REC_NOT_GAP = 1024;
978/** this bit is set when we place a waiting gap type record lock request in
979 order to let an insert of an index record to wait until there are no
980 conflicting locks by other transactions on the gap; note that this flag
981 remains set when the waiting lock is granted, or if the lock is inherited to
982 a neighboring record */
983constexpr uint32_t LOCK_INSERT_INTENTION = 2048;
984/** Predicate lock */
985constexpr uint32_t LOCK_PREDICATE = 8192;
986/** Page lock */
987constexpr uint32_t LOCK_PRDT_PAGE = 16384;
988
989static_assert(
992 LOCK_MODE_MASK) == 0,
993 "(LOCK_WAIT | LOCK_GAP | LOCK_REC_NOT_GAP | LOCK_INSERT_INTENTION | "
994 "LOCK_PREDICATE | LOCK_PRDT_PAGE) & LOCK_TYPE_MASK");
995/** @} */
996
997/** Lock operation struct */
998struct lock_op_t {
999 dict_table_t *table; /*!< table to be locked */
1000 lock_mode mode; /*!< lock mode */
1001};
1002
1003typedef ib_mutex_t Lock_mutex;
1004/** A hashmap used by lock sys, to organize locks by page (block), so that
1005it is easy to maintain a list of all locks related to a given page by
1006append(lock,..), prepend(lock,..), erase(lock,..), move_to_front(lock,...)
1007while also providing ability to iterate over all locks related for a given
1008page in that order.
1009
1010The hash has a configurable number of cells, and handles conflicts by using
1011a singly linked list for each cell - locks related to same page are guaranteed
1012to hash to the same cell. This detail is exposed because, for performance
1013reasons you might want to resize(n) it, or inspect all locks from a given
1014cell with find_in_cell(cell_id, visitor), or find a next non-empty cell with
1015find_set_in_this_shard(..), or cell to which a given hash_value is mapped
1016with get_cell_id(hash_value).
1017*/
1020 Locks_hashtable(size_t n_cells)
1021 : ht(ut::make_unique<hash_table_t>(n_cells)),
1024
1025 void append(lock_t *lock, uint64_t hash_value);
1026 void prepend(lock_t *lock, uint64_t hash_value);
1027 void erase(lock_t *lock, uint64_t hash_value);
1028 void move_to_front(lock_t *lock, uint64_t hash_value);
1029 void resize(size_t n_cells);
1030
1031 template <typename F>
1032 lock_t *find_in_cell(size_t cell_id, F &&f);
1033 template <typename F>
1034 lock_t *find_on_page(page_id_t page_id, F &&f);
1035 template <typename F>
1036 lock_t *find_on_block(const buf_block_t *block, F &&f);
1037 template <typename F>
1038 lock_t *find_on_record(const struct RecID &rec_id, F &&f);
1039#ifdef UNIV_DEBUG
1040 /* Don't use it in Release - it's too slow, as it requires the global latch.
1041 Instead use All_locks_iterator, or something like that - which will not
1042 give you a consistent view, needed in debug, but would be faster. */
1043 template <typename F>
1044 lock_t *find(F &&f);
1045#endif /* UNIV_DEBUG */
1046
1047 size_t get_n_cells() { return ht->get_n_cells(); }
1048 size_t find_set_in_this_shard(size_t start_pos) {
1049 return cells_in_use.find_set_in_this_shard(start_pos);
1050 }
1051
1052 size_t get_cell_id(uint64_t hash_value);
1053
1054 private:
1055 bool append(hash_cell_t *cell, lock_t *lock);
1056 bool prepend(hash_cell_t *cell, lock_t *lock);
1057 bool erase(hash_cell_t *cell, lock_t *lock);
1058
1059 // Disable copying
1066};
1067
1068/** The lock system struct */
1070 /** The latches protecting queues of record and table locks */
1072
1073 /** The hash table of the record (LOCK_REC) locks, except for predicate
1074 (LOCK_PREDICATE) and predicate page (LOCK_PRDT_PAGE) locks */
1076
1077 /** The hash table of predicate (LOCK_PREDICATE) locks */
1079
1080 /** The hash table of the predicate page (LOCK_PRD_PAGE) locks */
1082
1083 lock_sys_t(size_t n_cells)
1084 : rec_hash{n_cells}, prdt_hash{n_cells}, prdt_page_hash{n_cells} {}
1085
1086 /** number of calls to lock_sys_resize() so far. Used to determine if
1087 iterators should be invalidated.
1088 Modified under global exclusive lock_sys latch.
1089 Read under global shared lock_sys latch. */
1090 uint32_t n_resizes;
1091
1092 /** Padding to avoid false sharing of wait_mutex field */
1094
1095 /** The mutex protecting the next two fields */
1097
1098 /** Array of user threads suspended while waiting for locks within InnoDB.
1099 Protected by the lock_sys->wait_mutex. */
1101
1102 /** The highest slot ever used in the waiting_threads array.
1103 Protected by lock_sys->wait_mutex. */
1105
1106 /** true if rollback of all recovered transactions is complete.
1107 Protected by exclusive global lock_sys latch. */
1109
1110 /** Max lock wait time observed, for innodb_row_lock_time_max reporting. */
1111 std::chrono::steady_clock::duration n_lock_max_wait_time;
1112
1113 /** Set to the event that is created in the lock wait monitor thread. A value
1114 of 0 means the thread is not active */
1116
1117#ifdef UNIV_DEBUG
1118 /** Lock timestamp counter, used to assign lock->m_seq on creation. */
1119 std::atomic<uint64_t> m_seq;
1120#endif /* UNIV_DEBUG */
1121};
1122
1123/** If a transaction has an implicit x-lock on a record, but no explicit x-lock
1124set on the record, sets one for it.
1125@param[in] block buffer block of rec
1126@param[in] rec user record on page
1127@param[in] index index of record
1128@param[in] offsets rec_get_offsets(rec, index) */
1129void lock_rec_convert_impl_to_expl(const buf_block_t *block, const rec_t *rec,
1130 dict_index_t *index, const ulint *offsets);
1131
1132/** Removes a record lock request, waiting or granted, from the queue. */
1133void lock_rec_discard(lock_t *in_lock); /*!< in: record lock object: all
1134 record locks which are contained
1135 in this lock object are removed */
1136
1137/** Moves the explicit locks on user records to another page if a record
1138 list start is moved to another page.
1139@param[in] new_block Index page to move to
1140@param[in] block Index page
1141@param[in] rec_move Recording records moved
1142@param[in] num_move Num of rec to move */
1143void lock_rtr_move_rec_list(const buf_block_t *new_block,
1144 const buf_block_t *block, rtr_rec_move_t *rec_move,
1145 ulint num_move);
1146
1147/** Removes record lock objects set on an index page which is discarded. This
1148 function does not move locks, or check for waiting locks, therefore the
1149 lock bitmaps must already be reset when this function is called. */
1151 const buf_block_t *block); /*!< in: page to be discarded */
1152
1153/** Reset the nth bit of a record lock. If this was a wait lock clears the wait
1154flag on it, and marks that the trx no longer waits on it, but doesn't wake up
1155the transaction. This function is meant to be used when lock requests are moved
1156from one place to another, and thus a new (equivalent) lock request will be soon
1157created for the transaction, so there's no point in waking it up.
1158@param[in,out] lock record lock
1159@param[in] heap_no index of the bit that will be reset
1160@return false iff the bit was already cleared before the call
1161*/
1162bool lock_rec_clear_request_no_wakeup(lock_t *lock, uint16_t heap_no);
1163
1164/** Checks if the lock is waiting (as opposed to granted).
1165Caller should hold a latch on shard containging the lock in order for this check
1166to be meaningful.
1167@param[in] lock the lock to inspect
1168@return true iff the lock is waiting */
1169bool lock_is_waiting(const lock_t &lock);
1170
1171/** Inspect the lock queue associated with the given table in search for a lock
1172which has guid equal to the given one.
1173Caller should hold a latch on the shard containing this table's locks.
1174@param[in] table the table, for which we expect the lock
1175@param[in] guid the guid of the lock we seek for
1176@return the lock with a given guid or nullptr if no such lock */
1178 const lock_guid_t &guid);
1179
1180/** Inspect the lock queues associated with the given page_id in search for a
1181lock which has guid equal to the given one. Caller should hold a latch on shard
1182containing locks for this page.
1183@param[in] page_id the id of the page, for which we expect the lock
1184@param[in] guid the guid of the lock we seek for
1185@return the lock with a given guid or nullptr if no such lock */
1187 const lock_guid_t &guid);
1188
1189/** The lock system */
1190extern lock_sys_t *lock_sys;
1191
1192#ifdef UNIV_DEBUG
1193/** Test if lock_sys->wait_mutex is owned. */
1194static inline bool lock_wait_mutex_own() {
1195 return lock_sys->wait_mutex.is_owned();
1196}
1197#endif
1198
1199/** Acquire the lock_sys->wait_mutex. */
1200static inline void lock_wait_mutex_enter() {
1202}
1203/** Release the lock_sys->wait_mutex. */
1204static inline void lock_wait_mutex_exit() { lock_sys->wait_mutex.exit(); }
1205
1206#include "lock0lock.ic"
1207
1208namespace locksys {
1209
1210/* OWNERSHIP TESTS */
1211#ifdef UNIV_DEBUG
1212
1213/**
1214Tests if lock_sys latch is exclusively owned by the current thread.
1215@return true iff the current thread owns exclusive global lock_sys latch
1216*/
1218
1219/**
1220Tests if lock_sys latch is owned in shared mode by the current thread.
1221@return true iff the current thread owns shared global lock_sys latch
1222*/
1224
1225/**
1226Tests if given page shard can be safely accessed by the current thread.
1227@param page_id specifies the page
1228@return true iff the current thread owns exclusive global lock_sys latch or both
1229a shared global lock_sys latch and mutex protecting the page shard
1230*/
1231bool owns_page_shard(const page_id_t &page_id);
1232
1233/**
1234Test if given table shard can be safely accessed by the current thread.
1235@param table the table
1236@return true iff the current thread owns exclusive global lock_sys latch or
1237both a shared global lock_sys latch and mutex protecting the table shard
1238*/
1239bool owns_table_shard(const dict_table_t &table);
1240
1241/** Checks if shard which contains lock is latched (or that an exclusive latch
1242on whole lock_sys is held) by current thread
1243@param[in] lock lock which belongs to a shard we want to check
1244@return true iff the current thread owns exclusive global lock_sys latch or
1245both a shared global lock_sys latch and mutex protecting the shard
1246containing the specified lock */
1247bool owns_lock_shard(const lock_t *lock);
1248
1249#endif /* UNIV_DEBUG */
1250
1251} // namespace locksys
1252
1253#include "lock0guards.h"
1254
1255#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:728
page_id_t m_cached_page_id
Definition: lock0lock.h:734
bool m_computed
Definition: lock0lock.h:730
bool has_granted_blocker(const trx_t *trx, const lock_t *waiting_lock)
Definition: lock0lock.cc:819
const trx_t * m_cached_trx
Definition: lock0lock.h:733
bool m_has_s_lock_on_record
Definition: lock0lock.h:731
size_t m_cached_heap_no
Definition: lock0lock.h:735
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:235
constexpr uint32_t LOCK_PRDT_PAGE
Page lock.
Definition: lock0lock.h:987
const char * lock_get_type_str(const lock_t *lock)
Gets the type of a lock in a human readable string.
Definition: lock0lock.cc:5783
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:5928
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:743
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:448
constexpr uint32_t LOCK_MODE_MASK
Lock modes and types.
Definition: lock0lock.h:949
bool lock_is_waiting(const lock_t &lock)
Checks if the lock is waiting (as opposed to granted).
Definition: lock0lock.cc:477
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:207
static void lock_wait_mutex_exit()
Release the lock_sys->wait_mutex.
Definition: lock0lock.h:1204
uint32_t lock_get_type(const lock_t *lock)
Gets the type of a lock.
Definition: lock0lock.cc:5689
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:3870
void lock_print_info_summary(FILE *file)
Prints info of locks for all transactions.
Definition: lock0lock.cc:4487
constexpr uint32_t LOCK_PREDICATE
Predicate lock.
Definition: lock0lock.h:985
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:962
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:5831
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...
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:5125
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:724
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:272
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:966
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:5593
void lock_unlock_table_autoinc(trx_t *trx)
Unlocks AUTO_INC type locks that were possibly reserved by a trx.
Definition: lock0lock.cc:5874
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:341
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:5533
void lock_sys_create(ulint n_cells)
Creates the lock system at database start.
Definition: lock0lock.cc:304
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:701
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:5842
bool lock_table_has_locks(const dict_table_t *table)
Check if there are any locks (table or rec) against table.
Definition: lock0lock.cc:6044
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:5484
const table_name_t & lock_get_table_name(const lock_t *lock)
Determine which table a lock is associated with.
Definition: lock0lock.cc:5825
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:196
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:5325
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:5813
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:1433
void lock_trx_release_read_locks(trx_t *trx, bool only_gap)
Release read locks of a transaction.
Definition: lock0lock.cc:4127
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:1095
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:3670
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:3802
constexpr uint32_t LOCK_TYPE_MASK
mask used to extract lock type from the type_mode field in a lock
Definition: lock0lock.h:956
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:6078
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:5163
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:983
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:952
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:3406
void lock_trx_print_wait_and_mvcc_state(FILE *file, const trx_t *trx)
Prints transaction lock wait and MVCC state.
Definition: lock0lock.cc:4676
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:1003
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:5850
bool lock_cancel_if_waiting_and_release(TrxVersion trx_version)
Cancels the waiting lock request of the trx, if any.
Definition: lock0lock.cc:5981
static void lock_wait_mutex_enter()
Acquire the lock_sys->wait_mutex.
Definition: lock0lock.h:1200
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:5374
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:218
const char * lock_get_mode_str(const lock_t *lock)
Gets the mode of a lock in a human readable string.
Definition: lock0lock.cc:5728
void lock_print_info_all_transactions(FILE *file)
Prints info of locks for each transaction.
Definition: lock0lock.cc:4818
trx_id_t lock_get_trx_id(const lock_t *lock)
Gets the id of the transaction owning a lock.
Definition: lock0lock.cc:5694
static bool lock_wait_mutex_own()
Test if lock_sys->wait_mutex is owned.
Definition: lock0lock.h:1194
lock_sys_t * lock_sys
The lock system.
Definition: lock0lock.cc:197
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:5704
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:690
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:510
@ 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:5426
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:3566
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:971
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:198
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:977
lock_t * lock_alloc_from_heap(mem_heap_t *heap, size_t bitmap_bytes=0)
Allocates memory suitable for holding a lock_t from specified heap.
Definition: lock0lock.cc:1107
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:680
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:4320
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:1086
void lock_set_timeout_event()
Set the lock system timeout event.
Definition: lock0lock.cc:6074
constexpr uint32_t LOCK_REC
record lock
Definition: lock0lock.h:954
void lock_trx_alloc_locks(trx_t *trx)
Allocate cached locks for the transaction.
Definition: lock0lock.cc:6281
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
const std::string FILE("FILE")
Definition: os0file.h:86
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:171
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:175
bool owns_shared_global_latch()
Tests if lock_sys latch is owned in shared mode by the current thread.
Definition: lock0lock.cc:167
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:179
bool owns_exclusive_global_latch()
Tests if lock_sys latch is exclusively owned by the current thread.
Definition: lock0lock.cc:163
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:663
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:60
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:2439
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:1018
Locks_hashtable(Locks_hashtable &&)=delete
void erase(lock_t *lock, uint64_t hash_value)
Definition: lock0lock.cc:431
lock_t * find_on_block(const buf_block_t *block, F &&f)
Definition: lock0priv.h:1151
size_t get_cell_id(uint64_t hash_value)
Definition: lock0lock.cc:380
ut::unique_ptr< hash_table_t > ht
Definition: lock0lock.h:1064
void prepend(lock_t *lock, uint64_t hash_value)
Definition: lock0lock.cc:423
Locks_hashtable(size_t n_cells)
Definition: lock0lock.h:1020
void move_to_front(lock_t *lock, uint64_t hash_value)
Definition: lock0lock.cc:439
void append(lock_t *lock, uint64_t hash_value)
Definition: lock0lock.cc:415
void resize(size_t n_cells)
Definition: lock0lock.cc:368
Locks_hashtable & operator=(Locks_hashtable &&)=delete
lock_t * find(F &&f)
Definition: lock0priv.h:1164
lock_t * find_on_page(page_id_t page_id, F &&f)
Definition: lock0priv.h:1141
size_t find_set_in_this_shard(size_t start_pos)
Definition: lock0lock.h:1048
size_t get_n_cells()
Definition: lock0lock.h:1047
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:1156
lock_t * find_in_cell(size_t cell_id, F &&f)
Definition: lock0priv.h:1126
Cells_in_use cells_in_use
Definition: lock0lock.h:1065
Record lock ID.
Definition: lock0priv.h:634
Definition: trx0types.h:635
The buffer control block structure.
Definition: buf0buf.h:1690
Data structure for an index.
Definition: dict0mem.h:1046
Data structure for a database table.
Definition: dict0mem.h:1909
Definition: hash0hash.h:61
Used to represent locks requests uniquely over time.
Definition: lock0types.h:106
Lock operation struct.
Definition: lock0lock.h:998
dict_table_t * table
table to be locked
Definition: lock0lock.h:999
lock_mode mode
lock mode
Definition: lock0lock.h:1000
The lock system struct.
Definition: lock0lock.h:1069
locksys::Latches latches
The latches protecting queues of record and table locks.
Definition: lock0lock.h:1071
char pad2[ut::INNODB_CACHE_LINE_SIZE]
Padding to avoid false sharing of wait_mutex field.
Definition: lock0lock.h:1093
Locks_hashtable rec_hash
The hash table of the record (LOCK_REC) locks, except for predicate (LOCK_PREDICATE) and predicate pa...
Definition: lock0lock.h:1075
lock_sys_t(size_t n_cells)
Definition: lock0lock.h:1083
srv_slot_t * last_slot
The highest slot ever used in the waiting_threads array.
Definition: lock0lock.h:1104
Locks_hashtable prdt_hash
The hash table of predicate (LOCK_PREDICATE) locks.
Definition: lock0lock.h:1078
bool rollback_complete
true if rollback of all recovered transactions is complete.
Definition: lock0lock.h:1108
uint32_t n_resizes
number of calls to lock_sys_resize() so far.
Definition: lock0lock.h:1090
srv_slot_t * waiting_threads
Array of user threads suspended while waiting for locks within InnoDB.
Definition: lock0lock.h:1100
Lock_mutex wait_mutex
The mutex protecting the next two fields.
Definition: lock0lock.h:1096
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:1111
os_event_t timeout_event
Set to the event that is created in the lock wait monitor thread.
Definition: lock0lock.h:1115
Locks_hashtable prdt_page_hash
The hash table of the predicate page (LOCK_PRD_PAGE) locks.
Definition: lock0lock.h:1081
std::atomic< uint64_t > m_seq
Lock timestamp counter, used to assign lock->m_seq on creation.
Definition: lock0lock.h:1119
Lock struct; protected by lock_sys latches.
Definition: lock0priv.h:137
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:302
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: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.