1
/******************************************************
2
The transaction lock system
6
Created 5/7/1996 Heikki Tuuri
7
*******************************************************/
13
#include "buf0types.h"
14
#include "trx0types.h"
15
#include "rem0types.h"
16
#include "dict0types.h"
17
#include "que0types.h"
18
#include "lock0types.h"
19
#include "read0types.h"
20
#include "hash0hash.h"
24
extern ibool lock_print_waits;
25
#endif /* UNIV_DEBUG */
26
/* Buffer for storing information about the most recent deadlock error */
27
extern FILE* lock_latest_err_file;
29
/*************************************************************************
30
Gets the size of a lock struct. */
35
/* out: size in bytes */
36
/*************************************************************************
37
Creates the lock system at database start. */
42
ulint n_cells); /* in: number of slots in lock hash table */
43
/*************************************************************************
44
Checks if some transaction has an implicit x-lock on a record in a clustered
48
lock_clust_rec_some_has_impl(
49
/*=========================*/
50
/* out: transaction which has the x-lock, or
52
const rec_t* rec, /* in: user record */
53
dict_index_t* index, /* in: clustered index */
54
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
55
/*************************************************************************
56
Gets the heap_no of the smallest user record on a page. */
61
/* out: heap_no of smallest
63
PAGE_HEAP_NO_SUPREMUM */
64
const buf_block_t* block); /* in: buffer block */
65
/*****************************************************************
66
Updates the lock table when we have reorganized a page. NOTE: we copy
67
also the locks set on the infimum of the page; the infimum may carry
68
locks if an update of a record is occurring on the page, and its locks
69
were temporarily stored on the infimum. */
72
lock_move_reorganize_page(
73
/*======================*/
74
const buf_block_t* block, /* in: old index page, now
76
const buf_block_t* oblock);/* in: copy of the old, not
78
/*****************************************************************
79
Moves the explicit locks on user records to another page if a record
80
list end is moved to another page. */
83
lock_move_rec_list_end(
84
/*===================*/
85
const buf_block_t* new_block, /* in: index page to move to */
86
const buf_block_t* block, /* in: index page */
87
const rec_t* rec); /* in: record on page: this
88
is the first record moved */
89
/*****************************************************************
90
Moves the explicit locks on user records to another page if a record
91
list start is moved to another page. */
94
lock_move_rec_list_start(
95
/*=====================*/
96
const buf_block_t* new_block, /* in: index page to move to */
97
const buf_block_t* block, /* in: index page */
98
const rec_t* rec, /* in: record on page:
101
const rec_t* old_end); /* in: old
106
/*****************************************************************
107
Updates the lock table when a page is split to the right. */
110
lock_update_split_right(
111
/*====================*/
112
const buf_block_t* right_block, /* in: right page */
113
const buf_block_t* left_block); /* in: left page */
114
/*****************************************************************
115
Updates the lock table when a page is merged to the right. */
118
lock_update_merge_right(
119
/*====================*/
120
const buf_block_t* right_block, /* in: right page to
122
const rec_t* orig_succ, /* in: original
126
const buf_block_t* left_block); /* in: merged index
129
/*****************************************************************
130
Updates the lock table when the root page is copied to another in
131
btr_root_raise_and_insert. Note that we leave lock structs on the
132
root page, even though they do not make sense on other than leaf
133
pages: the reason is that in a pessimistic update the infimum record
134
of the root page will act as a dummy carrier of the locks of the record
138
lock_update_root_raise(
139
/*===================*/
140
const buf_block_t* block, /* in: index page to which copied */
141
const buf_block_t* root); /* in: root page */
142
/*****************************************************************
143
Updates the lock table when a page is copied to another and the original page
144
is removed from the chain of leaf pages, except if page is the root! */
147
lock_update_copy_and_discard(
148
/*=========================*/
149
const buf_block_t* new_block, /* in: index page to
151
const buf_block_t* block); /* in: index page;
153
/*****************************************************************
154
Updates the lock table when a page is split to the left. */
157
lock_update_split_left(
158
/*===================*/
159
const buf_block_t* right_block, /* in: right page */
160
const buf_block_t* left_block); /* in: left page */
161
/*****************************************************************
162
Updates the lock table when a page is merged to the left. */
165
lock_update_merge_left(
166
/*===================*/
167
const buf_block_t* left_block, /* in: left page to
169
const rec_t* orig_pred, /* in: original predecessor
170
of supremum on the left page
172
const buf_block_t* right_block); /* in: merged index page
173
which will be discarded */
174
/*****************************************************************
175
Resets the original locks on heir and replaces them with gap type locks
176
inherited from rec. */
179
lock_rec_reset_and_inherit_gap_locks(
180
/*=================================*/
181
const buf_block_t* heir_block, /* in: block containing the
182
record which inherits */
183
const buf_block_t* block, /* in: block containing the
184
record from which inherited;
185
does NOT reset the locks on
187
ulint heir_heap_no, /* in: heap_no of the
189
ulint heap_no); /* in: heap_no of the
191
/*****************************************************************
192
Updates the lock table when a page is discarded. */
197
const buf_block_t* heir_block, /* in: index page
198
which will inherit the locks */
199
ulint heir_heap_no, /* in: heap_no of the record
200
which will inherit the locks */
201
const buf_block_t* block); /* in: index page
202
which will be discarded */
203
/*****************************************************************
204
Updates the lock table when a new user record is inserted. */
209
const buf_block_t* block, /* in: buffer block containing rec */
210
const rec_t* rec); /* in: the inserted record */
211
/*****************************************************************
212
Updates the lock table when a record is removed. */
217
const buf_block_t* block, /* in: buffer block containing rec */
218
const rec_t* rec); /* in: the record to be removed */
219
/*************************************************************************
220
Stores on the page infimum record the explicit locks of another record.
221
This function is used to store the lock state of a record when it is
222
updated and the size of the record changes in the update. The record
223
is in such an update moved, perhaps to another page. The infimum record
224
acts as a dummy carrier record, taking care of lock releases while the
225
actual record is being moved. */
228
lock_rec_store_on_page_infimum(
229
/*===========================*/
230
const buf_block_t* block, /* in: buffer block containing rec */
231
const rec_t* rec); /* in: record whose lock state
232
is stored on the infimum
233
record of the same page; lock
234
bits are reset on the
236
/*************************************************************************
237
Restores the state of explicit lock requests on a single record, where the
238
state was stored on the infimum of the page. */
241
lock_rec_restore_from_page_infimum(
242
/*===============================*/
243
const buf_block_t* block, /* in: buffer block containing rec */
244
const rec_t* rec, /* in: record whose lock state
246
const buf_block_t* donator);/* in: page (rec is not
247
necessarily on this page)
248
whose infimum stored the lock
249
state; lock bits are reset on
251
/*************************************************************************
252
Returns TRUE if there are explicit record locks on a page. */
255
lock_rec_expl_exist_on_page(
256
/*========================*/
257
/* out: TRUE if there are explicit record locks on
259
ulint space, /* in: space id */
260
ulint page_no);/* in: page number */
261
/*************************************************************************
262
Checks if locks of other transactions prevent an immediate insert of
263
a record. If they do, first tests if the query thread should anyway
264
be suspended for some reason; if not, then puts the transaction and
265
the query thread to the lock wait state and inserts a waiting request
266
for a gap x-lock to the lock queue. */
269
lock_rec_insert_check_and_lock(
270
/*===========================*/
271
/* out: DB_SUCCESS, DB_LOCK_WAIT,
272
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
273
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is
275
rec_t* rec, /* in: record after which to insert */
276
buf_block_t* block, /* in/out: buffer block of rec */
277
dict_index_t* index, /* in: index */
278
que_thr_t* thr, /* in: query thread */
279
ibool* inherit);/* out: set to TRUE if the new
280
inserted record maybe should inherit
281
LOCK_GAP type locks from the successor
283
/*************************************************************************
284
Checks if locks of other transactions prevent an immediate modify (update,
285
delete mark, or delete unmark) of a clustered index record. If they do,
286
first tests if the query thread should anyway be suspended for some
287
reason; if not, then puts the transaction and the query thread to the
288
lock wait state and inserts a waiting request for a record x-lock to the
292
lock_clust_rec_modify_check_and_lock(
293
/*=================================*/
295
DB_LOCK_WAIT, DB_DEADLOCK, or
296
DB_QUE_THR_SUSPENDED */
297
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
298
bit is set, does nothing */
299
const buf_block_t* block, /* in: buffer block of rec */
300
const rec_t* rec, /* in: record which should be
302
dict_index_t* index, /* in: clustered index */
303
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
304
que_thr_t* thr); /* in: query thread */
305
/*************************************************************************
306
Checks if locks of other transactions prevent an immediate modify
307
(delete mark or delete unmark) of a secondary index record. */
310
lock_sec_rec_modify_check_and_lock(
311
/*===============================*/
312
/* out: DB_SUCCESS, DB_LOCK_WAIT,
313
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
314
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
315
bit is set, does nothing */
316
buf_block_t* block, /* in/out: buffer block of rec */
317
rec_t* rec, /* in: record which should be
318
modified; NOTE: as this is a secondary
319
index, we always have to modify the
320
clustered index record first: see the
322
dict_index_t* index, /* in: secondary index */
323
que_thr_t* thr); /* in: query thread */
324
/*************************************************************************
325
Like the counterpart for a clustered index below, but now we read a
326
secondary index record. */
329
lock_sec_rec_read_check_and_lock(
330
/*=============================*/
332
DB_LOCK_WAIT, DB_DEADLOCK, or
333
DB_QUE_THR_SUSPENDED */
334
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
335
bit is set, does nothing */
336
const buf_block_t* block, /* in: buffer block of rec */
337
const rec_t* rec, /* in: user record or page
338
supremum record which should
339
be read or passed over by a
341
dict_index_t* index, /* in: secondary index */
342
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
343
enum lock_mode mode, /* in: mode of the lock which
344
the read cursor should set on
345
records: LOCK_S or LOCK_X; the
346
latter is possible in
348
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
350
que_thr_t* thr); /* in: query thread */
351
/*************************************************************************
352
Checks if locks of other transactions prevent an immediate read, or passing
353
over by a read cursor, of a clustered index record. If they do, first tests
354
if the query thread should anyway be suspended for some reason; if not, then
355
puts the transaction and the query thread to the lock wait state and inserts a
356
waiting request for a record lock to the lock queue. Sets the requested mode
357
lock on the record. */
360
lock_clust_rec_read_check_and_lock(
361
/*===============================*/
363
DB_LOCK_WAIT, DB_DEADLOCK, or
364
DB_QUE_THR_SUSPENDED */
365
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
366
bit is set, does nothing */
367
const buf_block_t* block, /* in: buffer block of rec */
368
const rec_t* rec, /* in: user record or page
369
supremum record which should
370
be read or passed over by a
372
dict_index_t* index, /* in: clustered index */
373
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
374
enum lock_mode mode, /* in: mode of the lock which
375
the read cursor should set on
376
records: LOCK_S or LOCK_X; the
377
latter is possible in
379
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
381
que_thr_t* thr); /* in: query thread */
382
/*************************************************************************
383
Checks if locks of other transactions prevent an immediate read, or passing
384
over by a read cursor, of a clustered index record. If they do, first tests
385
if the query thread should anyway be suspended for some reason; if not, then
386
puts the transaction and the query thread to the lock wait state and inserts a
387
waiting request for a record lock to the lock queue. Sets the requested mode
388
lock on the record. This is an alternative version of
389
lock_clust_rec_read_check_and_lock() that does not require the parameter
393
lock_clust_rec_read_check_and_lock_alt(
394
/*===================================*/
396
DB_LOCK_WAIT, DB_DEADLOCK, or
397
DB_QUE_THR_SUSPENDED */
398
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
399
bit is set, does nothing */
400
const buf_block_t* block, /* in: buffer block of rec */
401
const rec_t* rec, /* in: user record or page
402
supremum record which should
403
be read or passed over by a
405
dict_index_t* index, /* in: clustered index */
406
enum lock_mode mode, /* in: mode of the lock which
407
the read cursor should set on
408
records: LOCK_S or LOCK_X; the
409
latter is possible in
411
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
413
que_thr_t* thr); /* in: query thread */
414
/*************************************************************************
415
Checks that a record is seen in a consistent read. */
418
lock_clust_rec_cons_read_sees(
419
/*==========================*/
420
/* out: TRUE if sees, or FALSE if an earlier
421
version of the record should be retrieved */
422
const rec_t* rec, /* in: user record which should be read or
423
passed over by a read cursor */
424
dict_index_t* index, /* in: clustered index */
425
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
426
read_view_t* view); /* in: consistent read view */
427
/*************************************************************************
428
Checks that a non-clustered index record is seen in a consistent read. */
431
lock_sec_rec_cons_read_sees(
432
/*========================*/
433
/* out: TRUE if certainly
434
sees, or FALSE if an earlier
435
version of the clustered index
436
record might be needed: NOTE
437
that a non-clustered index
438
page contains so little
440
modifications that also in the
441
case FALSE, the present
442
version of rec may be the
443
right, but we must check this
444
from the clustered index
446
const rec_t* rec, /* in: user record which
447
should be read or passed over
449
const read_view_t* view); /* in: consistent read view */
450
/*************************************************************************
451
Locks the specified database table in the mode given. If the lock cannot
452
be granted immediately, the query thread is put to wait. */
457
/* out: DB_SUCCESS, DB_LOCK_WAIT,
458
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
459
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
461
dict_table_t* table, /* in: database table in dictionary cache */
462
enum lock_mode mode, /* in: lock mode */
463
que_thr_t* thr); /* in: query thread */
464
/*************************************************************************
465
Checks if there are any locks set on the table. */
470
/* out: TRUE if there are lock(s) */
471
dict_table_t* table); /* in: database table in dictionary cache */
472
/*****************************************************************
473
Removes a granted record lock of a transaction from the queue and grants
474
locks to other transactions waiting in the queue if they now are entitled
480
trx_t* trx, /* in: transaction that has
482
const buf_block_t* block, /* in: buffer block containing rec */
483
const rec_t* rec, /* in: record */
484
enum lock_mode lock_mode);/* in: LOCK_S or LOCK_X */
485
/*************************************************************************
486
Releases a table lock.
487
Releases possible other transactions waiting for this lock. */
492
lock_t* lock); /* in: lock */
493
/*************************************************************************
494
Releases transaction locks, and releases possible other transactions waiting
495
because of these locks. */
498
lock_release_off_kernel(
499
/*====================*/
500
trx_t* trx); /* in: transaction */
501
/*************************************************************************
502
Cancels a waiting lock request and releases possible other transactions
503
waiting behind it. */
506
lock_cancel_waiting_and_release(
507
/*============================*/
508
lock_t* lock); /* in: waiting lock request */
510
/*************************************************************************
511
Removes locks on a table to be dropped or truncated.
512
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
513
also removed in addition to other table-level and record-level locks.
514
No lock, that is going to be removed, is allowed to be a wait lock. */
517
lock_remove_all_on_table(
518
/*=====================*/
519
dict_table_t* table, /* in: table to be dropped
521
ibool remove_also_table_sx_locks);/* in: also removes
522
table S and X locks */
524
/*************************************************************************
525
Calculates the fold value of a page file address: used in inserting or
526
searching for a lock in the hash table. */
531
/* out: folded value */
532
ulint space, /* in: space */
533
ulint page_no)/* in: page number */
534
__attribute__((__const__));
535
/*************************************************************************
536
Calculates the hash value of a page file address: used in inserting or
537
searching for a lock in the hash table. */
542
/* out: hashed value */
543
ulint space, /* in: space */
544
ulint page_no);/* in: page number */
546
/**************************************************************************
547
Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED,
551
lock_rec_find_set_bit(
552
/*==================*/
553
/* out: bit index == heap number of
554
the record, or ULINT_UNDEFINED if none found */
555
const lock_t* lock); /* in: record lock with at least one bit set */
557
/*************************************************************************
558
Gets the source table of an ALTER TABLE transaction. The table must be
559
covered by an IX or IS table lock. */
564
/* out: the source table of transaction,
565
if it is covered by an IX or IS table lock;
566
dest if there is no source table, and
567
NULL if the transaction is locking more than
568
two tables or an inconsistency is found */
569
trx_t* trx, /* in: transaction */
570
dict_table_t* dest, /* in: destination of ALTER TABLE */
571
enum lock_mode* mode); /* out: lock mode of the source table */
572
/*************************************************************************
573
Determine if the given table is exclusively "owned" by the given
574
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
578
lock_is_table_exclusive(
579
/*====================*/
580
/* out: TRUE if table is only locked by trx,
581
with LOCK_IX, and possibly LOCK_AUTO_INC */
582
dict_table_t* table, /* in: table */
583
trx_t* trx); /* in: transaction */
584
/*************************************************************************
585
Checks if a lock request lock1 has to wait for request lock2. */
590
/* out: TRUE if lock1 has to wait for
591
lock2 to be removed */
592
const lock_t* lock1, /* in: waiting lock */
593
const lock_t* lock2); /* in: another lock; NOTE that it is
594
assumed that this has a lock bit set
595
on the same record as in lock1 if the
596
locks are record locks */
597
/*************************************************************************
598
Checks that a transaction id is sensible, i.e., not in the future. */
601
lock_check_trx_id_sanity(
602
/*=====================*/
603
/* out: TRUE if ok */
604
dulint trx_id, /* in: trx id */
605
const rec_t* rec, /* in: user record */
606
dict_index_t* index, /* in: clustered index */
607
const ulint* offsets, /* in: rec_get_offsets(rec, index) */
608
ibool has_kernel_mutex);/* in: TRUE if the caller owns the
610
/*************************************************************************
611
Prints info of a table lock. */
616
FILE* file, /* in: file where to print */
617
const lock_t* lock); /* in: table type lock */
618
/*************************************************************************
619
Prints info of a record lock. */
624
FILE* file, /* in: file where to print */
625
const lock_t* lock); /* in: record type lock */
626
/*************************************************************************
627
Prints info of locks for all transactions. */
630
lock_print_info_summary(
631
/*====================*/
632
FILE* file); /* in: file where to print */
633
/*************************************************************************
634
Prints info of locks for each transaction. */
637
lock_print_info_all_transactions(
638
/*=============================*/
639
FILE* file); /* in: file where to print */
640
/*************************************************************************
641
Return approximate number or record locks (bits set in the bitmap) for
642
this transaction. Since delete-marked records may be removed, the
643
record count will not be precise. */
646
lock_number_of_rows_locked(
647
/*=======================*/
648
trx_t* trx); /* in: transaction */
649
/***********************************************************************
650
Release all the transaction's autoinc locks. */
653
lock_release_autoinc_locks(
654
/*=======================*/
655
trx_t* trx); /* in/out: transaction */
657
/***********************************************************************
658
Gets the type of a lock. Non-inline version for using outside of the
664
/* out: LOCK_TABLE or LOCK_REC */
665
const lock_t* lock); /* in: lock */
667
/***********************************************************************
668
Gets the id of the transaction owning a lock. */
673
/* out: transaction id */
674
const lock_t* lock); /* in: lock */
676
/***********************************************************************
677
Gets the mode of a lock in a human readable string.
678
The string should not be free()'d or modified. */
684
const lock_t* lock); /* in: lock */
686
/***********************************************************************
687
Gets the type of a lock in a human readable string.
688
The string should not be free()'d or modified. */
694
const lock_t* lock); /* in: lock */
696
/***********************************************************************
697
Gets the id of the table on which the lock is. */
702
/* out: id of the table */
703
const lock_t* lock); /* in: lock */
705
/***********************************************************************
706
Gets the name of the table on which the lock is.
707
The string should not be free()'d or modified. */
712
/* out: name of the table */
713
const lock_t* lock); /* in: lock */
715
/***********************************************************************
716
For a record lock, gets the index on which the lock is. */
722
const lock_t* lock); /* in: lock */
724
/***********************************************************************
725
For a record lock, gets the name of the index on which the lock is.
726
The string should not be free()'d or modified. */
729
lock_rec_get_index_name(
730
/*====================*/
731
/* out: name of the index */
732
const lock_t* lock); /* in: lock */
734
/***********************************************************************
735
For a record lock, gets the tablespace number on which the lock is. */
738
lock_rec_get_space_id(
739
/*==================*/
740
/* out: tablespace number */
741
const lock_t* lock); /* in: lock */
743
/***********************************************************************
744
For a record lock, gets the page number on which the lock is. */
747
lock_rec_get_page_no(
748
/*=================*/
749
/* out: page number */
750
const lock_t* lock); /* in: lock */
752
/* Lock modes and types */
753
#define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the
754
type_mode field in a lock */
756
#define LOCK_TABLE 16 /* these type values should be so high that */
757
#define LOCK_REC 32 /* they can be ORed to the lock mode */
758
#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the
759
type_mode field in a lock */
760
/* Waiting lock flag */
761
#define LOCK_WAIT 256 /* this wait bit should be so high that
762
it can be ORed to the lock mode and type;
763
when this bit is set, it means that the
764
lock has not yet been granted, it is just
765
waiting for its turn in the wait queue */
767
#define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock
768
in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */
769
#define LOCK_GAP 512 /* this gap bit should be so high that
770
it can be ORed to the other flags;
771
when this bit is set, it means that the
772
lock holds only on the gap before the record;
773
for instance, an x-lock on the gap does not
774
give permission to modify the record on which
775
the bit is set; locks of this type are created
776
when records are removed from the index chain
778
#define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on
779
the index record and does NOT block inserts
780
to the gap before the index record; this is
781
used in the case when we retrieve a record
782
with a unique key, and is also used in
783
locking plain SELECTs (not part of UPDATE
784
or DELETE) when the user has set the READ
785
COMMITTED isolation level */
786
#define LOCK_INSERT_INTENTION 2048 /* this bit is set when we place a waiting
787
gap type record lock request in order to let
788
an insert of an index record to wait until
789
there are no conflicting locks by other
790
transactions on the gap; note that this flag
791
remains set when the waiting lock is granted,
792
or if the lock is inherited to a neighboring
795
/* When lock bits are reset, the following flags are available: */
796
#define LOCK_RELEASE_WAIT 1
797
#define LOCK_NOT_RELEASE_WAIT 2
799
/* Lock operation struct */
800
typedef struct lock_op_struct lock_op_t;
801
struct lock_op_struct{
802
dict_table_t* table; /* table to be locked */
803
enum lock_mode mode; /* lock mode */
806
#define LOCK_OP_START 1
807
#define LOCK_OP_COMPLETE 2
809
/* The lock system struct */
810
struct lock_sys_struct{
811
hash_table_t* rec_hash; /* hash table of the record locks */
814
/* The lock system */
815
extern lock_sys_t* lock_sys;
819
#include "lock0lock.ic"