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"
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 clustered
47
lock_clust_rec_some_has_impl(
48
/*=========================*/
49
/* out: transaction which has the x-lock, or
51
const rec_t* rec, /* in: user record */
52
dict_index_t* index, /* in: clustered index */
53
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
54
/*************************************************************************
55
Gets the heap_no of the smallest user record on a page. */
60
/* out: heap_no of smallest
62
PAGE_HEAP_NO_SUPREMUM */
63
const buf_block_t* block); /* in: buffer block */
64
/*****************************************************************
65
Updates the lock table when we have reorganized a page. NOTE: we copy
66
also the locks set on the infimum of the page; the infimum may carry
67
locks if an update of a record is occurring on the page, and its locks
68
were temporarily stored on the infimum. */
71
lock_move_reorganize_page(
72
/*======================*/
73
const buf_block_t* block, /* in: old index page, now
75
const buf_block_t* oblock);/* in: copy of the old, not
77
/*****************************************************************
78
Moves the explicit locks on user records to another page if a record
79
list end is moved to another page. */
82
lock_move_rec_list_end(
83
/*===================*/
84
const buf_block_t* new_block, /* in: index page to move to */
85
const buf_block_t* block, /* in: index page */
86
const rec_t* rec); /* in: record on page: this
87
is the first record moved */
88
/*****************************************************************
89
Moves the explicit locks on user records to another page if a record
90
list start is moved to another page. */
93
lock_move_rec_list_start(
94
/*=====================*/
95
const buf_block_t* new_block, /* in: index page to move to */
96
const buf_block_t* block, /* in: index page */
97
const rec_t* rec, /* in: record on page:
100
const rec_t* old_end); /* in: old
105
/*****************************************************************
106
Updates the lock table when a page is split to the right. */
109
lock_update_split_right(
110
/*====================*/
111
const buf_block_t* right_block, /* in: right page */
112
const buf_block_t* left_block); /* in: left page */
113
/*****************************************************************
114
Updates the lock table when a page is merged to the right. */
117
lock_update_merge_right(
118
/*====================*/
119
const buf_block_t* right_block, /* in: right page to
121
const rec_t* orig_succ, /* in: original
125
const buf_block_t* left_block); /* in: merged index
128
/*****************************************************************
129
Updates the lock table when the root page is copied to another in
130
btr_root_raise_and_insert. Note that we leave lock structs on the
131
root page, even though they do not make sense on other than leaf
132
pages: the reason is that in a pessimistic update the infimum record
133
of the root page will act as a dummy carrier of the locks of the record
137
lock_update_root_raise(
138
/*===================*/
139
const buf_block_t* block, /* in: index page to which copied */
140
const buf_block_t* root); /* in: root page */
141
/*****************************************************************
142
Updates the lock table when a page is copied to another and the original page
143
is removed from the chain of leaf pages, except if page is the root! */
146
lock_update_copy_and_discard(
147
/*=========================*/
148
const buf_block_t* new_block, /* in: index page to
150
const buf_block_t* block); /* in: index page;
152
/*****************************************************************
153
Updates the lock table when a page is split to the left. */
156
lock_update_split_left(
157
/*===================*/
158
const buf_block_t* right_block, /* in: right page */
159
const buf_block_t* left_block); /* in: left page */
160
/*****************************************************************
161
Updates the lock table when a page is merged to the left. */
164
lock_update_merge_left(
165
/*===================*/
166
const buf_block_t* left_block, /* in: left page to
168
const rec_t* orig_pred, /* in: original predecessor
169
of supremum on the left page
171
const buf_block_t* right_block); /* in: merged index page
172
which will be discarded */
173
/*****************************************************************
174
Resets the original locks on heir and replaces them with gap type locks
175
inherited from rec. */
178
lock_rec_reset_and_inherit_gap_locks(
179
/*=================================*/
180
const buf_block_t* heir_block, /* in: block containing the
181
record which inherits */
182
const buf_block_t* block, /* in: block containing the
183
record from which inherited;
184
does NOT reset the locks on
186
ulint heir_heap_no, /* in: heap_no of the
188
ulint heap_no); /* in: heap_no of the
190
/*****************************************************************
191
Updates the lock table when a page is discarded. */
196
const buf_block_t* heir_block, /* in: index page
197
which will inherit the locks */
198
ulint heir_heap_no, /* in: heap_no of the record
199
which will inherit the locks */
200
const buf_block_t* block); /* in: index page
201
which will be discarded */
202
/*****************************************************************
203
Updates the lock table when a new user record is inserted. */
208
const buf_block_t* block, /* in: buffer block containing rec */
209
const rec_t* rec); /* in: the inserted record */
210
/*****************************************************************
211
Updates the lock table when a record is removed. */
216
const buf_block_t* block, /* in: buffer block containing rec */
217
const rec_t* rec); /* in: the record to be removed */
218
/*************************************************************************
219
Stores on the page infimum record the explicit locks of another record.
220
This function is used to store the lock state of a record when it is
221
updated and the size of the record changes in the update. The record
222
is in such an update moved, perhaps to another page. The infimum record
223
acts as a dummy carrier record, taking care of lock releases while the
224
actual record is being moved. */
227
lock_rec_store_on_page_infimum(
228
/*===========================*/
229
const buf_block_t* block, /* in: buffer block containing rec */
230
const rec_t* rec); /* in: record whose lock state
231
is stored on the infimum
232
record of the same page; lock
233
bits are reset on the
235
/*************************************************************************
236
Restores the state of explicit lock requests on a single record, where the
237
state was stored on the infimum of the page. */
240
lock_rec_restore_from_page_infimum(
241
/*===============================*/
242
const buf_block_t* block, /* in: buffer block containing rec */
243
const rec_t* rec, /* in: record whose lock state
245
const buf_block_t* donator);/* in: page (rec is not
246
necessarily on this page)
247
whose infimum stored the lock
248
state; lock bits are reset on
250
/*************************************************************************
251
Returns TRUE if there are explicit record locks on a page. */
254
lock_rec_expl_exist_on_page(
255
/*========================*/
256
/* out: TRUE if there are explicit record locks on
258
ulint space, /* in: space id */
259
ulint page_no);/* in: page number */
260
/*************************************************************************
261
Checks if locks of other transactions prevent an immediate insert of
262
a record. If they do, first tests if the query thread should anyway
263
be suspended for some reason; if not, then puts the transaction and
264
the query thread to the lock wait state and inserts a waiting request
265
for a gap x-lock to the lock queue. */
268
lock_rec_insert_check_and_lock(
269
/*===========================*/
270
/* out: DB_SUCCESS, DB_LOCK_WAIT,
271
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
272
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is
274
rec_t* rec, /* in: record after which to insert */
275
buf_block_t* block, /* in/out: buffer block of rec */
276
dict_index_t* index, /* in: index */
277
que_thr_t* thr, /* in: query thread */
278
ibool* inherit);/* out: set to TRUE if the new
279
inserted record maybe should inherit
280
LOCK_GAP type locks from the successor
282
/*************************************************************************
283
Checks if locks of other transactions prevent an immediate modify (update,
284
delete mark, or delete unmark) of a clustered index record. If they do,
285
first tests if the query thread should anyway be suspended for some
286
reason; if not, then puts the transaction and the query thread to the
287
lock wait state and inserts a waiting request for a record x-lock to the
291
lock_clust_rec_modify_check_and_lock(
292
/*=================================*/
294
DB_LOCK_WAIT, DB_DEADLOCK, or
295
DB_QUE_THR_SUSPENDED */
296
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
297
bit is set, does nothing */
298
const buf_block_t* block, /* in: buffer block of rec */
299
const rec_t* rec, /* in: record which should be
301
dict_index_t* index, /* in: clustered index */
302
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
303
que_thr_t* thr); /* in: query thread */
304
/*************************************************************************
305
Checks if locks of other transactions prevent an immediate modify
306
(delete mark or delete unmark) of a secondary index record. */
309
lock_sec_rec_modify_check_and_lock(
310
/*===============================*/
311
/* out: DB_SUCCESS, DB_LOCK_WAIT,
312
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
313
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
314
bit is set, does nothing */
315
buf_block_t* block, /* in/out: buffer block of rec */
316
rec_t* rec, /* in: record which should be
317
modified; NOTE: as this is a secondary
318
index, we always have to modify the
319
clustered index record first: see the
321
dict_index_t* index, /* in: secondary index */
322
que_thr_t* thr); /* in: query thread */
323
/*************************************************************************
324
Like the counterpart for a clustered index below, but now we read a
325
secondary index record. */
328
lock_sec_rec_read_check_and_lock(
329
/*=============================*/
331
DB_LOCK_WAIT, DB_DEADLOCK, or
332
DB_QUE_THR_SUSPENDED */
333
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
334
bit is set, does nothing */
335
const buf_block_t* block, /* in: buffer block of rec */
336
const rec_t* rec, /* in: user record or page
337
supremum record which should
338
be read or passed over by a
340
dict_index_t* index, /* in: secondary index */
341
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
342
enum lock_mode mode, /* in: mode of the lock which
343
the read cursor should set on
344
records: LOCK_S or LOCK_X; the
345
latter is possible in
347
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
349
que_thr_t* thr); /* in: query thread */
350
/*************************************************************************
351
Checks if locks of other transactions prevent an immediate read, or passing
352
over by a read cursor, of a clustered index record. If they do, first tests
353
if the query thread should anyway be suspended for some reason; if not, then
354
puts the transaction and the query thread to the lock wait state and inserts a
355
waiting request for a record lock to the lock queue. Sets the requested mode
356
lock on the record. */
359
lock_clust_rec_read_check_and_lock(
360
/*===============================*/
362
DB_LOCK_WAIT, DB_DEADLOCK, or
363
DB_QUE_THR_SUSPENDED */
364
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
365
bit is set, does nothing */
366
const buf_block_t* block, /* in: buffer block of rec */
367
const rec_t* rec, /* in: user record or page
368
supremum record which should
369
be read or passed over by a
371
dict_index_t* index, /* in: clustered index */
372
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
373
enum lock_mode mode, /* in: mode of the lock which
374
the read cursor should set on
375
records: LOCK_S or LOCK_X; the
376
latter is possible in
378
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
380
que_thr_t* thr); /* in: query thread */
381
/*************************************************************************
382
Checks if locks of other transactions prevent an immediate read, or passing
383
over by a read cursor, of a clustered index record. If they do, first tests
384
if the query thread should anyway be suspended for some reason; if not, then
385
puts the transaction and the query thread to the lock wait state and inserts a
386
waiting request for a record lock to the lock queue. Sets the requested mode
387
lock on the record. This is an alternative version of
388
lock_clust_rec_read_check_and_lock() that does not require the parameter
392
lock_clust_rec_read_check_and_lock_alt(
393
/*===================================*/
395
DB_LOCK_WAIT, DB_DEADLOCK, or
396
DB_QUE_THR_SUSPENDED */
397
ulint flags, /* in: if BTR_NO_LOCKING_FLAG
398
bit is set, does nothing */
399
const buf_block_t* block, /* in: buffer block of rec */
400
const rec_t* rec, /* in: user record or page
401
supremum record which should
402
be read or passed over by a
404
dict_index_t* index, /* in: clustered index */
405
enum lock_mode mode, /* in: mode of the lock which
406
the read cursor should set on
407
records: LOCK_S or LOCK_X; the
408
latter is possible in
410
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
412
que_thr_t* thr); /* in: query thread */
413
/*************************************************************************
414
Checks that a record is seen in a consistent read. */
417
lock_clust_rec_cons_read_sees(
418
/*==========================*/
419
/* out: TRUE if sees, or FALSE if an earlier
420
version of the record should be retrieved */
421
const rec_t* rec, /* in: user record which should be read or
422
passed over by a read cursor */
423
dict_index_t* index, /* in: clustered index */
424
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
425
read_view_t* view); /* in: consistent read view */
426
/*************************************************************************
427
Checks that a non-clustered index record is seen in a consistent read. */
430
lock_sec_rec_cons_read_sees(
431
/*========================*/
432
/* out: TRUE if certainly
433
sees, or FALSE if an earlier
434
version of the clustered index
435
record might be needed: NOTE
436
that a non-clustered index
437
page contains so little
439
modifications that also in the
440
case FALSE, the present
441
version of rec may be the
442
right, but we must check this
443
from the clustered index
445
const rec_t* rec, /* in: user record which
446
should be read or passed over
448
const read_view_t* view); /* in: consistent read view */
449
/*************************************************************************
450
Locks the specified database table in the mode given. If the lock cannot
451
be granted immediately, the query thread is put to wait. */
456
/* out: DB_SUCCESS, DB_LOCK_WAIT,
457
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
458
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
460
dict_table_t* table, /* in: database table in dictionary cache */
461
enum lock_mode mode, /* in: lock mode */
462
que_thr_t* thr); /* in: query thread */
463
/*************************************************************************
464
Checks if there are any locks set on the table. */
469
/* out: TRUE if there are lock(s) */
470
dict_table_t* table); /* in: database table in dictionary cache */
471
/*****************************************************************
472
Removes a granted record lock of a transaction from the queue and grants
473
locks to other transactions waiting in the queue if they now are entitled
479
trx_t* trx, /* in: transaction that has
481
const buf_block_t* block, /* in: buffer block containing rec */
482
const rec_t* rec, /* in: record */
483
enum lock_mode lock_mode);/* in: LOCK_S or LOCK_X */
484
/*************************************************************************
485
Releases a table lock.
486
Releases possible other transactions waiting for this lock. */
491
lock_t* lock); /* in: lock */
492
/*************************************************************************
493
Releases an auto-inc lock a transaction possibly has on a table.
494
Releases possible other transactions waiting for this lock. */
497
lock_table_unlock_auto_inc(
498
/*=======================*/
499
trx_t* trx); /* in: transaction */
500
/*************************************************************************
501
Releases transaction locks, and releases possible other transactions waiting
502
because of these locks. */
505
lock_release_off_kernel(
506
/*====================*/
507
trx_t* trx); /* in: transaction */
508
/*************************************************************************
509
Cancels a waiting lock request and releases possible other transactions
510
waiting behind it. */
513
lock_cancel_waiting_and_release(
514
/*============================*/
515
lock_t* lock); /* in: waiting lock request */
516
/*************************************************************************
517
Resets all locks, both table and record locks, on a table to be dropped.
518
No lock is allowed to be a wait lock. */
521
lock_reset_all_on_table(
522
/*====================*/
523
dict_table_t* table); /* in: table to be dropped */
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 */
650
/***********************************************************************
651
Gets the type of a lock. Non-inline version for using outside of the
657
/* out: LOCK_TABLE or LOCK_REC */
658
const lock_t* lock); /* in: lock */
660
/***********************************************************************
661
Gets the id of the transaction owning a lock. */
666
/* out: transaction id */
667
const lock_t* lock); /* in: lock */
669
/***********************************************************************
670
Gets the mode of a lock in a human readable string.
671
The string should not be free()'d or modified. */
677
const lock_t* lock); /* in: lock */
679
/***********************************************************************
680
Gets the type of a lock in a human readable string.
681
The string should not be free()'d or modified. */
687
const lock_t* lock); /* in: lock */
689
/***********************************************************************
690
Gets the id of the table on which the lock is. */
695
/* out: id of the table */
696
const lock_t* lock); /* in: lock */
698
/***********************************************************************
699
Gets the name of the table on which the lock is.
700
The string should not be free()'d or modified. */
705
/* out: name of the table */
706
const lock_t* lock); /* in: lock */
708
/***********************************************************************
709
For a record lock, gets the index on which the lock is. */
715
const lock_t* lock); /* in: lock */
717
/***********************************************************************
718
For a record lock, gets the name of the index on which the lock is.
719
The string should not be free()'d or modified. */
722
lock_rec_get_index_name(
723
/*====================*/
724
/* out: name of the index */
725
const lock_t* lock); /* in: lock */
727
/***********************************************************************
728
For a record lock, gets the tablespace number on which the lock is. */
731
lock_rec_get_space_id(
732
/*==================*/
733
/* out: tablespace number */
734
const lock_t* lock); /* in: lock */
736
/***********************************************************************
737
For a record lock, gets the page number on which the lock is. */
740
lock_rec_get_page_no(
741
/*=================*/
742
/* out: page number */
743
const lock_t* lock); /* in: lock */
745
/* Lock modes and types */
746
#define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the
747
type_mode field in a lock */
749
#define LOCK_TABLE 16 /* these type values should be so high that */
750
#define LOCK_REC 32 /* they can be ORed to the lock mode */
751
#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the
752
type_mode field in a lock */
753
/* Waiting lock flag */
754
#define LOCK_WAIT 256 /* this wait bit should be so high that
755
it can be ORed to the lock mode and type;
756
when this bit is set, it means that the
757
lock has not yet been granted, it is just
758
waiting for its turn in the wait queue */
760
#define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock
761
in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */
762
#define LOCK_GAP 512 /* this gap bit should be so high that
763
it can be ORed to the other flags;
764
when this bit is set, it means that the
765
lock holds only on the gap before the record;
766
for instance, an x-lock on the gap does not
767
give permission to modify the record on which
768
the bit is set; locks of this type are created
769
when records are removed from the index chain
771
#define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on
772
the index record and does NOT block inserts
773
to the gap before the index record; this is
774
used in the case when we retrieve a record
775
with a unique key, and is also used in
776
locking plain SELECTs (not part of UPDATE
777
or DELETE) when the user has set the READ
778
COMMITTED isolation level */
779
#define LOCK_INSERT_INTENTION 2048 /* this bit is set when we place a waiting
780
gap type record lock request in order to let
781
an insert of an index record to wait until
782
there are no conflicting locks by other
783
transactions on the gap; note that this flag
784
remains set when the waiting lock is granted,
785
or if the lock is inherited to a neighboring
788
/* When lock bits are reset, the following flags are available: */
789
#define LOCK_RELEASE_WAIT 1
790
#define LOCK_NOT_RELEASE_WAIT 2
792
/* Lock operation struct */
793
typedef struct lock_op_struct lock_op_t;
794
struct lock_op_struct{
795
dict_table_t* table; /* table to be locked */
796
enum lock_mode mode; /* lock mode */
799
#define LOCK_OP_START 1
800
#define LOCK_OP_COMPLETE 2
802
/* The lock system struct */
803
struct lock_sys_struct{
804
hash_table_t* rec_hash; /* hash table of the record locks */
807
/* The lock system */
808
extern lock_sys_t* lock_sys;
812
#include "lock0lock.ic"