26 #define LOCK_MODULE_IMPLEMENTATION
32 #include "lock0lock.ic"
33 #include "lock0priv.ic"
44 #define LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK 1000000
48 #define LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK 200
53 #define LOCK_RELEASE_KERNEL_INTERVAL 1000
59 #define LOCK_PAGE_BITMAP_MARGIN 64
310 #define LK(a,b) (1 << ((a) * LOCK_NUM + (b)))
311 #define LKS(a,b) LK(a,b) | LK(b,a)
317 #define LOCK_MODE_COMPATIBILITY 0 \
318 | LK(LOCK_IS, LOCK_IS) | LK(LOCK_IX, LOCK_IX) | LK(LOCK_S, LOCK_S) \
319 | LKS(LOCK_IX, LOCK_IS) | LKS(LOCK_IS, LOCK_AUTO_INC) \
320 | LKS(LOCK_S, LOCK_IS) \
321 | LKS(LOCK_AUTO_INC, LOCK_IS) | LKS(LOCK_AUTO_INC, LOCK_IX)
336 #define LOCK_MODE_STRONGER_OR_EQ 0 \
337 | LK(LOCK_IS, LOCK_IS) \
338 | LK(LOCK_IX, LOCK_IS) | LK(LOCK_IX, LOCK_IX) \
339 | LK(LOCK_S, LOCK_IS) | LK(LOCK_S, LOCK_S) \
340 | LK(LOCK_AUTO_INC, LOCK_AUTO_INC) \
341 | LK(LOCK_X, LOCK_IS) | LK(LOCK_X, LOCK_IX) | LK(LOCK_X, LOCK_S) \
342 | LK(LOCK_X, LOCK_AUTO_INC) | LK(LOCK_X, LOCK_X)
345 UNIV_INTERN ibool lock_print_waits = FALSE;
360 lock_rec_validate_page(
371 UNIV_INTERN ibool lock_deadlock_found = FALSE;
372 UNIV_INTERN FILE* lock_latest_err_file;
375 #define LOCK_VICTIM_IS_START 1
376 #define LOCK_VICTIM_IS_OTHER 2
377 #define LOCK_EXCEED_MAX_DEPTH 3
386 lock_deadlock_occurs(
400 lock_deadlock_recursive(
417 lock_rec_get_nth_bit(
436 return(1 & ((
const byte*) &lock[1])[byte_index] >> bit_index);
441 #define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex)
442 #define lock_mutex_exit_kernel() mutex_exit(&kernel_mutex)
454 const ulint* offsets,
455 ibool has_kernel_mutex)
462 if (!has_kernel_mutex) {
463 mutex_enter(&kernel_mutex);
471 fputs(
" InnoDB: Error: transaction id associated"
475 fputs(
"InnoDB: in ", stderr);
476 dict_index_name_print(stderr, NULL, index);
478 "InnoDB: is " TRX_ID_FMT " which is higher than the"
480 "InnoDB: The table is corrupt. You have to do"
481 " dump + drop + reimport.\n",
487 if (!has_kernel_mutex) {
488 mutex_exit(&kernel_mutex);
505 const ulint* offsets,
558 return(max_trx_id < view->up_limit_id);
576 ut_a(lock_latest_err_file);
586 if (lock_latest_err_file != NULL) {
587 fclose(lock_latest_err_file);
588 lock_latest_err_file = NULL;
604 return((ulint)
sizeof(
lock_t));
653 enum lock_mode* mode)
665 enum lock_mode lock_mode;
671 if (dest == tab_lock->
table) {
676 src = tab_lock->
table;
683 }
else if (src != tab_lock->
table) {
691 lock_mode = lock_get_mode(lock);
692 if (lock_mode == LOCK_IX || lock_mode == LOCK_IS) {
693 if (*mode != LOCK_NONE && *mode != lock_mode) {
728 lock_mutex_enter_kernel();
733 if (lock->
trx != trx) {
744 switch (lock_get_mode(lock)) {
761 lock_mutex_exit_kernel();
770 lock_set_lock_and_trx_wait(
787 lock_reset_lock_and_trx_wait(
791 ut_ad((lock->
trx)->wait_lock == lock);
792 ut_ad(lock_get_wait(lock));
796 (lock->
trx)->wait_lock = NULL;
825 lock_rec_get_rec_not_gap(
845 lock_rec_get_insert_intention(
865 lock_mode_stronger_or_eq(
867 enum lock_mode mode1,
868 enum lock_mode mode2)
870 ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
871 || mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
872 ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX
873 || mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC);
875 return((LOCK_MODE_STRONGER_OR_EQ) & LK(mode1, mode2));
883 lock_mode_compatible(
885 enum lock_mode mode1,
886 enum lock_mode mode2)
888 ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
889 || mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
890 ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX
891 || mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC);
893 return((LOCK_MODE_COMPATIBILITY) & LK(mode1, mode2));
901 lock_rec_has_to_wait(
912 ibool lock_is_on_supremum)
920 if (trx != lock2->
trx
921 && !lock_mode_compatible(static_cast<lock_mode>(
LOCK_MODE_MASK & type_mode),
922 lock_get_mode(lock2))) {
927 if ((lock_is_on_supremum || (type_mode &
LOCK_GAP))
938 if (!(type_mode & LOCK_INSERT_INTENTION)
939 && lock_rec_get_gap(lock2)) {
947 if ((type_mode & LOCK_GAP)
948 && lock_rec_get_rec_not_gap(lock2)) {
956 if (lock_rec_get_insert_intention(lock2)) {
991 ut_ad(lock1 && lock2);
993 if (lock1->
trx != lock2->
trx
994 && !lock_mode_compatible(lock_get_mode(lock1),
995 lock_get_mode(lock2))) {
1002 return(lock_rec_has_to_wait(lock1->
trx,
1004 lock_rec_get_nth_bit(
1021 lock_rec_get_n_bits(
1032 lock_rec_set_nth_bit(
1042 ut_ad(i < lock->un_member.rec_lock.n_bits);
1047 ((byte*) &lock[1])[byte_index] |= 1 << bit_index;
1063 for (i = 0; i < lock_rec_get_n_bits(lock); i++) {
1065 if (lock_rec_get_nth_bit(lock, i)) {
1071 return(ULINT_UNDEFINED);
1078 lock_rec_reset_nth_bit(
1089 ut_ad(i < lock->un_member.rec_lock.n_bits);
1094 ((byte*) &lock[1])[byte_index] &= ~(1 << bit_index);
1102 lock_rec_get_next_on_page(
1109 ut_ad(mutex_own(&kernel_mutex));
1139 lock_rec_get_first_on_page_addr(
1146 ut_ad(mutex_own(&kernel_mutex));
1175 mutex_enter(&kernel_mutex);
1177 if (lock_rec_get_first_on_page_addr(space, page_no)) {
1183 mutex_exit(&kernel_mutex);
1194 lock_rec_get_first_on_page(
1203 ut_ad(mutex_own(&kernel_mutex));
1232 ut_ad(mutex_own(&kernel_mutex));
1236 lock = lock_rec_get_next_on_page(lock);
1237 }
while (lock && !lock_rec_get_nth_bit(lock, heap_no));
1254 ut_ad(mutex_own(&kernel_mutex));
1256 for (lock = lock_rec_get_first_on_page(block); lock;
1257 lock = lock_rec_get_next_on_page(lock)) {
1258 if (lock_rec_get_nth_bit(lock, heap_no)) {
1272 lock_rec_bitmap_reset(
1283 n_bytes = lock_rec_get_n_bits(lock) / 8;
1285 ut_ad((lock_rec_get_n_bits(lock) % 8) == 0);
1287 memset(&lock[1], 0, n_bytes);
1304 size =
sizeof(
lock_t) + lock_rec_get_n_bits(lock) / 8;
1322 lock_t* found_lock = NULL;
1324 ut_ad(mutex_own(&kernel_mutex));
1330 lock = lock_rec_get_first_on_page_addr(space, page_no);
1335 if (lock == in_lock) {
1340 if (lock_rec_get_nth_bit(lock, heap_no)) {
1345 lock = lock_rec_get_next_on_page(lock);
1360 enum lock_mode mode)
1364 ut_ad(mutex_own(&kernel_mutex));
1370 while (lock != NULL) {
1372 if (lock->
trx == trx
1373 && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) {
1378 ut_ad(!lock_get_wait(lock));
1411 ut_ad(mutex_own(&kernel_mutex));
1413 || (precise_mode & LOCK_MODE_MASK) == LOCK_X);
1414 ut_ad(!(precise_mode & LOCK_INSERT_INTENTION));
1416 lock = lock_rec_get_first(block, heap_no);
1419 if (lock->
trx == trx
1420 && lock_mode_stronger_or_eq(lock_get_mode(lock),
1421 static_cast<lock_mode>(precise_mode & LOCK_MODE_MASK))
1422 && !lock_get_wait(lock)
1423 && (!lock_rec_get_rec_not_gap(lock)
1425 || heap_no == PAGE_HEAP_NO_SUPREMUM)
1426 && (!lock_rec_get_gap(lock)
1427 || (precise_mode & LOCK_GAP)
1428 || heap_no == PAGE_HEAP_NO_SUPREMUM)
1429 && (!lock_rec_get_insert_intention(lock))) {
1434 lock = lock_rec_get_next(heap_no, lock);
1446 lock_rec_other_has_expl_req(
1448 enum lock_mode mode,
1464 ut_ad(mutex_own(&kernel_mutex));
1465 ut_ad(mode == LOCK_X || mode == LOCK_S);
1466 ut_ad(gap == 0 || gap == LOCK_GAP);
1469 lock = lock_rec_get_first(block, heap_no);
1472 if (lock->
trx != trx
1474 || !(lock_rec_get_gap(lock)
1475 || heap_no == PAGE_HEAP_NO_SUPREMUM))
1476 && (wait || !lock_get_wait(lock))
1477 && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) {
1482 lock = lock_rec_get_next(heap_no, lock);
1495 lock_rec_other_has_conflicting(
1497 enum lock_mode mode,
1508 ut_ad(mutex_own(&kernel_mutex));
1510 lock = lock_rec_get_first(block, heap_no);
1512 if (UNIV_LIKELY_NULL(lock)) {
1513 if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
1516 if (lock_rec_has_to_wait(trx, mode, lock,
1521 lock = lock_rec_get_next(heap_no, lock);
1526 if (lock_rec_has_to_wait(trx, mode, lock,
1531 lock = lock_rec_get_next(heap_no, lock);
1546 lock_rec_find_similar_on_page(
1553 ut_ad(mutex_own(&kernel_mutex));
1555 while (lock != NULL) {
1556 if (lock->
trx == trx
1558 && lock_rec_get_n_bits(lock) > heap_no) {
1563 lock = lock_rec_get_next_on_page(lock);
1575 lock_sec_rec_some_has_impl_off_kernel(
1579 const ulint* offsets)
1583 ut_ad(mutex_own(&kernel_mutex));
1604 rec, index, offsets, TRUE)) {
1605 buf_page_print(page, 0);
1626 ulint n_records = 0;
1634 n_bits = lock_rec_get_n_bits(lock);
1636 for (n_bit = 0; n_bit < n_bits; n_bit++) {
1637 if (lock_rec_get_nth_bit(lock, n_bit)) {
1675 ut_ad(mutex_own(&kernel_mutex));
1679 page = block->
frame;
1687 if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
1688 ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
1695 n_bytes = 1 + n_bits / 8;
1704 lock->
index = index;
1713 lock_rec_bitmap_reset(lock);
1716 lock_rec_set_nth_bit(lock, heap_no);
1720 if (UNIV_UNLIKELY(type_mode &
LOCK_WAIT)) {
1722 lock_set_lock_and_trx_wait(lock, trx);
1737 lock_rec_enqueue_waiting(
1757 ut_ad(mutex_own(&kernel_mutex));
1767 return(DB_QUE_THR_SUSPENDED);
1778 fputs(
" InnoDB: Error: a record lock wait happens"
1779 " in a dictionary operation!\n"
1780 "InnoDB: ", stderr);
1781 dict_index_name_print(stderr, trx, index);
1783 "InnoDB: Submit a detailed bug report"
1784 " to http://bugs.mysql.com\n",
1789 lock = lock_rec_create(type_mode | LOCK_WAIT,
1790 block, heap_no, index, trx);
1795 if (UNIV_UNLIKELY(lock_deadlock_occurs(lock, trx))) {
1797 lock_reset_lock_and_trx_wait(lock);
1798 lock_rec_reset_nth_bit(lock, heap_no);
1800 return(DB_DEADLOCK);
1812 trx->was_chosen_as_deadlock_victim = FALSE;
1818 if (lock_print_waits) {
1819 fprintf(stderr,
"Lock wait for trx " TRX_ID_FMT " in index ",
1825 return(DB_LOCK_WAIT);
1838 lock_rec_add_to_queue(
1851 ut_ad(mutex_own(&kernel_mutex));
1853 switch (type_mode & LOCK_MODE_MASK) {
1861 if (!(type_mode & (LOCK_WAIT | LOCK_GAP))) {
1866 = lock_rec_other_has_expl_req(mode, 0, LOCK_WAIT,
1867 block, heap_no, trx);
1879 if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
1880 ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
1890 lock = lock_rec_get_first_on_page(block);
1892 while (lock != NULL) {
1893 if (lock_get_wait(lock)
1894 && (lock_rec_get_nth_bit(lock, heap_no))) {
1896 goto somebody_waits;
1899 lock = lock_rec_get_next_on_page(lock);
1902 if (UNIV_LIKELY(!(type_mode & LOCK_WAIT))) {
1908 lock = lock_rec_find_similar_on_page(
1910 lock_rec_get_first_on_page(block), trx);
1914 lock_rec_set_nth_bit(lock, heap_no);
1921 return(lock_rec_create(type_mode, block, heap_no, index, trx));
1925 enum lock_rec_req_status {
1931 LOCK_REC_SUCCESS_CREATED
1943 enum lock_rec_req_status
1962 ut_ad(mutex_own(&kernel_mutex));
1963 ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
1965 ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
1967 ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
1968 || (LOCK_MODE_MASK & mode) == LOCK_X);
1969 ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
1970 || mode - (LOCK_MODE_MASK & mode) == 0
1971 || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
1973 lock = lock_rec_get_first_on_page(block);
1979 lock_rec_create(mode, block, heap_no, index, trx);
1982 return(LOCK_REC_SUCCESS_CREATED);
1985 if (lock_rec_get_next_on_page(lock)) {
1987 return(LOCK_REC_FAIL);
1990 if (lock->
trx != trx
1992 || lock_rec_get_n_bits(lock) <= heap_no) {
1994 return(LOCK_REC_FAIL);
2001 if (!lock_rec_get_nth_bit(lock, heap_no)) {
2002 lock_rec_set_nth_bit(lock, heap_no);
2003 return(LOCK_REC_SUCCESS_CREATED);
2007 return(LOCK_REC_SUCCESS);
2036 ut_ad(mutex_own(&kernel_mutex));
2037 ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
2039 ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
2041 ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
2042 || (LOCK_MODE_MASK & mode) == LOCK_X);
2043 ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
2044 || mode - (LOCK_MODE_MASK & mode) == 0
2045 || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
2049 if (lock_rec_has_expl(mode, block, heap_no, trx)) {
2053 }
else if (lock_rec_other_has_conflicting(static_cast<lock_mode>(mode), block, heap_no, trx)) {
2059 return(lock_rec_enqueue_waiting(mode, block, heap_no,
2064 lock_rec_add_to_queue(
LOCK_REC | mode, block,
2065 heap_no, index, trx);
2097 ut_ad(mutex_own(&kernel_mutex));
2098 ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
2100 ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
2102 ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
2103 || (LOCK_MODE_MASK & mode) == LOCK_X);
2104 ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
2105 || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
2106 || mode - (LOCK_MODE_MASK & mode) == 0);
2110 switch (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) {
2111 case LOCK_REC_SUCCESS:
2113 case LOCK_REC_SUCCESS_CREATED:
2116 return(lock_rec_lock_slow(impl, mode, block,
2117 heap_no, index, thr));
2129 lock_rec_has_to_wait_in_queue(
2138 ut_ad(mutex_own(&kernel_mutex));
2139 ut_ad(lock_get_wait(wait_lock));
2146 lock = lock_rec_get_first_on_page_addr(space, page_no);
2148 while (lock != wait_lock) {
2150 if (lock_rec_get_nth_bit(lock, heap_no)
2156 lock = lock_rec_get_next_on_page(lock);
2171 ut_ad(mutex_own(&kernel_mutex));
2173 lock_reset_lock_and_trx_wait(lock);
2175 if (lock_get_mode(lock) == LOCK_AUTO_INC) {
2181 "InnoDB: Error: trx already had"
2182 " an AUTO-INC lock!\n");
2191 if (lock_print_waits) {
2192 fprintf(stderr,
"Lock wait for trx " TRX_ID_FMT " ends\n",
2217 ut_ad(mutex_own(&kernel_mutex));
2225 lock_reset_lock_and_trx_wait(lock);
2238 lock_rec_dequeue_from_page(
2250 ut_ad(mutex_own(&kernel_mutex));
2266 lock = lock_rec_get_first_on_page_addr(space, page_no);
2268 while (lock != NULL) {
2269 if (lock_get_wait(lock)
2270 && !lock_rec_has_to_wait_in_queue(lock)) {
2276 lock = lock_rec_get_next_on_page(lock);
2293 ut_ad(mutex_own(&kernel_mutex));
2313 lock_rec_free_all_from_discard_page(
2322 ut_ad(mutex_own(&kernel_mutex));
2327 lock = lock_rec_get_first_on_page_addr(space, page_no);
2329 while (lock != NULL) {
2331 ut_ad(!lock_get_wait(lock));
2333 next_lock = lock_rec_get_next_on_page(lock);
2335 lock_rec_discard(lock);
2348 lock_rec_reset_and_release_wait(
2356 ut_ad(mutex_own(&kernel_mutex));
2358 lock = lock_rec_get_first(block, heap_no);
2360 while (lock != NULL) {
2361 if (lock_get_wait(lock)) {
2362 lock_rec_cancel(lock);
2364 lock_rec_reset_nth_bit(lock, heap_no);
2367 lock = lock_rec_get_next(heap_no, lock);
2378 lock_rec_inherit_to_gap(
2393 ut_ad(mutex_own(&kernel_mutex));
2395 lock = lock_rec_get_first(block, heap_no);
2403 while (lock != NULL) {
2404 if (!lock_rec_get_insert_intention(lock)
2405 && !((srv_locks_unsafe_for_binlog
2406 || lock->
trx->isolation_level
2407 <= TRX_ISO_READ_COMMITTED)
2408 && lock_get_mode(lock) == LOCK_X)) {
2410 lock_rec_add_to_queue(
LOCK_REC | LOCK_GAP
2411 | lock_get_mode(lock),
2412 heir_block, heir_heap_no,
2416 lock = lock_rec_get_next(heap_no, lock);
2426 lock_rec_inherit_to_gap_if_gap_lock(
2438 ut_ad(mutex_own(&kernel_mutex));
2440 lock = lock_rec_get_first(block, heap_no);
2442 while (lock != NULL) {
2443 if (!lock_rec_get_insert_intention(lock)
2444 && (heap_no == PAGE_HEAP_NO_SUPREMUM
2445 || !lock_rec_get_rec_not_gap(lock))) {
2447 lock_rec_add_to_queue(
LOCK_REC | LOCK_GAP
2448 | lock_get_mode(lock),
2449 block, heir_heap_no,
2453 lock = lock_rec_get_next(heap_no, lock);
2468 ulint receiver_heap_no,
2472 ulint donator_heap_no)
2477 ut_ad(mutex_own(&kernel_mutex));
2479 lock = lock_rec_get_first(donator, donator_heap_no);
2481 ut_ad(lock_rec_get_first(receiver, receiver_heap_no) == NULL);
2483 while (lock != NULL) {
2484 const ulint type_mode = lock->
type_mode;
2486 lock_rec_reset_nth_bit(lock, donator_heap_no);
2488 if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
2489 lock_reset_lock_and_trx_wait(lock);
2495 lock_rec_add_to_queue(type_mode, receiver, receiver_heap_no,
2497 lock = lock_rec_get_next(donator_heap_no, lock);
2500 ut_ad(lock_rec_get_first(donator, donator_heap_no) == NULL);
2522 lock_mutex_enter_kernel();
2524 lock = lock_rec_get_first_on_page(block);
2527 lock_mutex_exit_kernel();
2542 lock_t* old_lock = lock_rec_copy(lock, heap);
2547 lock_rec_bitmap_reset(lock);
2549 if (lock_get_wait(lock)) {
2550 lock_reset_lock_and_trx_wait(lock);
2553 lock = lock_rec_get_next_on_page(lock);
2554 }
while (lock != NULL);
2576 ut_ad(comp || !memcmp(page_cur_get_rec(&cur1),
2577 page_cur_get_rec(&cur2),
2581 if (UNIV_LIKELY(comp)) {
2583 page_cur_get_rec(&cur2));
2585 page_cur_get_rec(&cur1));
2588 page_cur_get_rec(&cur2));
2590 page_cur_get_rec(&cur1));
2593 if (lock_rec_get_nth_bit(lock, old_heap_no)) {
2596 ut_d(lock_rec_reset_nth_bit(lock,
2602 lock_rec_add_to_queue(lock->
type_mode, block,
2615 (new_heap_no == PAGE_HEAP_NO_SUPREMUM)) {
2617 ut_ad(old_heap_no == PAGE_HEAP_NO_SUPREMUM);
2630 if (UNIV_UNLIKELY(i != ULINT_UNDEFINED)) {
2632 "lock_move_reorganize_page():"
2633 " %lu not moved in %p\n",
2634 (ulong) i, (
void*) lock);
2641 lock_mutex_exit_kernel();
2645 #ifdef UNIV_DEBUG_LOCK_VALIDATE
2666 lock_mutex_enter_kernel();
2674 for (lock = lock_rec_get_first_on_page(block); lock;
2675 lock = lock_rec_get_next_on_page(lock)) {
2678 const ulint type_mode = lock->
type_mode;
2697 page_cur_get_rec(&cur1));
2700 page_cur_get_rec(&cur1));
2701 ut_ad(!memcmp(page_cur_get_rec(&cur1),
2702 page_cur_get_rec(&cur2),
2704 page_cur_get_rec(&cur2))));
2707 if (lock_rec_get_nth_bit(lock, heap_no)) {
2708 lock_rec_reset_nth_bit(lock, heap_no);
2710 if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
2711 lock_reset_lock_and_trx_wait(lock);
2716 page_cur_get_rec(&cur2));
2719 page_cur_get_rec(&cur2));
2722 lock_rec_add_to_queue(type_mode,
2732 lock_mutex_exit_kernel();
2734 #ifdef UNIV_DEBUG_LOCK_VALIDATE
2754 const rec_t* old_end)
2766 lock_mutex_enter_kernel();
2768 for (lock = lock_rec_get_first_on_page(block); lock;
2769 lock = lock_rec_get_next_on_page(lock)) {
2772 const ulint type_mode = lock->
type_mode;
2783 while (page_cur_get_rec(&cur1) != rec) {
2788 page_cur_get_rec(&cur1));
2791 page_cur_get_rec(&cur1));
2792 ut_ad(!memcmp(page_cur_get_rec(&cur1),
2793 page_cur_get_rec(&cur2),
2799 if (lock_rec_get_nth_bit(lock, heap_no)) {
2800 lock_rec_reset_nth_bit(lock, heap_no);
2802 if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
2803 lock_reset_lock_and_trx_wait(lock);
2808 page_cur_get_rec(&cur2));
2811 page_cur_get_rec(&cur2));
2814 lock_rec_add_to_queue(type_mode,
2827 for (i = PAGE_HEAP_NO_USER_LOW;
2828 i < lock_rec_get_n_bits(lock); i++) {
2830 (lock_rec_get_nth_bit(lock, i))) {
2833 "lock_move_rec_list_start():"
2834 " %lu not moved in %p\n",
2835 (ulong) i, (
void*) lock);
2843 lock_mutex_exit_kernel();
2845 #ifdef UNIV_DEBUG_LOCK_VALIDATE
2862 lock_mutex_enter_kernel();
2867 lock_rec_move(right_block, left_block,
2868 PAGE_HEAP_NO_SUPREMUM, PAGE_HEAP_NO_SUPREMUM);
2873 lock_rec_inherit_to_gap(left_block, right_block,
2874 PAGE_HEAP_NO_SUPREMUM, heap_no);
2876 lock_mutex_exit_kernel();
2887 const rec_t* orig_succ,
2895 lock_mutex_enter_kernel();
2901 lock_rec_inherit_to_gap(right_block, left_block,
2903 PAGE_HEAP_NO_SUPREMUM);
2908 lock_rec_reset_and_release_wait(left_block,
2909 PAGE_HEAP_NO_SUPREMUM);
2911 lock_rec_free_all_from_discard_page(left_block);
2913 lock_mutex_exit_kernel();
2930 lock_mutex_enter_kernel();
2935 lock_rec_move(block, root,
2936 PAGE_HEAP_NO_SUPREMUM, PAGE_HEAP_NO_SUPREMUM);
2937 lock_mutex_exit_kernel();
2952 lock_mutex_enter_kernel();
2957 lock_rec_move(new_block, block,
2958 PAGE_HEAP_NO_SUPREMUM, PAGE_HEAP_NO_SUPREMUM);
2959 lock_rec_free_all_from_discard_page(block);
2961 lock_mutex_exit_kernel();
2975 lock_mutex_enter_kernel();
2980 lock_rec_inherit_to_gap(left_block, right_block,
2981 PAGE_HEAP_NO_SUPREMUM, heap_no);
2983 lock_mutex_exit_kernel();
2994 const rec_t* orig_pred,
3000 const rec_t* left_next_rec;
3004 lock_mutex_enter_kernel();
3013 lock_rec_inherit_to_gap(left_block, left_block,
3015 PAGE_HEAP_NO_SUPREMUM);
3020 lock_rec_reset_and_release_wait(left_block,
3021 PAGE_HEAP_NO_SUPREMUM);
3027 lock_rec_move(left_block, right_block,
3028 PAGE_HEAP_NO_SUPREMUM, PAGE_HEAP_NO_SUPREMUM);
3030 lock_rec_free_all_from_discard_page(right_block);
3032 lock_mutex_exit_kernel();
3053 mutex_enter(&kernel_mutex);
3055 lock_rec_reset_and_release_wait(heir_block, heir_heap_no);
3057 lock_rec_inherit_to_gap(heir_block, block, heir_heap_no, heap_no);
3059 mutex_exit(&kernel_mutex);
3079 lock_mutex_enter_kernel();
3081 if (!lock_rec_get_first_on_page(block)) {
3084 lock_mutex_exit_kernel();
3093 rec = page + PAGE_NEW_INFIMUM;
3098 lock_rec_inherit_to_gap(heir_block, block,
3099 heir_heap_no, heap_no);
3101 lock_rec_reset_and_release_wait(block, heap_no);
3104 }
while (heap_no != PAGE_HEAP_NO_SUPREMUM);
3106 rec = page + PAGE_OLD_INFIMUM;
3111 lock_rec_inherit_to_gap(heir_block, block,
3112 heir_heap_no, heap_no);
3114 lock_rec_reset_and_release_wait(block, heap_no);
3117 }
while (heap_no != PAGE_HEAP_NO_SUPREMUM);
3120 lock_rec_free_all_from_discard_page(block);
3122 lock_mutex_exit_kernel();
3134 ulint receiver_heap_no;
3135 ulint donator_heap_no;
3152 lock_mutex_enter_kernel();
3153 lock_rec_inherit_to_gap_if_gap_lock(block,
3154 receiver_heap_no, donator_heap_no);
3155 lock_mutex_exit_kernel();
3185 lock_mutex_enter_kernel();
3189 lock_rec_inherit_to_gap(block, block, next_heap_no, heap_no);
3193 lock_rec_reset_and_release_wait(block, heap_no);
3195 lock_mutex_exit_kernel();
3220 lock_mutex_enter_kernel();
3222 lock_rec_move(block, block, PAGE_HEAP_NO_INFIMUM, heap_no);
3224 lock_mutex_exit_kernel();
3245 lock_mutex_enter_kernel();
3247 lock_rec_move(block, donator, heap_no, PAGE_HEAP_NO_INFIMUM);
3249 lock_mutex_exit_kernel();
3261 lock_deadlock_occurs(
3272 ut_ad(mutex_own(&kernel_mutex));
3285 ret = lock_deadlock_recursive(trx, trx, lock, &cost, 0);
3288 case LOCK_VICTIM_IS_OTHER:
3293 case LOCK_EXCEED_MAX_DEPTH:
3297 rewind(lock_latest_err_file);
3300 fputs(
"TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
3301 " WAITS-FOR GRAPH, WE WILL ROLL BACK"
3302 " FOLLOWING TRANSACTION \n",
3303 lock_latest_err_file);
3305 fputs(
"\n*** TRANSACTION:\n", lock_latest_err_file);
3306 trx_print(lock_latest_err_file, trx, 3000);
3308 fputs(
"*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
3309 lock_latest_err_file);
3318 case LOCK_VICTIM_IS_START:
3319 fputs(
"*** WE ROLL BACK TRANSACTION (2)\n",
3320 lock_latest_err_file);
3328 lock_deadlock_found = TRUE;
3343 lock_deadlock_recursive(
3358 ulint heap_no = ULINT_UNDEFINED;
3363 ut_ad(mutex_own(&kernel_mutex));
3379 ut_a(heap_no != ULINT_UNDEFINED);
3384 lock = lock_rec_get_first_on_page_addr(space, page_no);
3388 && lock != wait_lock
3389 && !lock_rec_get_nth_bit(lock, heap_no)) {
3391 lock = lock_rec_get_next_on_page(lock);
3394 if (lock == wait_lock) {
3398 ut_ad(lock == NULL || lock_rec_get_nth_bit(lock, heap_no));
3408 if (heap_no == ULINT_UNDEFINED) {
3411 un_member.tab_lock.locks, lock);
3424 = depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK
3425 || *cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK;
3427 lock_trx = lock->
trx;
3429 if (lock_trx == start) {
3435 FILE* ef = lock_latest_err_file;
3440 fputs(
"\n*** (1) TRANSACTION:\n", ef);
3444 fputs(
"*** (1) WAITING FOR THIS LOCK"
3445 " TO BE GRANTED:\n", ef);
3453 fputs(
"*** (2) TRANSACTION:\n", ef);
3457 fputs(
"*** (2) HOLDS THE LOCK(S):\n", ef);
3465 fputs(
"*** (2) WAITING FOR THIS LOCK"
3466 " TO BE GRANTED:\n", ef);
3475 if (lock_print_waits) {
3476 fputs(
"Deadlock detected\n",
3487 return(LOCK_VICTIM_IS_START);
3490 lock_deadlock_found = TRUE;
3496 fputs(
"*** WE ROLL BACK TRANSACTION (1)\n",
3499 wait_lock->
trx->was_chosen_as_deadlock_victim
3511 return(LOCK_VICTIM_IS_OTHER);
3517 if (lock_print_waits) {
3518 fputs(
"Deadlock search exceeds"
3519 " max steps or depth.\n",
3526 return(LOCK_EXCEED_MAX_DEPTH);
3529 if (lock_trx->
que_state == TRX_QUE_LOCK_WAIT) {
3535 ret = lock_deadlock_recursive(
3546 if (heap_no != ULINT_UNDEFINED) {
3551 lock = lock_rec_get_next_on_page(lock);
3552 }
while (lock != NULL
3553 && lock != wait_lock
3554 && !lock_rec_get_nth_bit(lock, heap_no));
3556 if (lock == wait_lock) {
3580 ut_ad(table && trx);
3581 ut_ad(mutex_own(&kernel_mutex));
3583 if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) {
3590 if (type_mode == LOCK_AUTO_INC) {
3610 if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
3612 lock_set_lock_and_trx_wait(lock, trx);
3624 lock_table_pop_autoinc_locks(
3628 ut_ad(mutex_own(&kernel_mutex));
3648 lock_table_remove_autoinc_lock(
3656 ut_ad(mutex_own(&kernel_mutex));
3657 ut_ad(lock_get_mode(lock) == LOCK_AUTO_INC);
3666 autoinc_lock =
static_cast<ib_lock_t *
>(
ib_vector_get(trx->autoinc_locks, i));
3670 if (autoinc_lock == lock) {
3671 lock_table_pop_autoinc_locks(trx);
3674 ut_a(autoinc_lock != NULL);
3679 autoinc_lock =
static_cast<ib_lock_t *
>(
ib_vector_get(trx->autoinc_locks, i));
3681 if (UNIV_LIKELY(autoinc_lock == lock)) {
3698 lock_table_remove_low(
3705 ut_ad(mutex_own(&kernel_mutex));
3712 if (lock_get_mode(lock) == LOCK_AUTO_INC) {
3729 if (!lock_get_wait(lock)
3731 lock_table_remove_autoinc_lock(lock, trx);
3751 lock_table_enqueue_waiting(
3761 ut_ad(mutex_own(&kernel_mutex));
3770 return(DB_QUE_THR_SUSPENDED);
3781 fputs(
" InnoDB: Error: a table lock wait happens"
3782 " in a dictionary operation!\n"
3783 "InnoDB: Table name ", stderr);
3786 "InnoDB: Submit a detailed bug report"
3787 " to http://bugs.mysql.com\n",
3793 lock = lock_table_create(table, mode | LOCK_WAIT, trx);
3798 if (lock_deadlock_occurs(lock, trx)) {
3802 lock_table_remove_low(lock);
3803 lock_reset_lock_and_trx_wait(lock);
3805 return(DB_DEADLOCK);
3816 trx->was_chosen_as_deadlock_victim = FALSE;
3821 return(DB_LOCK_WAIT);
3830 lock_table_other_has_incompatible(
3837 enum lock_mode mode)
3841 ut_ad(mutex_own(&kernel_mutex));
3845 while (lock != NULL) {
3847 if ((lock->
trx != trx)
3848 && (!lock_mode_compatible(lock_get_mode(lock), mode))
3849 && (wait || !(lock_get_wait(lock)))) {
3871 enum lock_mode mode,
3877 ut_ad(table && thr);
3879 if (flags & BTR_NO_LOCKING_FLAG) {
3888 lock_mutex_enter_kernel();
3892 if (lock_table_has(trx, table, mode)) {
3894 lock_mutex_exit_kernel();
3902 if (lock_table_other_has_incompatible(trx, LOCK_WAIT, table, mode)) {
3907 err = lock_table_enqueue_waiting(mode | flags, table, thr);
3909 lock_mutex_exit_kernel();
3914 lock_table_create(table, mode | flags, trx);
3916 ut_a(!flags || mode == LOCK_S || mode == LOCK_X);
3918 lock_mutex_exit_kernel();
3928 lock_table_has_to_wait_in_queue(
3935 ut_ad(mutex_own(&kernel_mutex));
3936 ut_ad(lock_get_wait(wait_lock));
3942 while (lock != wait_lock) {
3969 ut_ad(mutex_own(&kernel_mutex));
3974 lock_table_remove_low(in_lock);
3979 while (lock != NULL) {
3981 if (lock_get_wait(lock)
3982 && !lock_table_has_to_wait_in_queue(lock)) {
4006 enum lock_mode lock_mode)
4017 mutex_enter(&kernel_mutex);
4019 first_lock = lock_rec_get_first(block, heap_no);
4024 for (lock = first_lock; lock != NULL;
4025 lock = lock_rec_get_next(heap_no, lock)) {
4026 if (lock->
trx == trx && lock_get_mode(lock) == lock_mode) {
4027 ut_a(!lock_get_wait(lock));
4028 lock_rec_reset_nth_bit(lock, heap_no);
4033 mutex_exit(&kernel_mutex);
4036 " InnoDB: Error: unlock row could not"
4037 " find a %lu mode lock on the record\n",
4045 for (lock = first_lock; lock != NULL;
4046 lock = lock_rec_get_next(heap_no, lock)) {
4047 if (lock_get_wait(lock)
4048 && !lock_rec_has_to_wait_in_queue(lock)) {
4055 mutex_exit(&kernel_mutex);
4071 ut_ad(mutex_own(&kernel_mutex));
4077 while (lock != NULL) {
4083 lock_rec_dequeue_from_page(lock);
4087 if (lock_get_mode(lock) != LOCK_IS
4100 lock_table_dequeue(lock);
4103 if (count == LOCK_RELEASE_KERNEL_INTERVAL) {
4107 lock_mutex_exit_kernel();
4109 lock_mutex_enter_kernel();
4131 ut_ad(mutex_own(&kernel_mutex));
4135 lock_rec_dequeue_from_page(lock);
4139 if (lock->
trx->autoinc_locks != NULL) {
4144 lock_table_dequeue(lock);
4149 lock_reset_lock_and_trx_wait(lock);
4157 #define IS_LOCK_S_OR_X(lock) \
4158 (lock_get_mode(lock) == LOCK_S \
4159 || lock_get_mode(lock) == LOCK_X)
4169 lock_remove_all_on_table_for_trx(
4173 ibool remove_also_table_sx_locks)
4179 ut_ad(mutex_own(&kernel_mutex));
4183 while (lock != NULL) {
4188 ut_a(!lock_get_wait(lock));
4190 lock_rec_discard(lock);
4193 && (remove_also_table_sx_locks
4194 || !IS_LOCK_S_OR_X(lock))) {
4196 ut_a(!lock_get_wait(lock));
4198 lock_table_remove_low(lock);
4216 ibool remove_also_table_sx_locks)
4222 mutex_enter(&kernel_mutex);
4226 while (lock != NULL) {
4234 if (remove_also_table_sx_locks
4236 && IS_LOCK_S_OR_X(lock))) {
4238 ut_a(!lock_get_wait(lock));
4241 lock_remove_all_on_table_for_trx(table, lock->
trx,
4242 remove_also_table_sx_locks);
4244 if (prev_lock == NULL) {
4248 un_member.tab_lock.locks, lock);
4254 prev_lock) != lock) {
4259 un_member.tab_lock.locks, prev_lock);
4263 un_member.tab_lock.locks, lock);
4267 mutex_exit(&kernel_mutex);
4281 ut_ad(mutex_own(&kernel_mutex));
4284 fputs(
"TABLE LOCK table ", file);
4289 if (lock_get_mode(lock) == LOCK_S) {
4290 fputs(
" lock mode S", file);
4291 }
else if (lock_get_mode(lock) == LOCK_X) {
4292 fputs(
" lock mode X", file);
4293 }
else if (lock_get_mode(lock) == LOCK_IS) {
4294 fputs(
" lock mode IS", file);
4295 }
else if (lock_get_mode(lock) == LOCK_IX) {
4296 fputs(
" lock mode IX", file);
4297 }
else if (lock_get_mode(lock) == LOCK_AUTO_INC) {
4298 fputs(
" lock mode AUTO-INC", file);
4300 fprintf(file,
" unknown lock mode %lu",
4301 (ulong) lock_get_mode(lock));
4304 if (lock_get_wait(lock)) {
4305 fputs(
" waiting", file);
4326 ulint offsets_[REC_OFFS_NORMAL_SIZE];
4327 ulint* offsets = offsets_;
4328 rec_offs_init(offsets_);
4330 ut_ad(mutex_own(&kernel_mutex));
4336 fprintf(file,
"RECORD LOCKS space id %lu page no %lu n bits %lu ",
4337 (ulong) space, (ulong) page_no,
4338 (ulong) lock_rec_get_n_bits(lock));
4339 dict_index_name_print(file, lock->
trx, lock->
index);
4342 if (lock_get_mode(lock) == LOCK_S) {
4343 fputs(
" lock mode S", file);
4344 }
else if (lock_get_mode(lock) == LOCK_X) {
4345 fputs(
" lock_mode X", file);
4350 if (lock_rec_get_gap(lock)) {
4351 fputs(
" locks gap before rec", file);
4354 if (lock_rec_get_rec_not_gap(lock)) {
4355 fputs(
" locks rec but not gap", file);
4358 if (lock_rec_get_insert_intention(lock)) {
4359 fputs(
" insert intention", file);
4362 if (lock_get_wait(lock)) {
4363 fputs(
" waiting", file);
4372 for (i = 0; i < lock_rec_get_n_bits(lock); ++i) {
4374 if (!lock_rec_get_nth_bit(lock, i)) {
4378 fprintf(file,
"Record lock, heap no %lu", (ulong) i);
4384 buf_block_get_frame(block), i);
4386 offsets = rec_get_offsets(
4387 rec, lock->
index, offsets,
4388 ULINT_UNDEFINED, &heap);
4398 if (UNIV_LIKELY_NULL(heap)) {
4407 #define PRINT_NUM_OF_LOCK_STRUCTS
4410 #ifdef PRINT_NUM_OF_LOCK_STRUCTS
4416 lock_get_n_rec_locks(
void)
4423 ut_ad(mutex_own(&kernel_mutex));
4455 lock_mutex_enter_kernel();
4456 }
else if (mutex_enter_nowait(&kernel_mutex)) {
4457 fputs(
"FAIL TO OBTAIN KERNEL MUTEX, "
4458 "SKIP LOCK INFO PRINTING\n", file);
4462 if (lock_deadlock_found) {
4463 fputs(
"------------------------\n"
4464 "LATEST DETECTED DEADLOCK\n"
4465 "------------------------\n", file);
4470 fputs(
"------------\n"
4472 "------------\n", file);
4474 fprintf(file,
"Trx id counter " TRX_ID_FMT "\n",
4484 "History list length %lu\n",
4487 #ifdef PRINT_NUM_OF_LOCK_STRUCTS
4489 "Total number of lock structs in row lock hash table %lu\n",
4490 (ulong) lock_get_n_rec_locks());
4504 ibool load_page_first = TRUE;
4511 fprintf(file,
"LIST OF TRANSACTIONS FOR EACH SESSION:\n");
4536 while (trx && (i < nth_trx)) {
4542 lock_mutex_exit_kernel();
4544 ut_ad(lock_validate());
4549 if (nth_lock == 0) {
4555 "Trx read view will not see trx with"
4562 if (trx->
que_state == TRX_QUE_LOCK_WAIT) {
4564 "------- TRX HAS BEEN WAITING %lu SEC"
4565 " FOR THIS LOCK TO BE GRANTED:\n",
4566 (ulong) difftime(time(NULL),
4575 fputs(
"------------------\n", file);
4579 if (!srv_print_innodb_lock_monitor) {
4591 while (lock && (i < nth_lock)) {
4604 if (load_page_first) {
4606 ulint zip_size= fil_space_get_zip_size(space);
4609 if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
4617 fprintf(file,
"RECORD LOCKS on"
4618 " non-existing space %lu\n",
4623 lock_mutex_exit_kernel();
4632 load_page_first = FALSE;
4634 lock_mutex_enter_kernel();
4647 load_page_first = TRUE;
4651 if (nth_lock >= 10) {
4652 fputs(
"10 LOCKS PRINTED FOR THIS TRX:"
4653 " SUPPRESSING FURTHER PRINTS\n",
4671 lock_table_queue_validate(
4677 ut_ad(mutex_own(&kernel_mutex));
4682 ut_a(((lock->
trx)->conc_state == TRX_ACTIVE)
4683 || ((lock->
trx)->conc_state == TRX_PREPARED)
4684 || ((lock->
trx)->conc_state == TRX_COMMITTED_IN_MEMORY));
4686 if (!lock_get_wait(lock)) {
4688 ut_a(!lock_table_other_has_incompatible(
4689 lock->
trx, 0, table,
4690 lock_get_mode(lock)));
4693 ut_a(lock_table_has_to_wait_in_queue(lock));
4707 lock_rec_queue_validate(
4712 const ulint* offsets)
4725 lock_mutex_enter_kernel();
4729 lock = lock_rec_get_first(block, heap_no);
4735 case TRX_COMMITTED_IN_MEMORY:
4743 if (lock_get_wait(lock)) {
4744 ut_a(lock_rec_has_to_wait_in_queue(lock));
4751 lock = lock_rec_get_next(heap_no, lock);
4754 lock_mutex_exit_kernel();
4765 && lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT,
4766 block, heap_no, impl_trx)) {
4768 ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
4769 block, heap_no, impl_trx));
4803 impl_trx = lock_sec_rec_some_has_impl_off_kernel(
4804 rec, index, offsets);
4807 && lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT,
4808 block, heap_no, impl_trx)) {
4810 ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
4811 block, heap_no, impl_trx));
4816 lock = lock_rec_get_first(block, heap_no);
4828 if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) {
4830 enum lock_mode mode;
4832 if (lock_get_mode(lock) == LOCK_S) {
4837 ut_a(!lock_rec_other_has_expl_req(
4838 mode, 0, 0, block, heap_no, lock->
trx));
4840 }
else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) {
4842 ut_a(lock_rec_has_to_wait_in_queue(lock));
4845 lock = lock_rec_get_next(heap_no, lock);
4848 lock_mutex_exit_kernel();
4858 lock_rec_validate_page(
4874 ulint offsets_[REC_OFFS_NORMAL_SIZE];
4875 ulint* offsets = offsets_;
4876 rec_offs_init(offsets_);
4878 ut_ad(!mutex_own(&kernel_mutex));
4882 zip_size = fil_space_get_zip_size(space);
4883 ut_ad(zip_size != ULINT_UNDEFINED);
4884 block =
buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
4885 buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
4887 page = block->
frame;
4889 lock_mutex_enter_kernel();
4891 lock = lock_rec_get_first_on_page_addr(space, page_no);
4897 for (i = 0; i < nth_lock; i++) {
4899 lock = lock_rec_get_next_on_page(lock);
4911 # ifdef UNIV_SYNC_DEBUG
4916 if (!sync_thread_levels_contains(SYNC_FSP))
4918 for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) {
4920 if (i == 1 || lock_rec_get_nth_bit(lock, i)) {
4922 index = lock->
index;
4925 offsets = rec_get_offsets(rec, index, offsets,
4926 ULINT_UNDEFINED, &heap);
4929 "Validating %lu %lu\n",
4930 (ulong) space, (ulong) page_no);
4932 lock_mutex_exit_kernel();
4939 lock_rec_queue_validate(block, rec, index, offsets);
4941 lock_mutex_enter_kernel();
4955 lock_mutex_exit_kernel();
4959 if (UNIV_LIKELY_NULL(heap)) {
4980 lock_mutex_enter_kernel();
4990 lock_table_queue_validate(
5008 ib_uint64_t space_page;
5016 if (space_page >= limit) {
5028 lock_mutex_exit_kernel();
5030 lock_rec_validate_page(space, page_no);
5032 lock_mutex_enter_kernel();
5038 lock_mutex_exit_kernel();
5068 const rec_t* next_rec;
5072 ulint next_rec_heap_no;
5076 if (flags & BTR_NO_LOCKING_FLAG) {
5085 lock_mutex_enter_kernel();
5090 ut_ad(lock_table_has(trx, index->
table, LOCK_IX)
5092 && lock_table_has(trx, index->
table, LOCK_S)));
5094 lock = lock_rec_get_first(block, next_rec_heap_no);
5096 if (UNIV_LIKELY(lock == NULL)) {
5099 lock_mutex_exit_kernel();
5125 if (lock_rec_other_has_conflicting(
5126 static_cast<lock_mode>(LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION),
5127 block, next_rec_heap_no, trx)) {
5130 err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP
5131 | LOCK_INSERT_INTENTION,
5132 block, next_rec_heap_no,
5138 lock_mutex_exit_kernel();
5157 ulint offsets_[REC_OFFS_NORMAL_SIZE];
5158 const ulint* offsets;
5159 rec_offs_init(offsets_);
5161 offsets = rec_get_offsets(next_rec, index, offsets_,
5162 ULINT_UNDEFINED, &heap);
5163 ut_ad(lock_rec_queue_validate(block,
5164 next_rec, index, offsets));
5165 if (UNIV_LIKELY_NULL(heap)) {
5180 lock_rec_convert_impl_to_expl(
5185 const ulint* offsets)
5189 ut_ad(mutex_own(&kernel_mutex));
5197 impl_trx = lock_sec_rec_some_has_impl_off_kernel(
5198 rec, index, offsets);
5207 if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, block,
5208 heap_no, impl_trx)) {
5210 lock_rec_add_to_queue(
5211 LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP,
5212 block, heap_no, index, impl_trx);
5235 const ulint* offsets,
5245 if (flags & BTR_NO_LOCKING_FLAG) {
5254 lock_mutex_enter_kernel();
5261 lock_rec_convert_impl_to_expl(block, rec, index, offsets);
5263 err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP,
5264 block, heap_no, index, thr);
5266 lock_mutex_exit_kernel();
5268 ut_ad(lock_rec_queue_validate(block, rec, index, offsets));
5303 if (flags & BTR_NO_LOCKING_FLAG) {
5315 lock_mutex_enter_kernel();
5319 err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP,
5320 block, heap_no, index, thr);
5322 lock_mutex_exit_kernel();
5327 ulint offsets_[REC_OFFS_NORMAL_SIZE];
5328 const ulint* offsets;
5329 rec_offs_init(offsets_);
5331 offsets = rec_get_offsets(rec, index, offsets_,
5332 ULINT_UNDEFINED, &heap);
5333 ut_ad(lock_rec_queue_validate(block, rec, index, offsets));
5334 if (UNIV_LIKELY_NULL(heap)) {
5371 const ulint* offsets,
5372 enum lock_mode mode,
5388 ut_ad(mode == LOCK_X || mode == LOCK_S);
5390 if (flags & BTR_NO_LOCKING_FLAG) {
5397 lock_mutex_enter_kernel();
5399 ut_ad(mode != LOCK_X
5401 ut_ad(mode != LOCK_S
5412 lock_rec_convert_impl_to_expl(block, rec, index, offsets);
5415 err = lock_rec_lock(FALSE, mode | gap_mode,
5416 block, heap_no, index, thr);
5418 lock_mutex_exit_kernel();
5420 ut_ad(lock_rec_queue_validate(block, rec, index, offsets));
5450 const ulint* offsets,
5451 enum lock_mode mode,
5467 || gap_mode == LOCK_REC_NOT_GAP);
5470 if (flags & BTR_NO_LOCKING_FLAG) {
5477 lock_mutex_enter_kernel();
5479 ut_ad(mode != LOCK_X
5481 ut_ad(mode != LOCK_S
5484 if (UNIV_LIKELY(heap_no != PAGE_HEAP_NO_SUPREMUM)) {
5486 lock_rec_convert_impl_to_expl(block, rec, index, offsets);
5489 err = lock_rec_lock(FALSE, mode | gap_mode,
5490 block, heap_no, index, thr);
5492 lock_mutex_exit_kernel();
5494 ut_ad(lock_rec_queue_validate(block, rec, index, offsets));
5520 enum lock_mode mode,
5530 ulint offsets_[REC_OFFS_NORMAL_SIZE];
5531 ulint* offsets = offsets_;
5533 rec_offs_init(offsets_);
5535 offsets = rec_get_offsets(rec, index, offsets,
5536 ULINT_UNDEFINED, &tmp_heap);
5538 offsets, mode, gap_mode, thr);
5554 lock_release_autoinc_last_lock(
5561 ut_ad(mutex_own(&kernel_mutex));
5569 ut_a(lock_get_mode(lock) == LOCK_AUTO_INC);
5575 lock_table_dequeue(lock);
5587 ut_a(trx->autoinc_locks != NULL);
5600 ut_ad(mutex_own(&kernel_mutex));
5602 ut_a(trx->autoinc_locks != NULL);
5611 lock_release_autoinc_last_lock(trx->autoinc_locks);
5640 return(lock->
trx->
id);
5656 && lock_rec_get_gap(lock);
5658 switch (lock_get_mode(lock)) {
5741 table = lock_get_table(lock);
5758 table = lock_get_table(lock);
5760 return(table->
name);
5774 return(lock->
index);