1 /******************************************************
2 The transaction lock system
6 Created 5/7/1996 Heikki Tuuri
7 *******************************************************/
13 #include "trx0types.h"
14 #include "rem0types.h"
15 #include "dict0types.h"
16 #include "que0types.h"
17 #include "page0types.h"
18 #include "lock0types.h"
19 #include "read0types.h"
20 #include "hash0hash.h"
23 extern ibool lock_print_waits
;
24 #endif /* UNIV_DEBUG */
25 /* Buffer for storing information about the most recent deadlock error */
26 extern FILE* lock_latest_err_file
;
28 /*************************************************************************
29 Gets the size of a lock struct. */
34 /* out: size in bytes */
35 /*************************************************************************
36 Creates the lock system at database start. */
41 ulint n_cells
); /* in: number of slots in lock hash table */
42 /*************************************************************************
43 Checks if some transaction has an implicit x-lock on a record in a secondary
47 lock_sec_rec_some_has_impl_off_kernel(
48 /*==================================*/
49 /* out: transaction which has the x-lock, or
51 rec_t
* rec
, /* in: user record */
52 dict_index_t
* index
, /* in: secondary index */
53 const ulint
* offsets
);/* in: rec_get_offsets(rec, index) */
54 /*************************************************************************
55 Checks if some transaction has an implicit x-lock on a record in a clustered
59 lock_clust_rec_some_has_impl(
60 /*=========================*/
61 /* out: transaction which has the x-lock, or
63 rec_t
* rec
, /* in: user record */
64 dict_index_t
* index
, /* in: clustered index */
65 const ulint
* offsets
);/* in: rec_get_offsets(rec, index) */
66 /*****************************************************************
67 Makes a record to inherit the locks of another record as gap type
68 locks, but does not reset the lock bits of the other record. Also
69 waiting lock requests on rec are inherited as GRANTED gap locks. */
72 lock_rec_inherit_to_gap(
73 /*====================*/
74 rec_t
* heir
, /* in: record which inherits */
75 rec_t
* rec
); /* in: record from which inherited; does NOT reset
76 the locks on this record */
77 /*****************************************************************
78 Updates the lock table when we have reorganized a page. NOTE: we copy
79 also the locks set on the infimum of the page; the infimum may carry
80 locks if an update of a record is occurring on the page, and its locks
81 were temporarily stored on the infimum. */
84 lock_move_reorganize_page(
85 /*======================*/
86 page_t
* page
, /* in: old index page */
87 page_t
* new_page
); /* in: reorganized page */
88 /*****************************************************************
89 Moves the explicit locks on user records to another page if a record
90 list end is moved to another page. */
93 lock_move_rec_list_end(
94 /*===================*/
95 page_t
* new_page
, /* in: index page to move to */
96 page_t
* page
, /* in: index page */
97 rec_t
* rec
); /* in: record on page: this is the
99 /*****************************************************************
100 Moves the explicit locks on user records to another page if a record
101 list start is moved to another page. */
104 lock_move_rec_list_start(
105 /*=====================*/
106 page_t
* new_page
, /* in: index page to move to */
107 page_t
* page
, /* in: index page */
108 rec_t
* rec
, /* in: record on page: this is the
109 first record NOT copied */
110 rec_t
* old_end
); /* in: old previous-to-last record on
111 new_page before the records were copied */
112 /*****************************************************************
113 Updates the lock table when a page is split to the right. */
116 lock_update_split_right(
117 /*====================*/
118 page_t
* right_page
, /* in: right page */
119 page_t
* left_page
); /* in: left page */
120 /*****************************************************************
121 Updates the lock table when a page is merged to the right. */
124 lock_update_merge_right(
125 /*====================*/
126 rec_t
* orig_succ
, /* in: original successor of infimum
127 on the right page before merge */
128 page_t
* left_page
); /* in: merged index page which will be
130 /*****************************************************************
131 Updates the lock table when the root page is copied to another in
132 btr_root_raise_and_insert. Note that we leave lock structs on the
133 root page, even though they do not make sense on other than leaf
134 pages: the reason is that in a pessimistic update the infimum record
135 of the root page will act as a dummy carrier of the locks of the record
139 lock_update_root_raise(
140 /*===================*/
141 page_t
* new_page
, /* in: index page to which copied */
142 page_t
* root
); /* in: root page */
143 /*****************************************************************
144 Updates the lock table when a page is copied to another and the original page
145 is removed from the chain of leaf pages, except if page is the root! */
148 lock_update_copy_and_discard(
149 /*=========================*/
150 page_t
* new_page
, /* in: index page to which copied */
151 page_t
* page
); /* in: index page; NOT the root! */
152 /*****************************************************************
153 Updates the lock table when a page is split to the left. */
156 lock_update_split_left(
157 /*===================*/
158 page_t
* right_page
, /* in: right page */
159 page_t
* left_page
); /* in: left page */
160 /*****************************************************************
161 Updates the lock table when a page is merged to the left. */
164 lock_update_merge_left(
165 /*===================*/
166 page_t
* left_page
, /* in: left page to which merged */
167 rec_t
* orig_pred
, /* in: original predecessor of supremum
168 on the left page before merge */
169 page_t
* right_page
); /* in: merged index page which will be
171 /*****************************************************************
172 Resets the original locks on heir and replaces them with gap type locks
173 inherited from rec. */
176 lock_rec_reset_and_inherit_gap_locks(
177 /*=================================*/
178 rec_t
* heir
, /* in: heir record */
179 rec_t
* rec
); /* in: record */
180 /*****************************************************************
181 Updates the lock table when a page is discarded. */
186 rec_t
* heir
, /* in: record which will inherit the locks */
187 page_t
* page
); /* in: index page which will be discarded */
188 /*****************************************************************
189 Updates the lock table when a new user record is inserted. */
194 rec_t
* rec
); /* in: the inserted record */
195 /*****************************************************************
196 Updates the lock table when a record is removed. */
201 rec_t
* rec
); /* in: the record to be removed */
202 /*************************************************************************
203 Stores on the page infimum record the explicit locks of another record.
204 This function is used to store the lock state of a record when it is
205 updated and the size of the record changes in the update. The record
206 is in such an update moved, perhaps to another page. The infimum record
207 acts as a dummy carrier record, taking care of lock releases while the
208 actual record is being moved. */
211 lock_rec_store_on_page_infimum(
212 /*===========================*/
213 page_t
* page
, /* in: page containing the record */
214 rec_t
* rec
); /* in: record whose lock state is stored
215 on the infimum record of the same page; lock
216 bits are reset on the record */
217 /*************************************************************************
218 Restores the state of explicit lock requests on a single record, where the
219 state was stored on the infimum of the page. */
222 lock_rec_restore_from_page_infimum(
223 /*===============================*/
224 rec_t
* rec
, /* in: record whose lock state is restored */
225 page_t
* page
); /* in: page (rec is not necessarily on this page)
226 whose infimum stored the lock state; lock bits are
227 reset on the infimum */
228 /*************************************************************************
229 Returns TRUE if there are explicit record locks on a page. */
232 lock_rec_expl_exist_on_page(
233 /*========================*/
234 /* out: TRUE if there are explicit record locks on
236 ulint space
, /* in: space id */
237 ulint page_no
);/* in: page number */
238 /*************************************************************************
239 Checks if locks of other transactions prevent an immediate insert of
240 a record. If they do, first tests if the query thread should anyway
241 be suspended for some reason; if not, then puts the transaction and
242 the query thread to the lock wait state and inserts a waiting request
243 for a gap x-lock to the lock queue. */
246 lock_rec_insert_check_and_lock(
247 /*===========================*/
248 /* out: DB_SUCCESS, DB_LOCK_WAIT,
249 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
250 ulint flags
, /* in: if BTR_NO_LOCKING_FLAG bit is set,
252 rec_t
* rec
, /* in: record after which to insert */
253 dict_index_t
* index
, /* in: index */
254 que_thr_t
* thr
, /* in: query thread */
255 ibool
* inherit
);/* out: set to TRUE if the new inserted
256 record maybe should inherit LOCK_GAP type
257 locks from the successor record */
258 /*************************************************************************
259 Checks if locks of other transactions prevent an immediate modify (update,
260 delete mark, or delete unmark) of a clustered index record. If they do,
261 first tests if the query thread should anyway be suspended for some
262 reason; if not, then puts the transaction and the query thread to the
263 lock wait state and inserts a waiting request for a record x-lock to the
267 lock_clust_rec_modify_check_and_lock(
268 /*=================================*/
269 /* out: DB_SUCCESS, DB_LOCK_WAIT,
270 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
271 ulint flags
, /* in: if BTR_NO_LOCKING_FLAG bit is set,
273 rec_t
* rec
, /* in: record which should be modified */
274 dict_index_t
* index
, /* in: clustered index */
275 const ulint
* offsets
,/* in: rec_get_offsets(rec, index) */
276 que_thr_t
* thr
); /* in: query thread */
277 /*************************************************************************
278 Checks if locks of other transactions prevent an immediate modify
279 (delete mark or delete unmark) of a secondary index record. */
282 lock_sec_rec_modify_check_and_lock(
283 /*===============================*/
284 /* out: DB_SUCCESS, DB_LOCK_WAIT,
285 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
286 ulint flags
, /* in: if BTR_NO_LOCKING_FLAG bit is set,
288 rec_t
* rec
, /* in: record which should be modified;
289 NOTE: as this is a secondary index, we
290 always have to modify the clustered index
291 record first: see the comment below */
292 dict_index_t
* index
, /* in: secondary index */
293 que_thr_t
* thr
); /* in: query thread */
294 /*************************************************************************
295 Like lock_clust_rec_read_check_and_lock(), but reads a
296 secondary index record. */
299 lock_sec_rec_read_check_and_lock(
300 /*=============================*/
301 /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC,
302 DB_LOCK_WAIT, DB_DEADLOCK,
303 or DB_QUE_THR_SUSPENDED */
304 ulint flags
, /* in: if BTR_NO_LOCKING_FLAG bit is set,
306 rec_t
* rec
, /* in: user record or page supremum record
307 which should be read or passed over by a read
309 dict_index_t
* index
, /* in: secondary index */
310 const ulint
* offsets
,/* in: rec_get_offsets(rec, index) */
311 ulint mode
, /* in: mode of the lock which the read cursor
312 should set on records: LOCK_S or LOCK_X; the
313 latter is possible in SELECT FOR UPDATE */
314 ulint gap_mode
,/* in: LOCK_ORDINARY, LOCK_GAP, or
316 que_thr_t
* thr
); /* in: query thread */
317 /*************************************************************************
318 Checks if locks of other transactions prevent an immediate read, or passing
319 over by a read cursor, of a clustered index record. If they do, first tests
320 if the query thread should anyway be suspended for some reason; if not, then
321 puts the transaction and the query thread to the lock wait state and inserts a
322 waiting request for a record lock to the lock queue. Sets the requested mode
323 lock on the record. */
326 lock_clust_rec_read_check_and_lock(
327 /*===============================*/
328 /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC,
329 DB_LOCK_WAIT, DB_DEADLOCK,
330 or DB_QUE_THR_SUSPENDED */
331 ulint flags
, /* in: if BTR_NO_LOCKING_FLAG bit is set,
333 rec_t
* rec
, /* in: user record or page supremum record
334 which should be read or passed over by a read
336 dict_index_t
* index
, /* in: clustered index */
337 const ulint
* offsets
,/* in: rec_get_offsets(rec, index) */
338 ulint mode
, /* in: mode of the lock which the read cursor
339 should set on records: LOCK_S or LOCK_X; the
340 latter is possible in SELECT FOR UPDATE */
341 ulint gap_mode
,/* in: LOCK_ORDINARY, LOCK_GAP, or
343 que_thr_t
* thr
); /* in: query thread */
344 /*************************************************************************
345 Checks if locks of other transactions prevent an immediate read, or passing
346 over by a read cursor, of a clustered index record. If they do, first tests
347 if the query thread should anyway be suspended for some reason; if not, then
348 puts the transaction and the query thread to the lock wait state and inserts a
349 waiting request for a record lock to the lock queue. Sets the requested mode
350 lock on the record. This is an alternative version of
351 lock_clust_rec_read_check_and_lock() that does not require the parameter
355 lock_clust_rec_read_check_and_lock_alt(
356 /*===================================*/
357 /* out: DB_SUCCESS, DB_LOCK_WAIT,
358 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
359 ulint flags
, /* in: if BTR_NO_LOCKING_FLAG bit is set,
361 rec_t
* rec
, /* in: user record or page supremum record
362 which should be read or passed over by a read
364 dict_index_t
* index
, /* in: clustered index */
365 ulint mode
, /* in: mode of the lock which the read cursor
366 should set on records: LOCK_S or LOCK_X; the
367 latter is possible in SELECT FOR UPDATE */
368 ulint gap_mode
,/* in: LOCK_ORDINARY, LOCK_GAP, or
370 que_thr_t
* thr
); /* in: query thread */
371 /*************************************************************************
372 Checks that a record is seen in a consistent read. */
375 lock_clust_rec_cons_read_sees(
376 /*==========================*/
377 /* out: TRUE if sees, or FALSE if an earlier
378 version of the record should be retrieved */
379 rec_t
* rec
, /* in: user record which should be read or
380 passed over by a read cursor */
381 dict_index_t
* index
, /* in: clustered index */
382 const ulint
* offsets
,/* in: rec_get_offsets(rec, index) */
383 read_view_t
* view
); /* in: consistent read view */
384 /*************************************************************************
385 Checks that a non-clustered index record is seen in a consistent read. */
388 lock_sec_rec_cons_read_sees(
389 /*========================*/
390 /* out: TRUE if certainly sees, or FALSE if an
391 earlier version of the clustered index record
392 might be needed: NOTE that a non-clustered
393 index page contains so little information on
394 its modifications that also in the case FALSE,
395 the present version of rec may be the right,
396 but we must check this from the clustered
398 rec_t
* rec
, /* in: user record which should be read or
399 passed over by a read cursor */
400 dict_index_t
* index
, /* in: non-clustered index */
401 read_view_t
* view
); /* in: consistent read view */
402 /*************************************************************************
403 Locks the specified database table in the mode given. If the lock cannot
404 be granted immediately, the query thread is put to wait. */
409 /* out: DB_SUCCESS, DB_LOCK_WAIT,
410 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
411 ulint flags
, /* in: if BTR_NO_LOCKING_FLAG bit is set,
413 dict_table_t
* table
, /* in: database table in dictionary cache */
414 ulint mode
, /* in: lock mode */
415 que_thr_t
* thr
); /* in: query thread */
416 /*************************************************************************
417 Checks if there are any locks set on the table. */
422 /* out: TRUE if there are lock(s) */
423 dict_table_t
* table
); /* in: database table in dictionary cache */
424 /*****************************************************************
425 Removes a granted record lock of a transaction from the queue and grants
426 locks to other transactions waiting in the queue if they now are entitled
432 trx_t
* trx
, /* in: transaction that has set a record
434 rec_t
* rec
, /* in: record */
435 ulint lock_mode
); /* in: LOCK_S or LOCK_X */
436 /*************************************************************************
437 Releases a table lock.
438 Releases possible other transactions waiting for this lock. */
443 lock_t
* lock
); /* in: lock */
444 /*************************************************************************
445 Releases an auto-inc lock a transaction possibly has on a table.
446 Releases possible other transactions waiting for this lock. */
449 lock_table_unlock_auto_inc(
450 /*=======================*/
451 trx_t
* trx
); /* in: transaction */
452 /*************************************************************************
453 Releases transaction locks, and releases possible other transactions waiting
454 because of these locks. */
457 lock_release_off_kernel(
458 /*====================*/
459 trx_t
* trx
); /* in: transaction */
460 /*************************************************************************
461 Cancels a waiting lock request and releases possible other transactions
462 waiting behind it. */
465 lock_cancel_waiting_and_release(
466 /*============================*/
467 lock_t
* lock
); /* in: waiting lock request */
469 /*************************************************************************
470 Removes locks on a table to be dropped or truncated.
471 If remove_also_table_sx_locks is TRUE then table-level S and X locks are
472 also removed in addition to other table-level and record-level locks.
473 No lock, that is going to be removed, is allowed to be a wait lock. */
476 lock_remove_all_on_table(
477 /*=====================*/
478 dict_table_t
* table
, /* in: table to be dropped
480 ibool remove_also_table_sx_locks
);/* in: also removes
481 table S and X locks */
483 /*************************************************************************
484 Calculates the fold value of a page file address: used in inserting or
485 searching for a lock in the hash table. */
490 /* out: folded value */
491 ulint space
, /* in: space */
492 ulint page_no
);/* in: page number */
493 /*************************************************************************
494 Calculates the hash value of a page file address: used in inserting or
495 searching for a lock in the hash table. */
500 /* out: hashed value */
501 ulint space
, /* in: space */
502 ulint page_no
);/* in: page number */
503 /*************************************************************************
504 Gets the source table of an ALTER TABLE transaction. The table must be
505 covered by an IX or IS table lock. */
510 /* out: the source table of transaction,
511 if it is covered by an IX or IS table lock;
512 dest if there is no source table, and
513 NULL if the transaction is locking more than
514 two tables or an inconsistency is found */
515 trx_t
* trx
, /* in: transaction */
516 dict_table_t
* dest
, /* in: destination of ALTER TABLE */
517 ulint
* mode
); /* out: lock mode of the source table */
518 /*************************************************************************
519 Determine if the given table is exclusively "owned" by the given
520 transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
524 lock_is_table_exclusive(
525 /*====================*/
526 /* out: TRUE if table is only locked by trx,
527 with LOCK_IX, and possibly LOCK_AUTO_INC */
528 dict_table_t
* table
, /* in: table */
529 trx_t
* trx
); /* in: transaction */
530 /*************************************************************************
531 Checks if a lock request lock1 has to wait for request lock2. */
536 /* out: TRUE if lock1 has to wait for lock2 to be
538 lock_t
* lock1
, /* in: waiting lock */
539 lock_t
* lock2
); /* in: another lock; NOTE that it is assumed that this
540 has a lock bit set on the same record as in lock1 if
541 the locks are record locks */
542 /*************************************************************************
543 Checks that a transaction id is sensible, i.e., not in the future. */
546 lock_check_trx_id_sanity(
547 /*=====================*/
548 /* out: TRUE if ok */
549 dulint trx_id
, /* in: trx id */
550 rec_t
* rec
, /* in: user record */
551 dict_index_t
* index
, /* in: clustered index */
552 const ulint
* offsets
, /* in: rec_get_offsets(rec, index) */
553 ibool has_kernel_mutex
);/* in: TRUE if the caller owns the
555 /*************************************************************************
556 Validates the lock queue on a single record. */
559 lock_rec_queue_validate(
560 /*====================*/
561 /* out: TRUE if ok */
562 rec_t
* rec
, /* in: record to look at */
563 dict_index_t
* index
, /* in: index, or NULL if not known */
564 const ulint
* offsets
);/* in: rec_get_offsets(rec, index) */
565 /*************************************************************************
566 Prints info of a table lock. */
571 FILE* file
, /* in: file where to print */
572 lock_t
* lock
); /* in: table type lock */
573 /*************************************************************************
574 Prints info of a record lock. */
579 FILE* file
, /* in: file where to print */
580 lock_t
* lock
); /* in: record type lock */
581 /*************************************************************************
582 Prints info of locks for all transactions. */
585 lock_print_info_summary(
586 /*====================*/
587 /* out: FALSE if not able to obtain
588 kernel mutex and exits without
590 FILE* file
, /* in: file where to print */
591 ibool nowait
);/* in: whether to wait for the kernel
593 /*************************************************************************
594 Prints info of locks for each transaction. */
597 lock_print_info_all_transactions(
598 /*=============================*/
599 FILE* file
); /* in: file where to print */
600 /*************************************************************************
601 Validates the lock queue on a table. */
604 lock_table_queue_validate(
605 /*======================*/
606 /* out: TRUE if ok */
607 dict_table_t
* table
); /* in: table */
608 /*************************************************************************
609 Validates the record lock queues on a page. */
612 lock_rec_validate_page(
613 /*===================*/
614 /* out: TRUE if ok */
615 ulint space
, /* in: space id */
616 ulint page_no
);/* in: page number */
617 /*************************************************************************
618 Validates the lock system. */
623 /* out: TRUE if ok */
624 /*************************************************************************
625 Return approximate number or record locks (bits set in the bitmap) for
626 this transaction. Since delete-marked records may be removed, the
627 record count will not be precise. */
630 lock_number_of_rows_locked(
631 /*=======================*/
632 trx_t
* trx
); /* in: transaction */
634 /* The lock system */
635 extern lock_sys_t
* lock_sys
;
637 /* Lock modes and types */
639 #define LOCK_NONE 0 /* this flag is used elsewhere to note
641 #define LOCK_IS 2 /* intention shared */
642 #define LOCK_IX 3 /* intention exclusive */
643 #define LOCK_S 4 /* shared */
644 #define LOCK_X 5 /* exclusive */
645 #define LOCK_AUTO_INC 6 /* locks the auto-inc counter of a table
646 in an exclusive mode */
647 #define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the
648 type_mode field in a lock */
650 #define LOCK_TABLE 16 /* these type values should be so high that */
651 #define LOCK_REC 32 /* they can be ORed to the lock mode */
652 #define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the
653 type_mode field in a lock */
654 /* Waiting lock flag */
655 #define LOCK_WAIT 256 /* this wait bit should be so high that
656 it can be ORed to the lock mode and type;
657 when this bit is set, it means that the
658 lock has not yet been granted, it is just
659 waiting for its turn in the wait queue */
661 #define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock
662 in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */
663 #define LOCK_GAP 512 /* this gap bit should be so high that
664 it can be ORed to the other flags;
665 when this bit is set, it means that the
666 lock holds only on the gap before the record;
667 for instance, an x-lock on the gap does not
668 give permission to modify the record on which
669 the bit is set; locks of this type are created
670 when records are removed from the index chain
672 #define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on
673 the index record and does NOT block inserts
674 to the gap before the index record; this is
675 used in the case when we retrieve a record
676 with a unique key, and is also used in
677 locking plain SELECTs (not part of UPDATE
678 or DELETE) when the user has set the READ
679 COMMITTED isolation level */
680 #define LOCK_INSERT_INTENTION 2048 /* this bit is set when we place a waiting
681 gap type record lock request in order to let
682 an insert of an index record to wait until
683 there are no conflicting locks by other
684 transactions on the gap; note that this flag
685 remains set when the waiting lock is granted,
686 or if the lock is inherited to a neighboring
688 #define LOCK_CONV_BY_OTHER 4096 /* this bit is set when the lock is created
689 by other transaction */
690 /* Checks if this is a waiting lock created by lock->trx itself.
691 @param type_mode lock->type_mode
692 @return whether it is a waiting lock belonging to lock->trx */
693 #define lock_is_wait_not_by_other(type_mode) \
694 ((type_mode & (LOCK_CONV_BY_OTHER | LOCK_WAIT)) == LOCK_WAIT)
696 /* When lock bits are reset, the following flags are available: */
697 #define LOCK_RELEASE_WAIT 1
698 #define LOCK_NOT_RELEASE_WAIT 2
700 /* Lock operation struct */
701 typedef struct lock_op_struct lock_op_t
;
702 struct lock_op_struct
{
703 dict_table_t
* table
; /* table to be locked */
704 ulint mode
; /* lock mode */
707 #define LOCK_OP_START 1
708 #define LOCK_OP_COMPLETE 2
710 /* The lock system struct */
711 struct lock_sys_struct
{
712 hash_table_t
* rec_hash
; /* hash table of the record locks */
715 /* The lock system */
716 extern lock_sys_t
* lock_sys
;
720 #include "lock0lock.ic"