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