1 /***************************************************************************** 2 3 Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License along with 22 this program; if not, write to the Free Software Foundation, Inc., 23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 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 "univ.i" 38 #include "buf0types.h" 39 #include "trx0types.h" 40 #include "mtr0types.h" 41 #include "rem0types.h" 42 #include "dict0types.h" 43 #include "que0types.h" 44 #include "lock0types.h" 45 #include "read0types.h" 46 #include "hash0hash.h" 47 #include "srv0srv.h" 48 #include "ut0vec.h" 49 50 #ifdef UNIV_DEBUG 51 extern ibool lock_print_waits; 52 #endif /* UNIV_DEBUG */ 53 54 /*********************************************************************//** 55 Gets the size of a lock struct. 56 @return size in bytes */ 57 UNIV_INTERN 58 ulint 59 lock_get_size(void); 60 /*===============*/ 61 /*********************************************************************//** 62 Creates the lock system at database start. */ 63 UNIV_INTERN 64 void 65 lock_sys_create( 66 /*============*/ 67 ulint n_cells); /*!< in: number of slots in lock hash table */ 68 /*********************************************************************//** 69 Closes the lock system at database shutdown. */ 70 UNIV_INTERN 71 void 72 lock_sys_close(void); 73 /*================*/ 74 /*********************************************************************//** 75 Gets the heap_no of the smallest user record on a page. 76 @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */ 77 UNIV_INLINE 78 ulint 79 lock_get_min_heap_no( 80 /*=================*/ 81 const buf_block_t* block); /*!< in: buffer block */ 82 /*************************************************************//** 83 Updates the lock table when we have reorganized a page. NOTE: we copy 84 also the locks set on the infimum of the page; the infimum may carry 85 locks if an update of a record is occurring on the page, and its locks 86 were temporarily stored on the infimum. */ 87 UNIV_INTERN 88 void 89 lock_move_reorganize_page( 90 /*======================*/ 91 const buf_block_t* block, /*!< in: old index page, now 92 reorganized */ 93 const buf_block_t* oblock);/*!< in: copy of the old, not 94 reorganized page */ 95 /*************************************************************//** 96 Moves the explicit locks on user records to another page if a record 97 list end is moved to another page. */ 98 UNIV_INTERN 99 void 100 lock_move_rec_list_end( 101 /*===================*/ 102 const buf_block_t* new_block, /*!< in: index page to move to */ 103 const buf_block_t* block, /*!< in: index page */ 104 const rec_t* rec); /*!< in: record on page: this 105 is the first record moved */ 106 /*************************************************************//** 107 Moves the explicit locks on user records to another page if a record 108 list start is moved to another page. */ 109 UNIV_INTERN 110 void 111 lock_move_rec_list_start( 112 /*=====================*/ 113 const buf_block_t* new_block, /*!< in: index page to move to */ 114 const buf_block_t* block, /*!< in: index page */ 115 const rec_t* rec, /*!< in: record on page: 116 this is the first 117 record NOT copied */ 118 const rec_t* old_end); /*!< in: old 119 previous-to-last 120 record on new_page 121 before the records 122 were copied */ 123 /*************************************************************//** 124 Updates the lock table when a page is split to the right. */ 125 UNIV_INTERN 126 void 127 lock_update_split_right( 128 /*====================*/ 129 const buf_block_t* right_block, /*!< in: right page */ 130 const buf_block_t* left_block); /*!< in: left page */ 131 /*************************************************************//** 132 Updates the lock table when a page is merged to the right. */ 133 UNIV_INTERN 134 void 135 lock_update_merge_right( 136 /*====================*/ 137 const buf_block_t* right_block, /*!< in: right page to 138 which merged */ 139 const rec_t* orig_succ, /*!< in: original 140 successor of infimum 141 on the right page 142 before merge */ 143 const buf_block_t* left_block); /*!< in: merged index 144 page which will be 145 discarded */ 146 /*************************************************************//** 147 Updates the lock table when the root page is copied to another in 148 btr_root_raise_and_insert. Note that we leave lock structs on the 149 root page, even though they do not make sense on other than leaf 150 pages: the reason is that in a pessimistic update the infimum record 151 of the root page will act as a dummy carrier of the locks of the record 152 to be updated. */ 153 UNIV_INTERN 154 void 155 lock_update_root_raise( 156 /*===================*/ 157 const buf_block_t* block, /*!< in: index page to which copied */ 158 const buf_block_t* root); /*!< in: root page */ 159 /*************************************************************//** 160 Updates the lock table when a page is copied to another and the original page 161 is removed from the chain of leaf pages, except if page is the root! */ 162 UNIV_INTERN 163 void 164 lock_update_copy_and_discard( 165 /*=========================*/ 166 const buf_block_t* new_block, /*!< in: index page to 167 which copied */ 168 const buf_block_t* block); /*!< in: index page; 169 NOT the root! */ 170 /*************************************************************//** 171 Updates the lock table when a page is split to the left. */ 172 UNIV_INTERN 173 void 174 lock_update_split_left( 175 /*===================*/ 176 const buf_block_t* right_block, /*!< in: right page */ 177 const buf_block_t* left_block); /*!< in: left page */ 178 /*************************************************************//** 179 Updates the lock table when a page is merged to the left. */ 180 UNIV_INTERN 181 void 182 lock_update_merge_left( 183 /*===================*/ 184 const buf_block_t* left_block, /*!< in: left page to 185 which merged */ 186 const rec_t* orig_pred, /*!< in: original predecessor 187 of supremum on the left page 188 before merge */ 189 const buf_block_t* right_block); /*!< in: merged index page 190 which will be discarded */ 191 /*************************************************************//** 192 Resets the original locks on heir and replaces them with gap type locks 193 inherited from rec. */ 194 UNIV_INTERN 195 void 196 lock_rec_reset_and_inherit_gap_locks( 197 /*=================================*/ 198 const buf_block_t* heir_block, /*!< in: block containing the 199 record which inherits */ 200 const buf_block_t* block, /*!< in: block containing the 201 record from which inherited; 202 does NOT reset the locks on 203 this record */ 204 ulint heir_heap_no, /*!< in: heap_no of the 205 inheriting record */ 206 ulint heap_no); /*!< in: heap_no of the 207 donating record */ 208 /*************************************************************//** 209 Updates the lock table when a page is discarded. */ 210 UNIV_INTERN 211 void 212 lock_update_discard( 213 /*================*/ 214 const buf_block_t* heir_block, /*!< in: index page 215 which will inherit the locks */ 216 ulint heir_heap_no, /*!< in: heap_no of the record 217 which will inherit the locks */ 218 const buf_block_t* block); /*!< in: index page 219 which will be discarded */ 220 /*************************************************************//** 221 Updates the lock table when a new user record is inserted. */ 222 UNIV_INTERN 223 void 224 lock_update_insert( 225 /*===============*/ 226 const buf_block_t* block, /*!< in: buffer block containing rec */ 227 const rec_t* rec); /*!< in: the inserted record */ 228 /*************************************************************//** 229 Updates the lock table when a record is removed. */ 230 UNIV_INTERN 231 void 232 lock_update_delete( 233 /*===============*/ 234 const buf_block_t* block, /*!< in: buffer block containing rec */ 235 const rec_t* rec); /*!< in: the record to be removed */ 236 /*********************************************************************//** 237 Stores on the page infimum record the explicit locks of another record. 238 This function is used to store the lock state of a record when it is 239 updated and the size of the record changes in the update. The record 240 is in such an update moved, perhaps to another page. The infimum record 241 acts as a dummy carrier record, taking care of lock releases while the 242 actual record is being moved. */ 243 UNIV_INTERN 244 void 245 lock_rec_store_on_page_infimum( 246 /*===========================*/ 247 const buf_block_t* block, /*!< in: buffer block containing rec */ 248 const rec_t* rec); /*!< in: record whose lock state 249 is stored on the infimum 250 record of the same page; lock 251 bits are reset on the 252 record */ 253 /*********************************************************************//** 254 Restores the state of explicit lock requests on a single record, where the 255 state was stored on the infimum of the page. */ 256 UNIV_INTERN 257 void 258 lock_rec_restore_from_page_infimum( 259 /*===============================*/ 260 const buf_block_t* block, /*!< in: buffer block containing rec */ 261 const rec_t* rec, /*!< in: record whose lock state 262 is restored */ 263 const buf_block_t* donator);/*!< in: page (rec is not 264 necessarily on this page) 265 whose infimum stored the lock 266 state; lock bits are reset on 267 the infimum */ 268 /*********************************************************************//** 269 Determines if there are explicit record locks on a page. 270 @return an explicit record lock on the page, or NULL if there are none */ 271 UNIV_INTERN 272 lock_t* 273 lock_rec_expl_exist_on_page( 274 /*========================*/ 275 ulint space, /*!< in: space id */ 276 ulint page_no)/*!< in: page number */ 277 MY_ATTRIBUTE((warn_unused_result)); 278 /*********************************************************************//** 279 Checks if locks of other transactions prevent an immediate insert of 280 a record. If they do, first tests if the query thread should anyway 281 be suspended for some reason; if not, then puts the transaction and 282 the query thread to the lock wait state and inserts a waiting request 283 for a gap x-lock to the lock queue. 284 @return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 285 UNIV_INTERN 286 dberr_t 287 lock_rec_insert_check_and_lock( 288 /*===========================*/ 289 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is 290 set, does nothing */ 291 const rec_t* rec, /*!< in: record after which to insert */ 292 buf_block_t* block, /*!< in/out: buffer block of rec */ 293 dict_index_t* index, /*!< in: index */ 294 que_thr_t* thr, /*!< in: query thread */ 295 mtr_t* mtr, /*!< in/out: mini-transaction */ 296 ibool* inherit)/*!< out: set to TRUE if the new 297 inserted record maybe should inherit 298 LOCK_GAP type locks from the successor 299 record */ 300 MY_ATTRIBUTE((nonnull, warn_unused_result)); 301 /*********************************************************************//** 302 Checks if locks of other transactions prevent an immediate modify (update, 303 delete mark, or delete unmark) of a clustered index record. If they do, 304 first tests if the query thread should anyway be suspended for some 305 reason; if not, then puts the transaction and the query thread to the 306 lock wait state and inserts a waiting request for a record x-lock to the 307 lock queue. 308 @return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 309 UNIV_INTERN 310 dberr_t 311 lock_clust_rec_modify_check_and_lock( 312 /*=================================*/ 313 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG 314 bit is set, does nothing */ 315 const buf_block_t* block, /*!< in: buffer block of rec */ 316 const rec_t* rec, /*!< in: record which should be 317 modified */ 318 dict_index_t* index, /*!< in: clustered index */ 319 const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ 320 que_thr_t* thr) /*!< in: query thread */ 321 MY_ATTRIBUTE((warn_unused_result, nonnull)); 322 /*********************************************************************//** 323 Checks if locks of other transactions prevent an immediate modify 324 (delete mark or delete unmark) of a secondary index record. 325 @return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 326 UNIV_INTERN 327 dberr_t 328 lock_sec_rec_modify_check_and_lock( 329 /*===============================*/ 330 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG 331 bit is set, does nothing */ 332 buf_block_t* block, /*!< in/out: buffer block of rec */ 333 const rec_t* rec, /*!< in: record which should be 334 modified; NOTE: as this is a secondary 335 index, we always have to modify the 336 clustered index record first: see the 337 comment below */ 338 dict_index_t* index, /*!< in: secondary index */ 339 que_thr_t* thr, /*!< in: query thread 340 (can be NULL if BTR_NO_LOCKING_FLAG) */ 341 mtr_t* mtr) /*!< in/out: mini-transaction */ 342 MY_ATTRIBUTE((warn_unused_result, nonnull(2,3,4,6))); 343 /*********************************************************************//** 344 Like lock_clust_rec_read_check_and_lock(), but reads a 345 secondary index record. 346 @return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, 347 or DB_QUE_THR_SUSPENDED */ 348 UNIV_INTERN 349 dberr_t 350 lock_sec_rec_read_check_and_lock( 351 /*=============================*/ 352 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG 353 bit is set, does nothing */ 354 const buf_block_t* block, /*!< in: buffer block of rec */ 355 const rec_t* rec, /*!< in: user record or page 356 supremum record which should 357 be read or passed over by a 358 read cursor */ 359 dict_index_t* index, /*!< in: secondary index */ 360 const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ 361 enum lock_mode mode, /*!< in: mode of the lock which 362 the read cursor should set on 363 records: LOCK_S or LOCK_X; the 364 latter is possible in 365 SELECT FOR UPDATE */ 366 ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or 367 LOCK_REC_NOT_GAP */ 368 que_thr_t* thr); /*!< in: query thread */ 369 /*********************************************************************//** 370 Checks if locks of other transactions prevent an immediate read, or passing 371 over by a read cursor, of a clustered index record. If they do, first tests 372 if the query thread should anyway be suspended for some reason; if not, then 373 puts the transaction and the query thread to the lock wait state and inserts a 374 waiting request for a record lock to the lock queue. Sets the requested mode 375 lock on the record. 376 @return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, 377 or DB_QUE_THR_SUSPENDED */ 378 UNIV_INTERN 379 dberr_t 380 lock_clust_rec_read_check_and_lock( 381 /*===============================*/ 382 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG 383 bit is set, does nothing */ 384 const buf_block_t* block, /*!< in: buffer block of rec */ 385 const rec_t* rec, /*!< in: user record or page 386 supremum record which should 387 be read or passed over by a 388 read cursor */ 389 dict_index_t* index, /*!< in: clustered index */ 390 const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ 391 enum lock_mode mode, /*!< in: mode of the lock which 392 the read cursor should set on 393 records: LOCK_S or LOCK_X; the 394 latter is possible in 395 SELECT FOR UPDATE */ 396 ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or 397 LOCK_REC_NOT_GAP */ 398 que_thr_t* thr); /*!< in: query thread */ 399 /*********************************************************************//** 400 Checks if locks of other transactions prevent an immediate read, or passing 401 over by a read cursor, of a clustered index record. If they do, first tests 402 if the query thread should anyway be suspended for some reason; if not, then 403 puts the transaction and the query thread to the lock wait state and inserts a 404 waiting request for a record lock to the lock queue. Sets the requested mode 405 lock on the record. This is an alternative version of 406 lock_clust_rec_read_check_and_lock() that does not require the parameter 407 "offsets". 408 @return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 409 UNIV_INTERN 410 dberr_t 411 lock_clust_rec_read_check_and_lock_alt( 412 /*===================================*/ 413 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG 414 bit is set, does nothing */ 415 const buf_block_t* block, /*!< in: buffer block of rec */ 416 const rec_t* rec, /*!< in: user record or page 417 supremum record which should 418 be read or passed over by a 419 read cursor */ 420 dict_index_t* index, /*!< in: clustered index */ 421 enum lock_mode mode, /*!< in: mode of the lock which 422 the read cursor should set on 423 records: LOCK_S or LOCK_X; the 424 latter is possible in 425 SELECT FOR UPDATE */ 426 ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or 427 LOCK_REC_NOT_GAP */ 428 que_thr_t* thr) /*!< in: query thread */ 429 MY_ATTRIBUTE((nonnull, warn_unused_result)); 430 /*********************************************************************//** 431 Checks that a record is seen in a consistent read. 432 @return true if sees, or false if an earlier version of the record 433 should be retrieved */ 434 UNIV_INTERN 435 bool 436 lock_clust_rec_cons_read_sees( 437 /*==========================*/ 438 const rec_t* rec, /*!< in: user record which should be read or 439 passed over by a read cursor */ 440 dict_index_t* index, /*!< in: clustered index */ 441 const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ 442 read_view_t* view); /*!< in: consistent read view */ 443 /*********************************************************************//** 444 Checks that a non-clustered index record is seen in a consistent read. 445 446 NOTE that a non-clustered index page contains so little information on 447 its modifications that also in the case false, the present version of 448 rec may be the right, but we must check this from the clustered index 449 record. 450 451 @return true if certainly sees, or false if an earlier version of the 452 clustered index record might be needed */ 453 UNIV_INTERN 454 bool 455 lock_sec_rec_cons_read_sees( 456 /*========================*/ 457 const rec_t* rec, /*!< in: user record which 458 should be read or passed over 459 by a read cursor */ 460 const read_view_t* view) /*!< in: consistent read view */ 461 MY_ATTRIBUTE((nonnull, warn_unused_result)); 462 /*********************************************************************//** 463 Locks the specified database table in the mode given. If the lock cannot 464 be granted immediately, the query thread is put to wait. 465 @return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 466 UNIV_INTERN 467 dberr_t 468 lock_table( 469 /*=======*/ 470 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set, 471 does nothing */ 472 dict_table_t* table, /*!< in/out: database table 473 in dictionary cache */ 474 enum lock_mode mode, /*!< in: lock mode */ 475 que_thr_t* thr) /*!< in: query thread */ 476 MY_ATTRIBUTE((nonnull, warn_unused_result)); 477 /*********************************************************************//** 478 Creates a table IX lock object for a resurrected transaction. */ 479 UNIV_INTERN 480 void 481 lock_table_ix_resurrect( 482 /*====================*/ 483 dict_table_t* table, /*!< in/out: table */ 484 trx_t* trx); /*!< in/out: transaction */ 485 /*************************************************************//** 486 Removes a granted record lock of a transaction from the queue and grants 487 locks to other transactions waiting in the queue if they now are entitled 488 to a lock. */ 489 UNIV_INTERN 490 void 491 lock_rec_unlock( 492 /*============*/ 493 trx_t* trx, /*!< in/out: transaction that has 494 set a record lock */ 495 const buf_block_t* block, /*!< in: buffer block containing rec */ 496 const rec_t* rec, /*!< in: record */ 497 enum lock_mode lock_mode);/*!< in: LOCK_S or LOCK_X */ 498 /*********************************************************************//** 499 Releases a transaction's locks, and releases possible other transactions 500 waiting because of these locks. Change the state of the transaction to 501 TRX_STATE_COMMITTED_IN_MEMORY. */ 502 UNIV_INTERN 503 void 504 lock_trx_release_locks( 505 /*===================*/ 506 trx_t* trx); /*!< in/out: transaction */ 507 /*********************************************************************//** 508 Removes locks on a table to be dropped or truncated. 509 If remove_also_table_sx_locks is TRUE then table-level S and X locks are 510 also removed in addition to other table-level and record-level locks. 511 No lock, that is going to be removed, is allowed to be a wait lock. */ 512 UNIV_INTERN 513 void 514 lock_remove_all_on_table( 515 /*=====================*/ 516 dict_table_t* table, /*!< in: table to be dropped 517 or truncated */ 518 ibool remove_also_table_sx_locks);/*!< in: also removes 519 table S and X locks */ 520 521 /*********************************************************************//** 522 Calculates the fold value of a page file address: used in inserting or 523 searching for a lock in the hash table. 524 @return folded value */ 525 UNIV_INLINE 526 ulint 527 lock_rec_fold( 528 /*==========*/ 529 ulint space, /*!< in: space */ 530 ulint page_no)/*!< in: page number */ 531 MY_ATTRIBUTE((const)); 532 /*********************************************************************//** 533 Calculates the hash value of a page file address: used in inserting or 534 searching for a lock in the hash table. 535 @return hashed value */ 536 UNIV_INLINE 537 ulint 538 lock_rec_hash( 539 /*==========*/ 540 ulint space, /*!< in: space */ 541 ulint page_no);/*!< in: page number */ 542 543 /**********************************************************************//** 544 Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED, 545 if none found. 546 @return bit index == heap number of the record, or ULINT_UNDEFINED if 547 none found */ 548 UNIV_INTERN 549 ulint 550 lock_rec_find_set_bit( 551 /*==================*/ 552 const lock_t* lock); /*!< in: record lock with at least one 553 bit set */ 554 555 /*********************************************************************//** 556 Gets the source table of an ALTER TABLE transaction. The table must be 557 covered by an IX or IS table lock. 558 @return the source table of transaction, if it is covered by an IX or 559 IS table lock; dest if there is no source table, and NULL if the 560 transaction is locking more than two tables or an inconsistency is 561 found */ 562 UNIV_INTERN 563 dict_table_t* 564 lock_get_src_table( 565 /*===============*/ 566 trx_t* trx, /*!< in: transaction */ 567 dict_table_t* dest, /*!< in: destination of ALTER TABLE */ 568 enum lock_mode* mode); /*!< out: lock mode of the source table */ 569 /*********************************************************************//** 570 Determine if the given table is exclusively "owned" by the given 571 transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC 572 on the table. 573 @return TRUE if table is only locked by trx, with LOCK_IX, and 574 possibly LOCK_AUTO_INC */ 575 UNIV_INTERN 576 ibool 577 lock_is_table_exclusive( 578 /*====================*/ 579 const dict_table_t* table, /*!< in: table */ 580 const trx_t* trx) /*!< in: transaction */ 581 MY_ATTRIBUTE((nonnull)); 582 /*********************************************************************//** 583 Checks if a lock request lock1 has to wait for request lock2. 584 @return TRUE if lock1 has to wait for lock2 to be removed */ 585 UNIV_INTERN 586 ibool 587 lock_has_to_wait( 588 /*=============*/ 589 const lock_t* lock1, /*!< in: waiting lock */ 590 const lock_t* lock2); /*!< in: another lock; NOTE that it is 591 assumed that this has a lock bit set 592 on the same record as in lock1 if the 593 locks are record locks */ 594 /*********************************************************************//** 595 Reports that a transaction id is insensible, i.e., in the future. */ 596 UNIV_INTERN 597 void 598 lock_report_trx_id_insanity( 599 /*========================*/ 600 trx_id_t trx_id, /*!< in: trx id */ 601 const rec_t* rec, /*!< in: user record */ 602 dict_index_t* index, /*!< in: index */ 603 const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */ 604 trx_id_t max_trx_id) /*!< in: trx_sys_get_max_trx_id() */ 605 MY_ATTRIBUTE((nonnull)); 606 /*********************************************************************//** 607 Prints info of a table lock. */ 608 UNIV_INTERN 609 void 610 lock_table_print( 611 /*=============*/ 612 FILE* file, /*!< in: file where to print */ 613 const lock_t* lock); /*!< in: table type lock */ 614 /*********************************************************************//** 615 Prints info of a record lock. */ 616 UNIV_INTERN 617 void 618 lock_rec_print( 619 /*===========*/ 620 FILE* file, /*!< in: file where to print */ 621 const lock_t* lock); /*!< in: record type lock */ 622 /*********************************************************************//** 623 Prints info of locks for all transactions. 624 @return FALSE if not able to obtain lock mutex and exits without 625 printing info */ 626 UNIV_INTERN 627 ibool 628 lock_print_info_summary( 629 /*====================*/ 630 FILE* file, /*!< in: file where to print */ 631 ibool nowait) /*!< in: whether to wait for the lock mutex */ 632 MY_ATTRIBUTE((nonnull, warn_unused_result)); 633 /*********************************************************************//** 634 Prints info of locks for each transaction. This function assumes that the 635 caller holds the lock mutex and more importantly it will release the lock 636 mutex on behalf of the caller. (This should be fixed in the future). */ 637 UNIV_INTERN 638 void 639 lock_print_info_all_transactions( 640 /*=============================*/ 641 FILE* file); /*!< in: file where to print */ 642 /*********************************************************************//** 643 Return approximate number or record locks (bits set in the bitmap) for 644 this transaction. Since delete-marked records may be removed, the 645 record count will not be precise. 646 The caller must be holding lock_sys->mutex. */ 647 UNIV_INTERN 648 ulint 649 lock_number_of_rows_locked( 650 /*=======================*/ 651 const trx_lock_t* trx_lock) /*!< in: transaction locks */ 652 MY_ATTRIBUTE((nonnull, warn_unused_result)); 653 654 /*******************************************************************//** 655 Gets the type of a lock. Non-inline version for using outside of the 656 lock module. 657 @return LOCK_TABLE or LOCK_REC */ 658 UNIV_INTERN 659 ulint 660 lock_get_type( 661 /*==========*/ 662 const lock_t* lock); /*!< in: lock */ 663 664 /*******************************************************************//** 665 Gets the id of the transaction owning a lock. 666 @return transaction id */ 667 UNIV_INTERN 668 trx_id_t 669 lock_get_trx_id( 670 /*============*/ 671 const lock_t* lock); /*!< in: lock */ 672 673 /*******************************************************************//** 674 Gets the mode of a lock in a human readable string. 675 The string should not be free()'d or modified. 676 @return lock mode */ 677 UNIV_INTERN 678 const char* 679 lock_get_mode_str( 680 /*==============*/ 681 const lock_t* lock); /*!< in: lock */ 682 683 /*******************************************************************//** 684 Gets the type of a lock in a human readable string. 685 The string should not be free()'d or modified. 686 @return lock type */ 687 UNIV_INTERN 688 const char* 689 lock_get_type_str( 690 /*==============*/ 691 const lock_t* lock); /*!< in: lock */ 692 693 /*******************************************************************//** 694 Gets the id of the table on which the lock is. 695 @return id of the table */ 696 UNIV_INTERN 697 table_id_t 698 lock_get_table_id( 699 /*==============*/ 700 const lock_t* lock); /*!< in: lock */ 701 702 /*******************************************************************//** 703 Gets the name of the table on which the lock is. 704 The string should not be free()'d or modified. 705 @return name of the table */ 706 UNIV_INTERN 707 const char* 708 lock_get_table_name( 709 /*================*/ 710 const lock_t* lock); /*!< in: lock */ 711 712 /*******************************************************************//** 713 For a record lock, gets the index on which the lock is. 714 @return index */ 715 UNIV_INTERN 716 const dict_index_t* 717 lock_rec_get_index( 718 /*===============*/ 719 const lock_t* lock); /*!< in: lock */ 720 721 /*******************************************************************//** 722 For a record lock, gets the name of the index on which the lock is. 723 The string should not be free()'d or modified. 724 @return name of the index */ 725 UNIV_INTERN 726 const char* 727 lock_rec_get_index_name( 728 /*====================*/ 729 const lock_t* lock); /*!< in: lock */ 730 731 /*******************************************************************//** 732 For a record lock, gets the tablespace number on which the lock is. 733 @return tablespace number */ 734 UNIV_INTERN 735 ulint 736 lock_rec_get_space_id( 737 /*==================*/ 738 const lock_t* lock); /*!< in: lock */ 739 740 /*******************************************************************//** 741 For a record lock, gets the page number on which the lock is. 742 @return page number */ 743 UNIV_INTERN 744 ulint 745 lock_rec_get_page_no( 746 /*=================*/ 747 const lock_t* lock); /*!< in: lock */ 748 /*******************************************************************//** 749 Check if there are any locks (table or rec) against table. 750 @return TRUE if locks exist */ 751 UNIV_INTERN 752 ibool 753 lock_table_has_locks( 754 /*=================*/ 755 const dict_table_t* table); /*!< in: check if there are any locks 756 held on records in this table or on the 757 table itself */ 758 759 /*********************************************************************//** 760 A thread which wakes up threads whose lock wait may have lasted too long. 761 @return a dummy parameter */ 762 extern "C" UNIV_INTERN 763 os_thread_ret_t 764 DECLARE_THREAD(lock_wait_timeout_thread)( 765 /*=====================================*/ 766 void* arg); /*!< in: a dummy parameter required by 767 os_thread_create */ 768 769 /********************************************************************//** 770 Releases a user OS thread waiting for a lock to be released, if the 771 thread is already suspended. */ 772 UNIV_INTERN 773 void 774 lock_wait_release_thread_if_suspended( 775 /*==================================*/ 776 que_thr_t* thr); /*!< in: query thread associated with the 777 user OS thread */ 778 779 /***************************************************************//** 780 Puts a user OS thread to wait for a lock to be released. If an error 781 occurs during the wait trx->error_state associated with thr is 782 != DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK 783 are possible errors. DB_DEADLOCK is returned if selective deadlock 784 resolution chose this transaction as a victim. */ 785 UNIV_INTERN 786 void 787 lock_wait_suspend_thread( 788 /*=====================*/ 789 que_thr_t* thr); /*!< in: query thread associated with the 790 user OS thread */ 791 /*********************************************************************//** 792 Unlocks AUTO_INC type locks that were possibly reserved by a trx. This 793 function should be called at the the end of an SQL statement, by the 794 connection thread that owns the transaction (trx->mysql_thd). */ 795 UNIV_INTERN 796 void 797 lock_unlock_table_autoinc( 798 /*======================*/ 799 trx_t* trx); /*!< in/out: transaction */ 800 /*********************************************************************//** 801 Check whether the transaction has already been rolled back because it 802 was selected as a deadlock victim, or if it has to wait then cancel 803 the wait lock. 804 @return DB_DEADLOCK, DB_LOCK_WAIT or DB_SUCCESS */ 805 UNIV_INTERN 806 dberr_t 807 lock_trx_handle_wait( 808 /*=================*/ 809 trx_t* trx) /*!< in/out: trx lock state */ 810 MY_ATTRIBUTE((nonnull)); 811 /*********************************************************************//** 812 Get the number of locks on a table. 813 @return number of locks */ 814 UNIV_INTERN 815 ulint 816 lock_table_get_n_locks( 817 /*===================*/ 818 const dict_table_t* table) /*!< in: table */ 819 MY_ATTRIBUTE((nonnull)); 820 #ifdef UNIV_DEBUG 821 /*********************************************************************//** 822 Checks that a transaction id is sensible, i.e., not in the future. 823 @return true if ok */ 824 UNIV_INTERN 825 bool 826 lock_check_trx_id_sanity( 827 /*=====================*/ 828 trx_id_t trx_id, /*!< in: trx id */ 829 const rec_t* rec, /*!< in: user record */ 830 dict_index_t* index, /*!< in: index */ 831 const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */ 832 MY_ATTRIBUTE((nonnull, warn_unused_result)); 833 /*******************************************************************//** 834 Check if the transaction holds any locks on the sys tables 835 or its records. 836 @return the strongest lock found on any sys table or 0 for none */ 837 UNIV_INTERN 838 const lock_t* 839 lock_trx_has_sys_table_locks( 840 /*=========================*/ 841 const trx_t* trx) /*!< in: transaction to check */ 842 MY_ATTRIBUTE((warn_unused_result)); 843 844 /*******************************************************************//** 845 Check if the transaction holds an exclusive lock on a record. 846 @return whether the locks are held */ 847 UNIV_INTERN 848 bool 849 lock_trx_has_rec_x_lock( 850 /*====================*/ 851 const trx_t* trx, /*!< in: transaction to check */ 852 const dict_table_t* table, /*!< in: table to check */ 853 const buf_block_t* block, /*!< in: buffer block of the record */ 854 ulint heap_no)/*!< in: record heap number */ 855 MY_ATTRIBUTE((nonnull, warn_unused_result)); 856 #endif /* UNIV_DEBUG */ 857 858 /** Lock modes and types */ 859 /* @{ */ 860 #define LOCK_MODE_MASK 0xFUL /*!< mask used to extract mode from the 861 type_mode field in a lock */ 862 /** Lock types */ 863 /* @{ */ 864 #define LOCK_TABLE 16 /*!< table lock */ 865 #define LOCK_REC 32 /*!< record lock */ 866 #define LOCK_TYPE_MASK 0xF0UL /*!< mask used to extract lock type from the 867 type_mode field in a lock */ 868 #if LOCK_MODE_MASK & LOCK_TYPE_MASK 869 # error "LOCK_MODE_MASK & LOCK_TYPE_MASK" 870 #endif 871 872 #define LOCK_WAIT 256 /*!< Waiting lock flag; when set, it 873 means that the lock has not yet been 874 granted, it is just waiting for its 875 turn in the wait queue */ 876 /* Precise modes */ 877 #define LOCK_ORDINARY 0 /*!< this flag denotes an ordinary 878 next-key lock in contrast to LOCK_GAP 879 or LOCK_REC_NOT_GAP */ 880 #define LOCK_GAP 512 /*!< when this bit is set, it means that the 881 lock holds only on the gap before the record; 882 for instance, an x-lock on the gap does not 883 give permission to modify the record on which 884 the bit is set; locks of this type are created 885 when records are removed from the index chain 886 of records */ 887 #define LOCK_REC_NOT_GAP 1024 /*!< this bit means that the lock is only on 888 the index record and does NOT block inserts 889 to the gap before the index record; this is 890 used in the case when we retrieve a record 891 with a unique key, and is also used in 892 locking plain SELECTs (not part of UPDATE 893 or DELETE) when the user has set the READ 894 COMMITTED isolation level */ 895 #define LOCK_INSERT_INTENTION 2048 /*!< this bit is set when we place a waiting 896 gap type record lock request in order to let 897 an insert of an index record to wait until 898 there are no conflicting locks by other 899 transactions on the gap; note that this flag 900 remains set when the waiting lock is granted, 901 or if the lock is inherited to a neighboring 902 record */ 903 904 #if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK 905 # error 906 #endif 907 #if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK 908 # error 909 #endif 910 /* @} */ 911 912 /** Lock operation struct */ 913 struct lock_op_t{ 914 dict_table_t* table; /*!< table to be locked */ 915 enum lock_mode mode; /*!< lock mode */ 916 }; 917 918 /** The lock system struct */ 919 struct lock_sys_t{ 920 ib_mutex_t mutex; /*!< Mutex protecting the 921 locks */ 922 hash_table_t* rec_hash; /*!< hash table of the record 923 locks */ 924 ib_mutex_t wait_mutex; /*!< Mutex protecting the 925 next two fields */ 926 srv_slot_t* waiting_threads; /*!< Array of user threads 927 suspended while waiting for 928 locks within InnoDB, protected 929 by the lock_sys->wait_mutex */ 930 srv_slot_t* last_slot; /*!< highest slot ever used 931 in the waiting_threads array, 932 protected by 933 lock_sys->wait_mutex */ 934 ibool rollback_complete; 935 /*!< TRUE if rollback of all 936 recovered transactions is 937 complete. Protected by 938 lock_sys->mutex */ 939 940 ulint n_lock_max_wait_time; /*!< Max wait time */ 941 942 os_event_t timeout_event; /*!< Set to the event that is 943 created in the lock wait monitor 944 thread. A value of 0 means the 945 thread is not active */ 946 947 bool timeout_thread_active; /*!< True if the timeout thread 948 is running */ 949 }; 950 951 /** The lock system */ 952 extern lock_sys_t* lock_sys; 953 954 /** Test if lock_sys->mutex can be acquired without waiting. */ 955 #define lock_mutex_enter_nowait() mutex_enter_nowait(&lock_sys->mutex) 956 957 /** Test if lock_sys->mutex is owned. */ 958 #define lock_mutex_own() mutex_own(&lock_sys->mutex) 959 960 /** Acquire the lock_sys->mutex. */ 961 #define lock_mutex_enter() do { \ 962 mutex_enter(&lock_sys->mutex); \ 963 } while (0) 964 965 /** Release the lock_sys->mutex. */ 966 #define lock_mutex_exit() do { \ 967 mutex_exit(&lock_sys->mutex); \ 968 } while (0) 969 970 /** Test if lock_sys->wait_mutex is owned. */ 971 #define lock_wait_mutex_own() mutex_own(&lock_sys->wait_mutex) 972 973 /** Acquire the lock_sys->wait_mutex. */ 974 #define lock_wait_mutex_enter() do { \ 975 mutex_enter(&lock_sys->wait_mutex); \ 976 } while (0) 977 978 /** Release the lock_sys->wait_mutex. */ 979 #define lock_wait_mutex_exit() do { \ 980 mutex_exit(&lock_sys->wait_mutex); \ 981 } while (0) 982 983 #ifdef WITH_WSREP 984 /*********************************************************************//** 985 Cancels a waiting lock request and releases possible other transactions 986 waiting behind it. */ 987 UNIV_INTERN 988 void 989 lock_cancel_waiting_and_release( 990 /*============================*/ 991 lock_t* lock); /*!< in/out: waiting lock request */ 992 #endif /* WITH_WSREP */ 993 #ifndef UNIV_NONINL 994 #include "lock0lock.ic" 995 #endif 996 997 #endif 998