#include "univ.i"#include "trx0types.h"#include "rem0types.h"#include "dict0types.h"#include "que0types.h"#include "page0types.h"#include "lock0types.h"#include "read0types.h"#include "hash0hash.h"Include dependency graph for lock0lock.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
| #define LOCK_AUTO_INC 6 |
Definition at line 619 of file lock0lock.h.
Referenced by lock_grant(), lock_is_table_exclusive(), lock_mode_compatible(), lock_mode_stronger_or_eq(), lock_table_create(), lock_table_print(), and row_lock_table_autoinc_for_mysql().
| #define LOCK_GAP 512 |
Definition at line 637 of file lock0lock.h.
Referenced by lock_clust_rec_read_check_and_lock(), lock_rec_add_to_queue(), lock_rec_create(), lock_rec_get_gap(), lock_rec_has_expl(), lock_rec_has_to_wait(), lock_rec_inherit_to_gap(), lock_rec_inherit_to_gap_if_gap_lock(), lock_rec_insert_check_and_lock(), lock_rec_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), lock_rec_other_has_expl_req(), and row_search_for_mysql().
| #define LOCK_INSERT_INTENTION 2048 |
Definition at line 654 of file lock0lock.h.
Referenced by lock_rec_get_insert_intention(), lock_rec_has_expl(), lock_rec_has_to_wait(), and lock_rec_insert_check_and_lock().
| #define LOCK_IS 2 |
Definition at line 615 of file lock0lock.h.
Referenced by lock_clust_rec_read_check_and_lock(), lock_get_src_table(), lock_mode_compatible(), lock_mode_stronger_or_eq(), lock_rec_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), lock_release_off_kernel(), lock_sec_rec_read_check_and_lock(), lock_table_print(), row_search_for_mysql(), and row_sel_step().
| #define LOCK_IX 3 |
Definition at line 616 of file lock0lock.h.
Referenced by lock_clust_rec_modify_check_and_lock(), lock_clust_rec_read_check_and_lock(), lock_get_src_table(), lock_is_table_exclusive(), lock_mode_compatible(), lock_mode_stronger_or_eq(), lock_rec_insert_check_and_lock(), lock_rec_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), lock_sec_rec_modify_check_and_lock(), lock_sec_rec_read_check_and_lock(), lock_table_print(), row_ins_foreign_check_on_constraint(), row_ins_step(), row_search_for_mysql(), row_sel_step(), and row_upd_step().
| #define LOCK_MODE_MASK 0xFUL |
Definition at line 621 of file lock0lock.h.
Referenced by ScanTabReq::getLockMode(), lock_get_mode(), lock_rec_add_to_queue(), lock_rec_has_expl(), lock_rec_has_to_wait(), lock_rec_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), and ScanTabReq::setLockMode().
| #define LOCK_NONE 0 |
Definition at line 613 of file lock0lock.h.
Referenced by lock_get_src_table(), row_create_prebuilt(), row_scan_and_check_index(), row_search_for_mysql(), and row_sel_get_clust_rec_for_mysql().
| #define LOCK_NOT_RELEASE_WAIT 2 |
Definition at line 665 of file lock0lock.h.
| #define LOCK_OP_COMPLETE 2 |
Definition at line 675 of file lock0lock.h.
| #define LOCK_OP_START 1 |
Definition at line 674 of file lock0lock.h.
| #define LOCK_ORDINARY 0 |
Definition at line 635 of file lock0lock.h.
Referenced by lock_clust_rec_read_check_and_lock(), row_ins_scan_sec_index_for_duplicate(), row_search_for_mysql(), row_sel(), and row_sel_get_clust_rec().
| #define LOCK_REC 32 |
Definition at line 625 of file lock0lock.h.
Referenced by lock_cancel_waiting_and_release(), lock_deadlock_recursive(), lock_has_to_wait(), lock_number_of_rows_locked(), lock_print_info_all_transactions(), lock_rec_add_to_queue(), lock_rec_bitmap_reset(), lock_rec_cancel(), lock_rec_convert_impl_to_expl(), lock_rec_copy(), lock_rec_create(), lock_rec_dequeue_from_page(), lock_rec_discard(), lock_rec_get_gap(), lock_rec_get_insert_intention(), lock_rec_get_next(), lock_rec_get_next_on_page(), lock_rec_get_nth_bit(), lock_rec_get_prev(), lock_rec_get_rec_not_gap(), lock_rec_has_to_wait(), lock_rec_has_to_wait_in_queue(), lock_rec_inherit_to_gap(), lock_rec_inherit_to_gap_if_gap_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), lock_rec_print(), lock_rec_reset_nth_bit(), lock_rec_set_nth_bit(), lock_release_off_kernel(), and lock_reset_all_on_table_for_trx().
| #define LOCK_REC_NOT_GAP 1024 |
Definition at line 646 of file lock0lock.h.
Referenced by lock_clust_rec_modify_check_and_lock(), lock_clust_rec_read_check_and_lock(), lock_rec_add_to_queue(), lock_rec_convert_impl_to_expl(), lock_rec_create(), lock_rec_get_rec_not_gap(), lock_rec_has_expl(), lock_rec_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), lock_rec_queue_validate(), lock_sec_rec_modify_check_and_lock(), row_ins_duplicate_error_in_clust(), row_ins_foreign_check_on_constraint(), row_search_for_mysql(), row_sel(), row_sel_get_clust_rec(), and row_sel_get_clust_rec_for_mysql().
| #define LOCK_RELEASE_WAIT 1 |
Definition at line 664 of file lock0lock.h.
| #define LOCK_S 4 |
Definition at line 617 of file lock0lock.h.
Referenced by lock_clust_rec_read_check_and_lock(), lock_mode_compatible(), lock_mode_stronger_or_eq(), lock_rec_add_to_queue(), lock_rec_has_expl(), lock_rec_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), lock_rec_other_has_expl_req(), lock_rec_print(), lock_rec_queue_validate(), lock_sec_rec_read_check_and_lock(), lock_table(), lock_table_print(), opt_print_query_plan(), pars_select_statement(), row_ins_set_shared_rec_lock(), and row_search_for_mysql().
| #define LOCK_TABLE 16 |
Definition at line 624 of file lock0lock.h.
Referenced by lock_cancel_waiting_and_release(), lock_deadlock_occurs(), lock_deadlock_recursive(), lock_get_src_table(), lock_is_table_exclusive(), lock_print_info_all_transactions(), lock_release_off_kernel(), lock_reset_all_on_table_for_trx(), lock_table_create(), lock_table_dequeue(), lock_table_print(), and lock_validate().
| #define LOCK_TYPE_MASK 0xF0UL |
| #define LOCK_WAIT 256 |
Definition at line 629 of file lock0lock.h.
Referenced by lock_get_wait(), lock_rec_add_to_queue(), lock_rec_create(), lock_rec_enqueue_waiting(), lock_rec_other_has_expl_req(), lock_rec_queue_validate(), lock_reset_lock_and_trx_wait(), lock_set_lock_and_trx_wait(), lock_table(), lock_table_create(), and lock_table_enqueue_waiting().
| #define LOCK_X 5 |
Definition at line 618 of file lock0lock.h.
Referenced by lock_clust_rec_modify_check_and_lock(), lock_clust_rec_read_check_and_lock(), lock_mode_compatible(), lock_mode_stronger_or_eq(), lock_rec_add_to_queue(), lock_rec_convert_impl_to_expl(), lock_rec_has_expl(), lock_rec_inherit_to_gap(), lock_rec_insert_check_and_lock(), lock_rec_lock(), lock_rec_lock_fast(), lock_rec_lock_slow(), lock_rec_other_has_expl_req(), lock_rec_print(), lock_rec_queue_validate(), lock_sec_rec_modify_check_and_lock(), lock_sec_rec_read_check_and_lock(), lock_table(), lock_table_print(), opt_print_query_plan(), pars_select_statement(), pars_update_statement(), row_ins_foreign_check_on_constraint(), row_ins_set_exclusive_rec_lock(), and row_sel_get_clust_rec_for_mysql().
| typedef struct lock_op_struct lock_op_t |
Definition at line 668 of file lock0lock.h.
| void lock_cancel_waiting_and_release | ( | lock_t * | lock | ) |
Definition at line 3969 of file lock0lock.c.
References kernel_mutex, lock, lock_get_type(), LOCK_REC, lock_rec_dequeue_from_page(), lock_reset_lock_and_trx_wait(), LOCK_TABLE, lock_table_dequeue(), trx_end_lock_wait(), and ut_ad.
Referenced by lock_deadlock_recursive(), row_search_for_mysql(), and srv_lock_timeout_and_monitor_thread().
03971 : waiting lock request */ 03972 { 03973 #ifdef UNIV_SYNC_DEBUG 03974 ut_ad(mutex_own(&kernel_mutex)); 03975 #endif /* UNIV_SYNC_DEBUG */ 03976 03977 if (lock_get_type(lock) == LOCK_REC) { 03978 03979 lock_rec_dequeue_from_page(lock); 03980 } else { 03981 ut_ad(lock_get_type(lock) & LOCK_TABLE); 03982 03983 lock_table_dequeue(lock); 03984 } 03985 03986 /* Reset the wait flag and the back pointer to lock in trx */ 03987 03988 lock_reset_lock_and_trx_wait(lock); 03989 03990 /* The following function releases the trx from lock wait */ 03991 03992 trx_end_lock_wait(lock->trx); 03993 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool lock_check_trx_id_sanity | ( | dulint | trx_id, | |
| rec_t * | rec, | |||
| dict_index_t * | index, | |||
| const ulint * | offsets, | |||
| ibool | has_kernel_mutex | |||
| ) |
Definition at line 456 of file lock0lock.c.
References dict_index_name_print(), FALSE, index(), kernel_mutex, trx_sys_struct::max_trx_id, mutex_enter, mutex_exit(), NULL, rec_offs_validate(), rec_print_new(), TRUE, trx_sys, ut_ad, ut_dulint_cmp(), ut_dulint_get_high(), ut_dulint_get_low(), and ut_print_timestamp().
Referenced by lock_sec_rec_some_has_impl_off_kernel(), and row_vers_impl_x_locked_off_kernel().
00458 : TRUE if ok */ 00459 dulint trx_id, /* in: trx id */ 00460 rec_t* rec, /* in: user record */ 00461 dict_index_t* index, /* in: index */ 00462 const ulint* offsets, /* in: rec_get_offsets(rec, index) */ 00463 ibool has_kernel_mutex)/* in: TRUE if the caller owns the 00464 kernel mutex */ 00465 { 00466 ibool is_ok = TRUE; 00467 00468 ut_ad(rec_offs_validate(rec, index, offsets)); 00469 00470 if (!has_kernel_mutex) { 00471 mutex_enter(&kernel_mutex); 00472 } 00473 00474 /* A sanity check: the trx_id in rec must be smaller than the global 00475 trx id counter */ 00476 00477 if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) { 00478 ut_print_timestamp(stderr); 00479 fputs(" InnoDB: Error: transaction id associated" 00480 " with record\n", 00481 stderr); 00482 rec_print_new(stderr, rec, offsets); 00483 fputs("InnoDB: in ", stderr); 00484 dict_index_name_print(stderr, NULL, index); 00485 fprintf(stderr, "\n" 00486 "InnoDB: is %lu %lu which is higher than the global trx id counter %lu %lu!\n" 00487 "InnoDB: The table is corrupt. You have to do dump + drop + reimport.\n", 00488 (ulong) ut_dulint_get_high(trx_id), 00489 (ulong) ut_dulint_get_low(trx_id), 00490 (ulong) ut_dulint_get_high(trx_sys->max_trx_id), 00491 (ulong) ut_dulint_get_low(trx_sys->max_trx_id)); 00492 00493 is_ok = FALSE; 00494 } 00495 00496 if (!has_kernel_mutex) { 00497 mutex_exit(&kernel_mutex); 00498 } 00499 00500 return(is_ok); 00501 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool lock_clust_rec_cons_read_sees | ( | rec_t * | rec, | |
| dict_index_t * | index, | |||
| const ulint * | offsets, | |||
| read_view_t * | view | |||
| ) |
Definition at line 507 of file lock0lock.c.
References DICT_CLUSTERED, index(), page_rec_is_user_rec(), read_view_sees_trx_id(), rec_offs_validate(), row_get_rec_trx_id(), and ut_ad.
Referenced by row_search_for_mysql(), row_sel(), row_sel_get_clust_rec(), row_sel_get_clust_rec_for_mysql(), row_sel_try_search_shortcut(), and row_sel_try_search_shortcut_for_mysql().
00509 : TRUE if sees, or FALSE if an earlier 00510 version of the record should be retrieved */ 00511 rec_t* rec, /* in: user record which should be read or 00512 passed over by a read cursor */ 00513 dict_index_t* index, /* in: clustered index */ 00514 const ulint* offsets,/* in: rec_get_offsets(rec, index) */ 00515 read_view_t* view) /* in: consistent read view */ 00516 { 00517 dulint trx_id; 00518 00519 ut_ad(index->type & DICT_CLUSTERED); 00520 ut_ad(page_rec_is_user_rec(rec)); 00521 ut_ad(rec_offs_validate(rec, index, offsets)); 00522 00523 /* NOTE that we call this function while holding the search 00524 system latch. To obey the latching order we must NOT reserve the 00525 kernel mutex here! */ 00526 00527 trx_id = row_get_rec_trx_id(rec, index, offsets); 00528 00529 return(read_view_sees_trx_id(view, trx_id)); 00530 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_clust_rec_modify_check_and_lock | ( | ulint | flags, | |
| rec_t * | rec, | |||
| dict_index_t * | index, | |||
| const ulint * | offsets, | |||
| que_thr_t * | thr | |||
| ) |
Definition at line 4946 of file lock0lock.c.
References BTR_NO_LOCKING_FLAG, DB_SUCCESS, DICT_CLUSTERED, err, index(), LOCK_IX, lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_convert_impl_to_expl(), lock_rec_lock(), LOCK_REC_NOT_GAP, lock_rec_queue_validate(), lock_table_has(), LOCK_X, rec_offs_validate(), thr_get_trx(), TRUE, and ut_ad.
Referenced by btr_cur_del_mark_set_clust_rec(), btr_cur_upd_lock_and_undo(), and row_upd_clust_step().
04948 : DB_SUCCESS, DB_LOCK_WAIT, 04949 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 04950 ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, 04951 does nothing */ 04952 rec_t* rec, /* in: record which should be modified */ 04953 dict_index_t* index, /* in: clustered index */ 04954 const ulint* offsets,/* in: rec_get_offsets(rec, index) */ 04955 que_thr_t* thr) /* in: query thread */ 04956 { 04957 ulint err; 04958 04959 ut_ad(rec_offs_validate(rec, index, offsets)); 04960 ut_ad(index->type & DICT_CLUSTERED); 04961 04962 if (flags & BTR_NO_LOCKING_FLAG) { 04963 04964 return(DB_SUCCESS); 04965 } 04966 04967 lock_mutex_enter_kernel(); 04968 04969 ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); 04970 04971 /* If a transaction has no explicit x-lock set on the record, set one 04972 for it */ 04973 04974 lock_rec_convert_impl_to_expl(rec, index, offsets); 04975 04976 err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP, rec, index, thr); 04977 04978 lock_mutex_exit_kernel(); 04979 04980 ut_ad(lock_rec_queue_validate(rec, index, offsets)); 04981 04982 return(err); 04983 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_clust_rec_read_check_and_lock | ( | ulint | flags, | |
| rec_t * | rec, | |||
| dict_index_t * | index, | |||
| const ulint * | offsets, | |||
| ulint | mode, | |||
| ulint | gap_mode, | |||
| que_thr_t * | thr | |||
| ) |
Definition at line 5122 of file lock0lock.c.
References BTR_NO_LOCKING_FLAG, DB_SUCCESS, DICT_CLUSTERED, err, FALSE, index(), LOCK_GAP, LOCK_IS, LOCK_IX, lock_mutex_enter_kernel, lock_mutex_exit_kernel, LOCK_ORDINARY, lock_rec_convert_impl_to_expl(), lock_rec_lock(), LOCK_REC_NOT_GAP, lock_rec_queue_validate(), LOCK_S, lock_table_has(), LOCK_X, page_rec_is_supremum(), page_rec_is_user_rec(), rec_offs_validate(), thr_get_trx(), and ut_ad.
Referenced by lock_clust_rec_read_check_and_lock_alt(), row_ins_set_exclusive_rec_lock(), row_ins_set_shared_rec_lock(), row_sel_get_clust_rec(), row_sel_get_clust_rec_for_mysql(), and sel_set_rec_lock().
05124 : DB_SUCCESS, DB_LOCK_WAIT, 05125 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 05126 ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, 05127 does nothing */ 05128 rec_t* rec, /* in: user record or page supremum record 05129 which should be read or passed over by a read 05130 cursor */ 05131 dict_index_t* index, /* in: clustered index */ 05132 const ulint* offsets,/* in: rec_get_offsets(rec, index) */ 05133 ulint mode, /* in: mode of the lock which the read cursor 05134 should set on records: LOCK_S or LOCK_X; the 05135 latter is possible in SELECT FOR UPDATE */ 05136 ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or 05137 LOCK_REC_NOT_GAP */ 05138 que_thr_t* thr) /* in: query thread */ 05139 { 05140 ulint err; 05141 05142 ut_ad(index->type & DICT_CLUSTERED); 05143 ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec)); 05144 ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP 05145 || gap_mode == LOCK_REC_NOT_GAP); 05146 ut_ad(rec_offs_validate(rec, index, offsets)); 05147 05148 if (flags & BTR_NO_LOCKING_FLAG) { 05149 05150 return(DB_SUCCESS); 05151 } 05152 05153 lock_mutex_enter_kernel(); 05154 05155 ut_ad(mode != LOCK_X 05156 || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); 05157 ut_ad(mode != LOCK_S 05158 || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); 05159 05160 if (!page_rec_is_supremum(rec)) { 05161 05162 lock_rec_convert_impl_to_expl(rec, index, offsets); 05163 } 05164 05165 err = lock_rec_lock(FALSE, mode | gap_mode, rec, index, thr); 05166 05167 lock_mutex_exit_kernel(); 05168 05169 ut_ad(lock_rec_queue_validate(rec, index, offsets)); 05170 05171 return(err); 05172 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_clust_rec_read_check_and_lock_alt | ( | ulint | flags, | |
| rec_t * | rec, | |||
| dict_index_t * | index, | |||
| ulint | mode, | |||
| ulint | gap_mode, | |||
| que_thr_t * | thr | |||
| ) |
Definition at line 5184 of file lock0lock.c.
References index(), lock_clust_rec_read_check_and_lock(), mem_heap_free, NULL, rec_get_offsets, and REC_OFFS_NORMAL_SIZE.
Referenced by row_ins_foreign_check_on_constraint().
05186 : DB_SUCCESS, DB_LOCK_WAIT, 05187 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 05188 ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, 05189 does nothing */ 05190 rec_t* rec, /* in: user record or page supremum record 05191 which should be read or passed over by a read 05192 cursor */ 05193 dict_index_t* index, /* in: clustered index */ 05194 ulint mode, /* in: mode of the lock which the read cursor 05195 should set on records: LOCK_S or LOCK_X; the 05196 latter is possible in SELECT FOR UPDATE */ 05197 ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or 05198 LOCK_REC_NOT_GAP */ 05199 que_thr_t* thr) /* in: query thread */ 05200 { 05201 mem_heap_t* tmp_heap = NULL; 05202 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 05203 ulint* offsets = offsets_; 05204 ulint ret; 05205 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 05206 05207 offsets = rec_get_offsets(rec, index, offsets, 05208 ULINT_UNDEFINED, &tmp_heap); 05209 ret = lock_clust_rec_read_check_and_lock(flags, rec, index, 05210 offsets, mode, gap_mode, thr); 05211 if (tmp_heap) { 05212 mem_heap_free(tmp_heap); 05213 } 05214 return(ret); 05215 }
Here is the call graph for this function:

Here is the caller graph for this function:

| UNIV_INLINE trx_t* lock_clust_rec_some_has_impl | ( | rec_t * | rec, | |
| dict_index_t * | index, | |||
| const ulint * | offsets | |||
| ) |
Referenced by lock_rec_convert_impl_to_expl(), and lock_rec_queue_validate().
Here is the caller graph for this function:

| ulint lock_get_size | ( | void | ) |
Definition at line 599 of file lock0lock.c.
Referenced by dict_mem_table_create().
Here is the caller graph for this function:

| dict_table_t* lock_get_src_table | ( | trx_t * | trx, | |
| dict_table_t * | dest, | |||
| ulint * | mode | |||
| ) |
Definition at line 644 of file lock0lock.c.
References lock, lock_get_mode(), lock_get_type(), LOCK_IS, LOCK_IX, LOCK_NONE, LOCK_TABLE, dict_table_struct::locks, NULL, lock_table_struct::table, trx_struct::trx_locks, UT_LIST_GET_FIRST, UT_LIST_GET_LEN, and UT_LIST_GET_NEXT.
00646 : the source table of transaction, 00647 if it is covered by an IX or IS table lock; 00648 dest if there is no source table, and 00649 NULL if the transaction is locking more than 00650 two tables or an inconsistency is found */ 00651 trx_t* trx, /* in: transaction */ 00652 dict_table_t* dest, /* in: destination of ALTER TABLE */ 00653 ulint* mode) /* out: lock mode of the source table */ 00654 { 00655 dict_table_t* src; 00656 lock_t* lock; 00657 00658 src = NULL; 00659 *mode = LOCK_NONE; 00660 00661 for (lock = UT_LIST_GET_FIRST(trx->trx_locks); 00662 lock; 00663 lock = UT_LIST_GET_NEXT(trx_locks, lock)) { 00664 lock_table_t* tab_lock; 00665 ulint lock_mode; 00666 if (!(lock_get_type(lock) & LOCK_TABLE)) { 00667 /* We are only interested in table locks. */ 00668 continue; 00669 } 00670 tab_lock = &lock->un_member.tab_lock; 00671 if (dest == tab_lock->table) { 00672 /* We are not interested in the destination table. */ 00673 continue; 00674 } else if (!src) { 00675 /* This presumably is the source table. */ 00676 src = tab_lock->table; 00677 if (UT_LIST_GET_LEN(src->locks) != 1 || 00678 UT_LIST_GET_FIRST(src->locks) != lock) { 00679 /* We only support the case when 00680 there is only one lock on this table. */ 00681 return(NULL); 00682 } 00683 } else if (src != tab_lock->table) { 00684 /* The transaction is locking more than 00685 two tables (src and dest): abort */ 00686 return(NULL); 00687 } 00688 00689 /* Check that the source table is locked by 00690 LOCK_IX or LOCK_IS. */ 00691 lock_mode = lock_get_mode(lock); 00692 switch (lock_mode) { 00693 case LOCK_IX: 00694 case LOCK_IS: 00695 if (*mode != LOCK_NONE && *mode != lock_mode) { 00696 /* There are multiple locks on src. */ 00697 return(NULL); 00698 } 00699 *mode = lock_mode; 00700 break; 00701 } 00702 } 00703 00704 if (!src) { 00705 /* No source table lock found: flag the situation to caller */ 00706 src = dest; 00707 } 00708 00709 return(src); 00710 }
Here is the call graph for this function:

| ibool lock_is_on_table | ( | dict_table_t * | table | ) |
Definition at line 3700 of file lock0lock.c.
References FALSE, lock_mutex_enter_kernel, lock_mutex_exit_kernel, dict_table_struct::locks, TRUE, ut_ad, and UT_LIST_GET_LAST.
03702 : TRUE if there are lock(s) */ 03703 dict_table_t* table) /* in: database table in dictionary cache */ 03704 { 03705 ibool ret; 03706 03707 ut_ad(table); 03708 03709 lock_mutex_enter_kernel(); 03710 03711 if (UT_LIST_GET_LAST(table->locks)) { 03712 ret = TRUE; 03713 } else { 03714 ret = FALSE; 03715 } 03716 03717 lock_mutex_exit_kernel(); 03718 03719 return(ret); 03720 }
| ibool lock_is_table_exclusive | ( | dict_table_t * | table, | |
| trx_t * | trx | |||
| ) |
Definition at line 718 of file lock0lock.c.
References FALSE, lock, LOCK_AUTO_INC, lock_get_mode(), lock_get_type(), LOCK_IX, LOCK_TABLE, dict_table_struct::locks, lock_table_struct::locks, ok(), lock_table_struct::table, TRUE, ut_ad, UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
00720 : TRUE if table is only locked by trx, 00721 with LOCK_IX, and possibly LOCK_AUTO_INC */ 00722 dict_table_t* table, /* in: table */ 00723 trx_t* trx) /* in: transaction */ 00724 { 00725 lock_t* lock; 00726 ibool ok = FALSE; 00727 00728 ut_ad(table && trx); 00729 00730 for (lock = UT_LIST_GET_FIRST(table->locks); 00731 lock; 00732 lock = UT_LIST_GET_NEXT(locks, &lock->un_member.tab_lock)) { 00733 if (lock->trx != trx) { 00734 /* A lock on the table is held 00735 by some other transaction. */ 00736 return(FALSE); 00737 } 00738 00739 if (!(lock_get_type(lock) & LOCK_TABLE)) { 00740 /* We are interested in table locks only. */ 00741 continue; 00742 } 00743 00744 switch (lock_get_mode(lock)) { 00745 case LOCK_IX: 00746 ok = TRUE; 00747 break; 00748 case LOCK_AUTO_INC: 00749 /* It is allowed for trx to hold an 00750 auto_increment lock. */ 00751 break; 00752 default: 00753 /* Other table locks than LOCK_IX are not allowed. */ 00754 return(FALSE); 00755 } 00756 } 00757 00758 return(ok); 00759 }
Here is the call graph for this function:

Definition at line 2704 of file lock0lock.c.
References buf_frame_align(), lock, lock_get_wait(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_add_to_queue(), lock_rec_get_first_on_page(), lock_rec_get_next_on_page(), lock_rec_get_nth_bit(), lock_rec_reset_nth_bit(), lock_reset_lock_and_trx_wait(), NULL, page_cur_get_rec(), page_cur_is_before_first(), page_cur_move_to_next(), page_cur_position(), page_cur_set_before_first(), page_get_supremum_rec(), page_is_comp(), rec_get_data_size_old(), rec_get_heap_no(), ut_ad, and ut_memcmp().
Referenced by page_copy_rec_list_end().
02706 : index page to move to */ 02707 page_t* page, /* in: index page */ 02708 rec_t* rec) /* in: record on page: this is the 02709 first record moved */ 02710 { 02711 lock_t* lock; 02712 page_cur_t cur1; 02713 page_cur_t cur2; 02714 ulint heap_no; 02715 rec_t* sup; 02716 ulint type_mode; 02717 ulint comp; 02718 ut_ad(page == buf_frame_align(rec)); 02719 02720 lock_mutex_enter_kernel(); 02721 02722 /* Note: when we move locks from record to record, waiting locks 02723 and possible granted gap type locks behind them are enqueued in 02724 the original order, because new elements are inserted to a hash 02725 table to the end of the hash chain, and lock_rec_add_to_queue 02726 does not reuse locks if there are waiters in the queue. */ 02727 02728 sup = page_get_supremum_rec(page); 02729 02730 lock = lock_rec_get_first_on_page(page); 02731 02732 comp = page_is_comp(page); 02733 02734 while (lock != NULL) { 02735 02736 page_cur_position(rec, &cur1); 02737 02738 if (page_cur_is_before_first(&cur1)) { 02739 page_cur_move_to_next(&cur1); 02740 } 02741 02742 page_cur_set_before_first(new_page, &cur2); 02743 page_cur_move_to_next(&cur2); 02744 02745 /* Copy lock requests on user records to new page and 02746 reset the lock bits on the old */ 02747 02748 while (page_cur_get_rec(&cur1) != sup) { 02749 ut_ad(comp || 0 == ut_memcmp(page_cur_get_rec(&cur1), 02750 page_cur_get_rec(&cur2), 02751 rec_get_data_size_old( 02752 page_cur_get_rec(&cur2)))); 02753 heap_no = rec_get_heap_no(page_cur_get_rec(&cur1), 02754 comp); 02755 02756 if (lock_rec_get_nth_bit(lock, heap_no)) { 02757 type_mode = lock->type_mode; 02758 02759 lock_rec_reset_nth_bit(lock, heap_no); 02760 02761 if (lock_get_wait(lock)) { 02762 lock_reset_lock_and_trx_wait(lock); 02763 } 02764 02765 lock_rec_add_to_queue(type_mode, 02766 page_cur_get_rec(&cur2), 02767 lock->index, lock->trx); 02768 } 02769 02770 page_cur_move_to_next(&cur1); 02771 page_cur_move_to_next(&cur2); 02772 } 02773 02774 lock = lock_rec_get_next_on_page(lock); 02775 } 02776 02777 lock_mutex_exit_kernel(); 02778 02779 /* ut_ad(lock_rec_validate_page(buf_frame_get_space_id(page), 02780 buf_frame_get_page_no(page))); 02781 ut_ad(lock_rec_validate_page(buf_frame_get_space_id(new_page), 02782 buf_frame_get_page_no(new_page))); */ 02783 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2790 of file lock0lock.c.
References buf_frame_align(), lock, lock_get_wait(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_add_to_queue(), lock_rec_get_first_on_page(), lock_rec_get_next_on_page(), lock_rec_get_nth_bit(), lock_rec_reset_nth_bit(), lock_reset_lock_and_trx_wait(), NULL, page_cur_get_rec(), page_cur_move_to_next(), page_cur_position(), page_cur_set_before_first(), page_is_comp(), rec_get_data_size_old(), rec_get_heap_no(), ut_a, ut_ad, and ut_memcmp().
Referenced by page_copy_rec_list_start().
02792 : index page to move to */ 02793 page_t* page, /* in: index page */ 02794 rec_t* rec, /* in: record on page: this is the 02795 first record NOT copied */ 02796 rec_t* old_end) /* in: old previous-to-last record on 02797 new_page before the records were copied */ 02798 { 02799 lock_t* lock; 02800 page_cur_t cur1; 02801 page_cur_t cur2; 02802 ulint heap_no; 02803 ulint type_mode; 02804 ulint comp; 02805 02806 ut_a(new_page); 02807 02808 lock_mutex_enter_kernel(); 02809 02810 lock = lock_rec_get_first_on_page(page); 02811 comp = page_is_comp(page); 02812 ut_ad(comp == page_is_comp(new_page)); 02813 ut_ad(page == buf_frame_align(rec)); 02814 02815 while (lock != NULL) { 02816 02817 page_cur_set_before_first(page, &cur1); 02818 page_cur_move_to_next(&cur1); 02819 02820 page_cur_position(old_end, &cur2); 02821 page_cur_move_to_next(&cur2); 02822 02823 /* Copy lock requests on user records to new page and 02824 reset the lock bits on the old */ 02825 02826 while (page_cur_get_rec(&cur1) != rec) { 02827 ut_ad(comp || 0 == ut_memcmp(page_cur_get_rec(&cur1), 02828 page_cur_get_rec(&cur2), 02829 rec_get_data_size_old( 02830 page_cur_get_rec(&cur2)))); 02831 heap_no = rec_get_heap_no(page_cur_get_rec(&cur1), 02832 comp); 02833 02834 if (lock_rec_get_nth_bit(lock, heap_no)) { 02835 type_mode = lock->type_mode; 02836 02837 lock_rec_reset_nth_bit(lock, heap_no); 02838 02839 if (lock_get_wait(lock)) { 02840 lock_reset_lock_and_trx_wait(lock); 02841 } 02842 02843 lock_rec_add_to_queue(type_mode, 02844 page_cur_get_rec(&cur2), 02845 lock->index, lock->trx); 02846 } 02847 02848 page_cur_move_to_next(&cur1); 02849 page_cur_move_to_next(&cur2); 02850 } 02851 02852 lock = lock_rec_get_next_on_page(lock); 02853 } 02854 02855 lock_mutex_exit_kernel(); 02856 02857 /* ut_ad(lock_rec_validate_page(buf_frame_get_space_id(page), 02858 buf_frame_get_page_no(page))); 02859 ut_ad(lock_rec_validate_page(buf_frame_get_space_id(new_page), 02860 buf_frame_get_page_no(new_page))); */ 02861 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2585 of file lock0lock.c.
References lock, lock_get_wait(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_add_to_queue(), lock_rec_bitmap_reset(), lock_rec_copy(), lock_rec_get_first_on_page(), lock_rec_get_next_on_page(), lock_rec_get_nth_bit(), lock_reset_lock_and_trx_wait(), mem_heap_create, mem_heap_free, NULL, page_cur_get_rec(), page_cur_move_to_next(), page_cur_set_before_first(), page_get_supremum_rec(), page_is_comp(), rec_get_data_size_old(), rec_get_heap_no(), ut_ad, UT_LIST_ADD_LAST, UT_LIST_BASE_NODE_T, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, UT_LIST_INIT, and ut_memcmp().
Referenced by btr_page_reorganize_low().
02587 : old index page, now reorganized */ 02588 page_t* old_page) /* in: copy of the old, not reorganized page */ 02589 { 02590 lock_t* lock; 02591 lock_t* old_lock; 02592 page_cur_t cur1; 02593 page_cur_t cur2; 02594 ulint old_heap_no; 02595 UT_LIST_BASE_NODE_T(lock_t) old_locks; 02596 mem_heap_t* heap = NULL; 02597 rec_t* sup; 02598 ulint comp; 02599 02600 lock_mutex_enter_kernel(); 02601 02602 lock = lock_rec_get_first_on_page(page); 02603 02604 if (lock == NULL) { 02605 lock_mutex_exit_kernel(); 02606 02607 return; 02608 } 02609 02610 heap = mem_heap_create(256); 02611 02612 /* Copy first all the locks on the page to heap and reset the 02613 bitmaps in the original locks; chain the copies of the locks 02614 using the trx_locks field in them. */ 02615 02616 UT_LIST_INIT(old_locks); 02617 02618 while (lock != NULL) { 02619 02620 /* Make a copy of the lock */ 02621 old_lock = lock_rec_copy(lock, heap); 02622 02623 UT_LIST_ADD_LAST(trx_locks, old_locks, old_lock); 02624 02625 /* Reset bitmap of lock */ 02626 lock_rec_bitmap_reset(lock); 02627 02628 if (lock_get_wait(lock)) { 02629 lock_reset_lock_and_trx_wait(lock); 02630 } 02631 02632 lock = lock_rec_get_next_on_page(lock); 02633 } 02634 02635 sup = page_get_supremum_rec(page); 02636 02637 lock = UT_LIST_GET_FIRST(old_locks); 02638 02639 comp = page_is_comp(page); 02640 ut_ad(comp == page_is_comp(old_page)); 02641 02642 while (lock) { 02643 /* NOTE: we copy also the locks set on the infimum and 02644 supremum of the page; the infimum may carry locks if an 02645 update of a record is occurring on the page, and its locks 02646 were temporarily stored on the infimum */ 02647 02648 page_cur_set_before_first(page, &cur1); 02649 page_cur_set_before_first(old_page, &cur2); 02650 02651 /* Set locks according to old locks */ 02652 for (;;) { 02653 ut_ad(comp || 0 == ut_memcmp(page_cur_get_rec(&cur1), 02654 page_cur_get_rec(&cur2), 02655 rec_get_data_size_old( 02656 page_cur_get_rec(&cur2)))); 02657 old_heap_no = rec_get_heap_no(page_cur_get_rec(&cur2), 02658 comp); 02659 02660 if (lock_rec_get_nth_bit(lock, old_heap_no)) { 02661 02662 /* NOTE that the old lock bitmap could be too 02663 small for the new heap number! */ 02664 02665 lock_rec_add_to_queue(lock->type_mode, 02666 page_cur_get_rec(&cur1), 02667 lock->index, lock->trx); 02668 02669 /* if ((page_cur_get_rec(&cur1) == sup) 02670 && lock_get_wait(lock)) { 02671 fprintf(stderr, 02672 "---\n--\n!!!Lock reorg: supr type %lu\n", 02673 lock->type_mode); 02674 } */ 02675 } 02676 02677 if (page_cur_get_rec(&cur1) == sup) { 02678 02679 break; 02680 } 02681 02682 page_cur_move_to_next(&cur1); 02683 page_cur_move_to_next(&cur2); 02684 } 02685 02686 /* Remember that we chained old locks on the trx_locks field: */ 02687 02688 lock = UT_LIST_GET_NEXT(trx_locks, lock); 02689 } 02690 02691 lock_mutex_exit_kernel(); 02692 02693 mem_heap_free(heap); 02694 02695 /* ut_ad(lock_rec_validate_page(buf_frame_get_space_id(page), 02696 buf_frame_get_page_no(page))); */ 02697 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1707 of file lock0lock.c.
References lock, lock_get_type(), LOCK_REC, lock_rec_get_n_bits(), lock_rec_get_nth_bit(), trx_struct::trx_locks, UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by lock_print_info_all_transactions(), and trx_print().
01709 : transaction */ 01710 { 01711 lock_t* lock; 01712 ulint n_records = 0; 01713 ulint n_bits; 01714 ulint n_bit; 01715 01716 lock = UT_LIST_GET_FIRST(trx->trx_locks); 01717 01718 while (lock) { 01719 if (lock_get_type(lock) == LOCK_REC) { 01720 n_bits = lock_rec_get_n_bits(lock); 01721 01722 for (n_bit = 0; n_bit < n_bits; n_bit++) { 01723 if (lock_rec_get_nth_bit(lock, n_bit)) { 01724 n_records++; 01725 } 01726 } 01727 } 01728 01729 lock = UT_LIST_GET_NEXT(trx_locks, lock); 01730 } 01731 01732 return (n_records); 01733 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_print_info_all_transactions | ( | FILE * | file | ) |
Definition at line 4298 of file lock0lock.c.
References buf_page_get_with_no_latch, trx_struct::conc_state, FALSE, innobase_mysql_end_print_arbitrary_thd(), innobase_mysql_prepare_print_arbitrary_thd(), lock, lock_get_type(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_number_of_rows_locked(), LOCK_REC, lock_rec_print(), LOCK_TABLE, lock_table_print(), lock_validate(), read_view_struct::low_limit_id, mtr_commit(), mtr_start(), NULL, page, page_t, trx_struct::read_view, srv_print_innodb_lock_monitor, TRUE, trx_struct::trx_locks, TRX_NOT_STARTED, trx_print(), TRX_QUE_LOCK_WAIT, trx_sys, read_view_struct::up_limit_id, ut_ad, ut_dulint_get_high(), ut_dulint_get_low(), UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by srv_printf_innodb_monitor().
04300 : file where to print */ 04301 { 04302 lock_t* lock; 04303 ulint space; 04304 ulint page_no; 04305 page_t* page; 04306 ibool load_page_first = TRUE; 04307 ulint nth_trx = 0; 04308 ulint nth_lock = 0; 04309 ulint i; 04310 mtr_t mtr; 04311 trx_t* trx; 04312 04313 fprintf(file, "LIST OF TRANSACTIONS FOR EACH SESSION:\n"); 04314 04315 /* First print info on non-active transactions */ 04316 04317 trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list); 04318 04319 while (trx) { 04320 if (trx->conc_state == TRX_NOT_STARTED) { 04321 fputs("---", file); 04322 trx_print(file, trx, 600); 04323 } 04324 04325 trx = UT_LIST_GET_NEXT(mysql_trx_list, trx); 04326 } 04327 04328 loop: 04329 trx = UT_LIST_GET_FIRST(trx_sys->trx_list); 04330 04331 i = 0; 04332 04333 /* Since we temporarily release the kernel mutex when 04334 reading a database page in below, variable trx may be 04335 obsolete now and we must loop through the trx list to 04336 get probably the same trx, or some other trx. */ 04337 04338 while (trx && (i < nth_trx)) { 04339 trx = UT_LIST_GET_NEXT(trx_list, trx); 04340 i++; 04341 } 04342 04343 if (trx == NULL) { 04344 lock_mutex_exit_kernel(); 04345 innobase_mysql_end_print_arbitrary_thd(); 04346 04347 ut_ad(lock_validate()); 04348 04349 return; 04350 } 04351 04352 if (nth_lock == 0) { 04353 fputs("---", file); 04354 trx_print(file, trx, 600); 04355 04356 if (trx->read_view) { 04357 fprintf(file, 04358 "Trx read view will not see trx with id >= %lu %lu, sees < %lu %lu\n", 04359 (ulong) ut_dulint_get_high(trx->read_view->low_limit_id), 04360 (ulong) ut_dulint_get_low(trx->read_view->low_limit_id), 04361 (ulong) ut_dulint_get_high(trx->read_view->up_limit_id), 04362 (ulong) ut_dulint_get_low(trx->read_view->up_limit_id)); 04363 } 04364 04365 fprintf(file, 04366 "Trx has approximately %lu row locks\n", 04367 (ulong) lock_number_of_rows_locked(trx)); 04368 04369 if (trx->que_state == TRX_QUE_LOCK_WAIT) { 04370 fprintf(file, 04371 "------- TRX HAS BEEN WAITING %lu SEC FOR THIS LOCK TO BE GRANTED:\n", 04372 (ulong)difftime(time(NULL), trx->wait_started)); 04373 04374 if (lock_get_type(trx->wait_lock) == LOCK_REC) { 04375 lock_rec_print(file, trx->wait_lock); 04376 } else { 04377 lock_table_print(file, trx->wait_lock); 04378 } 04379 04380 fputs("------------------\n", file); 04381 } 04382 } 04383 04384 if (!srv_print_innodb_lock_monitor) { 04385 nth_trx++; 04386 goto loop; 04387 } 04388 04389 i = 0; 04390 04391 /* Look at the note about the trx loop above why we loop here: 04392 lock may be an obsolete pointer now. */ 04393 04394 lock = UT_LIST_GET_FIRST(trx->trx_locks); 04395 04396 while (lock && (i < nth_lock)) { 04397 lock = UT_LIST_GET_NEXT(trx_locks, lock); 04398 i++; 04399 } 04400 04401 if (lock == NULL) { 04402 nth_trx++; 04403 nth_lock = 0; 04404 04405 goto loop; 04406 } 04407 04408 if (lock_get_type(lock) == LOCK_REC) { 04409 space = lock->un_member.rec_lock.space; 04410 page_no = lock->un_member.rec_lock.page_no; 04411 04412 if (load_page_first) { 04413 lock_mutex_exit_kernel(); 04414 innobase_mysql_end_print_arbitrary_thd(); 04415 04416 mtr_start(&mtr); 04417 04418 page = buf_page_get_with_no_latch(space, page_no, &mtr); 04419 04420 mtr_commit(&mtr); 04421 04422 load_page_first = FALSE; 04423 04424 innobase_mysql_prepare_print_arbitrary_thd(); 04425 lock_mutex_enter_kernel(); 04426 04427 goto loop; 04428 } 04429 04430 lock_rec_print(file, lock); 04431 } else { 04432 ut_ad(lock_get_type(lock) & LOCK_TABLE); 04433 04434 lock_table_print(file, lock); 04435 } 04436 04437 load_page_first = TRUE; 04438 04439 nth_lock++; 04440 04441 if (nth_lock >= 10) { 04442 fputs( 04443 "10 LOCKS PRINTED FOR THIS TRX: SUPPRESSING FURTHER PRINTS\n", 04444 file); 04445 04446 nth_trx++; 04447 nth_lock = 0; 04448 04449 goto loop; 04450 } 04451 04452 goto loop; 04453 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_print_info_summary | ( | FILE * | file | ) |
Definition at line 4250 of file lock0lock.c.
References innobase_mysql_prepare_print_arbitrary_thd(), lock_deadlock_found, lock_get_n_rec_locks(), lock_latest_err_file, lock_mutex_enter_kernel, trx_sys_struct::max_trx_id, purge_sys, trx_purge_struct::purge_trx_no, trx_purge_struct::purge_undo_no, trx_sys_struct::rseg_history_len, trx_sys, ut_copy_file(), ut_dulint_get_high(), and ut_dulint_get_low().
Referenced by srv_printf_innodb_monitor().
04252 : file where to print */ 04253 { 04254 /* We must protect the MySQL thd->query field with a MySQL mutex, and 04255 because the MySQL mutex must be reserved before the kernel_mutex of 04256 InnoDB, we call innobase_mysql_prepare_print_arbitrary_thd() here. */ 04257 04258 innobase_mysql_prepare_print_arbitrary_thd(); 04259 lock_mutex_enter_kernel(); 04260 04261 if (lock_deadlock_found) { 04262 fputs( 04263 "------------------------\n" 04264 "LATEST DETECTED DEADLOCK\n" 04265 "------------------------\n", file); 04266 04267 ut_copy_file(file, lock_latest_err_file); 04268 } 04269 04270 fputs( 04271 "------------\n" 04272 "TRANSACTIONS\n" 04273 "------------\n", file); 04274 04275 fprintf(file, "Trx id counter %lu %lu\n", 04276 (ulong) ut_dulint_get_high(trx_sys->max_trx_id), 04277 (ulong) ut_dulint_get_low(trx_sys->max_trx_id)); 04278 04279 fprintf(file, 04280 "Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n", 04281 (ulong) ut_dulint_get_high(purge_sys->purge_trx_no), 04282 (ulong) ut_dulint_get_low(purge_sys->purge_trx_no), 04283 (ulong) ut_dulint_get_high(purge_sys->purge_undo_no), 04284 (ulong) ut_dulint_get_low(purge_sys->purge_undo_no)); 04285 04286 fprintf(file, 04287 "History list length %lu\n", (ulong) trx_sys->rseg_history_len); 04288 04289 fprintf(file, 04290 "Total number of lock structs in row lock hash table %lu\n", 04291 (ulong) lock_get_n_rec_locks()); 04292 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1224 of file lock0lock.c.
References FALSE, kernel_mutex, lock_rec_get_first_on_page_addr(), mutex_enter, mutex_exit(), and TRUE.
Referenced by ibuf_insert_low().
01226 : TRUE if there are explicit record locks on 01227 the page */ 01228 ulint space, /* in: space id */ 01229 ulint page_no)/* in: page number */ 01230 { 01231 ibool ret; 01232 01233 mutex_enter(&kernel_mutex); 01234 01235 if (lock_rec_get_first_on_page_addr(space, page_no)) { 01236 ret = TRUE; 01237 } else { 01238 ret = FALSE; 01239 } 01240 01241 mutex_exit(&kernel_mutex); 01242 01243 return(ret); 01244 }
Here is the call graph for this function:

Here is the caller graph for this function:

Referenced by lock_rec_create(), lock_rec_dequeue_from_page(), and lock_rec_discard().
Here is the caller graph for this function:

Referenced by buf_page_init(), and lock_rec_get_first_on_page_addr().
Here is the caller graph for this function:

Definition at line 2464 of file lock0lock.c.
References kernel_mutex, lock, LOCK_GAP, lock_get_mode(), LOCK_REC, lock_rec_add_to_queue(), lock_rec_get_first(), lock_rec_get_insert_intention(), lock_rec_get_next(), LOCK_X, NULL, srv_locks_unsafe_for_binlog, TRX_ISO_READ_COMMITTED, and ut_ad.
Referenced by lock_rec_reset_and_inherit_gap_locks(), lock_update_delete(), lock_update_discard(), lock_update_merge_left(), lock_update_merge_right(), lock_update_split_left(), and lock_update_split_right().
02466 : record which inherits */ 02467 rec_t* rec) /* in: record from which inherited; does NOT reset 02468 the locks on this record */ 02469 { 02470 lock_t* lock; 02471 #ifdef UNIV_SYNC_DEBUG 02472 ut_ad(mutex_own(&kernel_mutex)); 02473 #endif /* UNIV_SYNC_DEBUG */ 02474 02475 lock = lock_rec_get_first(rec); 02476 02477 /* If srv_locks_unsafe_for_binlog is TRUE or session is using 02478 READ COMMITTED isolation level, we do not want locks set 02479 by an UPDATE or a DELETE to be inherited as gap type locks. But we 02480 DO want S-locks set by a consistency constraint to be inherited also 02481 then. */ 02482 02483 while (lock != NULL) { 02484 if (!lock_rec_get_insert_intention(lock) 02485 && !((srv_locks_unsafe_for_binlog 02486 || lock->trx->isolation_level == 02487 TRX_ISO_READ_COMMITTED) 02488 && lock_get_mode(lock) == LOCK_X)) { 02489 02490 lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock) 02491 | LOCK_GAP, 02492 heir, lock->index, lock->trx); 02493 } 02494 02495 lock = lock_rec_get_next(rec, lock); 02496 } 02497 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_rec_insert_check_and_lock | ( | ulint | flags, | |
| rec_t * | rec, | |||
| dict_index_t * | index, | |||
| que_thr_t * | thr, | |||
| ibool * | inherit | |||
| ) |
Definition at line 4794 of file lock0lock.c.
References BTR_NO_LOCKING_FLAG, buf_frame_align(), DB_SUCCESS, DICT_CLUSTERED, err, FALSE, index(), lock, LOCK_GAP, LOCK_INSERT_INTENTION, LOCK_IX, lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_enqueue_waiting(), lock_rec_get_first(), lock_rec_other_has_conflicting(), lock_rec_queue_validate(), lock_table_has(), LOCK_X, mem_heap_free, NULL, page_rec_get_next(), page_update_max_trx_id(), rec_get_offsets, REC_OFFS_NORMAL_SIZE, thr_get_trx(), TRUE, and ut_ad.
Referenced by btr_cur_ins_lock_and_undo().
04796 : DB_SUCCESS, DB_LOCK_WAIT, 04797 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 04798 ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, 04799 does nothing */ 04800 rec_t* rec, /* in: record after which to insert */ 04801 dict_index_t* index, /* in: index */ 04802 que_thr_t* thr, /* in: query thread */ 04803 ibool* inherit)/* out: set to TRUE if the new inserted 04804 record maybe should inherit LOCK_GAP type 04805 locks from the successor record */ 04806 { 04807 rec_t* next_rec; 04808 trx_t* trx; 04809 lock_t* lock; 04810 ulint err; 04811 04812 if (flags & BTR_NO_LOCKING_FLAG) { 04813 04814 return(DB_SUCCESS); 04815 } 04816 04817 ut_ad(rec); 04818 04819 trx = thr_get_trx(thr); 04820 next_rec = page_rec_get_next(rec); 04821 04822 *inherit = FALSE; 04823 04824 lock_mutex_enter_kernel(); 04825 04826 ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); 04827 04828 lock = lock_rec_get_first(next_rec); 04829 04830 if (lock == NULL) { 04831 /* We optimize CPU time usage in the simplest case */ 04832 04833 lock_mutex_exit_kernel(); 04834 04835 if (!(index->type & DICT_CLUSTERED)) { 04836 04837 /* Update the page max trx id field */ 04838 page_update_max_trx_id(buf_frame_align(rec), 04839 thr_get_trx(thr)->id); 04840 } 04841 04842 return(DB_SUCCESS); 04843 } 04844 04845 *inherit = TRUE; 04846 04847 /* If another transaction has an explicit lock request which locks 04848 the gap, waiting or granted, on the successor, the insert has to wait. 04849 04850 An exception is the case where the lock by the another transaction 04851 is a gap type lock which it placed to wait for its turn to insert. We 04852 do not consider that kind of a lock conflicting with our insert. This 04853 eliminates an unnecessary deadlock which resulted when 2 transactions 04854 had to wait for their insert. Both had waiting gap type lock requests 04855 on the successor, which produced an unnecessary deadlock. */ 04856 04857 if (lock_rec_other_has_conflicting(LOCK_X | LOCK_GAP 04858 | LOCK_INSERT_INTENTION, next_rec, trx)) { 04859 04860 /* Note that we may get DB_SUCCESS also here! */ 04861 err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP 04862 | LOCK_INSERT_INTENTION, 04863 next_rec, index, thr); 04864 } else { 04865 err = DB_SUCCESS; 04866 } 04867 04868 lock_mutex_exit_kernel(); 04869 04870 if (!(index->type & DICT_CLUSTERED) && (err == DB_SUCCESS)) { 04871 04872 /* Update the page max trx id field */ 04873 page_update_max_trx_id(buf_frame_align(rec), 04874 thr_get_trx(thr)->id); 04875 } 04876 04877 #ifdef UNIV_DEBUG 04878 { 04879 mem_heap_t* heap = NULL; 04880 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 04881 const ulint* offsets; 04882 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 04883 04884 offsets = rec_get_offsets(next_rec, index, offsets_, 04885 ULINT_UNDEFINED, &heap); 04886 ut_ad(lock_rec_queue_validate(next_rec, index, offsets)); 04887 if (UNIV_LIKELY_NULL(heap)) { 04888 mem_heap_free(heap); 04889 } 04890 } 04891 #endif /* UNIV_DEBUG */ 04892 04893 return(err); 04894 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_rec_print | ( | FILE * | file, | |
| lock_t * | lock | |||
| ) |
Definition at line 4107 of file lock0lock.c.
References BUF_GET_IF_IN_POOL, buf_page_get_gen(), buf_page_get_nowait, dict_index_name_print(), kernel_mutex, lock, lock_get_mode(), lock_get_type(), lock_get_wait(), LOCK_REC, lock_rec_get_gap(), lock_rec_get_insert_intention(), lock_rec_get_n_bits(), lock_rec_get_nth_bit(), lock_rec_get_rec_not_gap(), LOCK_S, LOCK_X, mem_heap_free, mtr_commit(), mtr_start(), NULL, page, page_find_rec_with_heap_no(), page_t, rec_get_offsets, REC_OFFS_NORMAL_SIZE, rec_print_new(), RW_NO_LATCH, RW_S_LATCH, RW_X_LATCH, SYNC_NO_ORDER_CHECK, ut_a, ut_ad, and ut_error.
Referenced by lock_deadlock_recursive(), and lock_print_info_all_transactions().
04109 : file where to print */ 04110 lock_t* lock) /* in: record type lock */ 04111 { 04112 page_t* page; 04113 ulint space; 04114 ulint page_no; 04115 ulint i; 04116 mtr_t mtr; 04117 mem_heap_t* heap = NULL; 04118 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 04119 ulint* offsets = offsets_; 04120 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 04121 04122 #ifdef UNIV_SYNC_DEBUG 04123 ut_ad(mutex_own(&kernel_mutex)); 04124 #endif /* UNIV_SYNC_DEBUG */ 04125 ut_a(lock_get_type(lock) == LOCK_REC); 04126 04127 space = lock->un_member.rec_lock.space; 04128 page_no = lock->un_member.rec_lock.page_no; 04129 04130 fprintf(file, "RECORD LOCKS space id %lu page no %lu n bits %lu ", 04131 (ulong) space, (ulong) page_no, 04132 (ulong) lock_rec_get_n_bits(lock)); 04133 dict_index_name_print(file, lock->trx, lock->index); 04134 fprintf(file, " trx id %lu %lu", 04135 (ulong) (lock->trx)->id.high, 04136 (ulong) (lock->trx)->id.low); 04137 04138 if (lock_get_mode(lock) == LOCK_S) { 04139 fputs(" lock mode S", file); 04140 } else if (lock_get_mode(lock) == LOCK_X) { 04141 fputs(" lock_mode X", file); 04142 } else { 04143 ut_error; 04144 } 04145 04146 if (lock_rec_get_gap(lock)) { 04147 fputs(" locks gap before rec", file); 04148 } 04149 04150 if (lock_rec_get_rec_not_gap(lock)) { 04151 fputs(" locks rec but not gap", file); 04152 } 04153 04154 if (lock_rec_get_insert_intention(lock)) { 04155 fputs(" insert intention", file); 04156 } 04157 04158 if (lock_get_wait(lock)) { 04159 fputs(" waiting", file); 04160 } 04161 04162 mtr_start(&mtr); 04163 04164 putc('\n', file); 04165 04166 /* If the page is not in the buffer pool, we cannot load it 04167 because we have the kernel mutex and ibuf operations would 04168 break the latching order */ 04169 04170 page = buf_page_get_gen(space, page_no, RW_NO_LATCH, 04171 NULL, BUF_GET_IF_IN_POOL, 04172 __FILE__, __LINE__, &mtr); 04173 if (page) { 04174 page = buf_page_get_nowait(space, page_no, RW_S_LATCH, &mtr); 04175 04176 if (!page) { 04177 /* Let us try to get an X-latch. If the current thread 04178 is holding an X-latch on the page, we cannot get an 04179 S-latch. */ 04180 04181 page = buf_page_get_nowait(space, page_no, RW_X_LATCH, 04182 &mtr); 04183 } 04184 } 04185 04186 if (page) { 04187 #ifdef UNIV_SYNC_DEBUG 04188 buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK); 04189 #endif /* UNIV_SYNC_DEBUG */ 04190 } 04191 04192 for (i = 0; i < lock_rec_get_n_bits(lock); i++) { 04193 04194 if (lock_rec_get_nth_bit(lock, i)) { 04195 04196 fprintf(file, "Record lock, heap no %lu ", (ulong) i); 04197 04198 if (page) { 04199 rec_t* rec 04200 = page_find_rec_with_heap_no(page, i); 04201 offsets = rec_get_offsets(rec, lock->index, 04202 offsets, ULINT_UNDEFINED, &heap); 04203 rec_print_new(file, rec, offsets); 04204 } 04205 04206 putc('\n', file); 04207 } 04208 } 04209 04210 mtr_commit(&mtr); 04211 if (UNIV_LIKELY_NULL(heap)) { 04212 mem_heap_free(heap); 04213 } 04214 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool lock_rec_queue_validate | ( | rec_t * | rec, | |
| dict_index_t * | index, | |||
| const ulint * | offsets | |||
| ) |
Definition at line 4502 of file lock0lock.c.
References DICT_CLUSTERED, index(), lock, lock_clust_rec_some_has_impl(), lock_get_mode(), lock_get_wait(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_get_first(), lock_rec_get_gap(), lock_rec_get_next(), lock_rec_has_expl(), lock_rec_has_to_wait_in_queue(), LOCK_REC_NOT_GAP, lock_rec_other_has_expl_req(), LOCK_S, lock_sec_rec_some_has_impl_off_kernel(), LOCK_WAIT, LOCK_X, page_rec_is_comp(), page_rec_is_user_rec(), rec_offs_comp(), rec_offs_validate(), TRUE, TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, trx_in_trx_list(), TRX_PREPARED, ut_a, and ut_ad.
Referenced by lock_clust_rec_modify_check_and_lock(), lock_clust_rec_read_check_and_lock(), lock_rec_insert_check_and_lock(), lock_rec_validate_page(), lock_sec_rec_modify_check_and_lock(), and lock_sec_rec_read_check_and_lock().
04504 : TRUE if ok */ 04505 rec_t* rec, /* in: record to look at */ 04506 dict_index_t* index, /* in: index, or NULL if not known */ 04507 const ulint* offsets)/* in: rec_get_offsets(rec, index) */ 04508 { 04509 trx_t* impl_trx; 04510 lock_t* lock; 04511 04512 ut_a(rec); 04513 ut_ad(rec_offs_validate(rec, index, offsets)); 04514 ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets)); 04515 04516 lock_mutex_enter_kernel(); 04517 04518 if (!page_rec_is_user_rec(rec)) { 04519 04520 lock = lock_rec_get_first(rec); 04521 04522 while (lock) { 04523 ut_a(lock->trx->conc_state == TRX_ACTIVE 04524 || lock->trx->conc_state == TRX_PREPARED 04525 || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); 04526 04527 ut_a(trx_in_trx_list(lock->trx)); 04528 04529 if (lock_get_wait(lock)) { 04530 ut_a(lock_rec_has_to_wait_in_queue(lock)); 04531 } 04532 04533 if (index) { 04534 ut_a(lock->index == index); 04535 } 04536 04537 lock = lock_rec_get_next(rec, lock); 04538 } 04539 04540 lock_mutex_exit_kernel(); 04541 04542 return(TRUE); 04543 } 04544 04545 if (index && (index->type & DICT_CLUSTERED)) { 04546 04547 impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets); 04548 04549 if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0, 04550 LOCK_WAIT, rec, impl_trx)) { 04551 04552 ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec, 04553 impl_trx)); 04554 } 04555 } 04556 04557 if (index && !(index->type & DICT_CLUSTERED)) { 04558 04559 /* The kernel mutex may get released temporarily in the 04560 next function call: we have to release lock table mutex 04561 to obey the latching order */ 04562 04563 impl_trx = lock_sec_rec_some_has_impl_off_kernel( 04564 rec, index, offsets); 04565 04566 if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0, 04567 LOCK_WAIT, rec, impl_trx)) { 04568 04569 ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, 04570 rec, impl_trx)); 04571 } 04572 } 04573 04574 lock = lock_rec_get_first(rec); 04575 04576 while (lock) { 04577 ut_a(lock->trx->conc_state == TRX_ACTIVE 04578 || lock->trx->conc_state == TRX_PREPARED 04579 || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); 04580 ut_a(trx_in_trx_list(lock->trx)); 04581 04582 if (index) { 04583 ut_a(lock->index == index); 04584 } 04585 04586 if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) { 04587 04588 ulint mode; 04589 04590 if (lock_get_mode(lock) == LOCK_S) { 04591 mode = LOCK_X; 04592 } else { 04593 mode = LOCK_S; 04594 } 04595 ut_a(!lock_rec_other_has_expl_req(mode, 04596 0, 0, rec, lock->trx)); 04597 04598 } else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) { 04599 04600 ut_a(lock_rec_has_to_wait_in_queue(lock)); 04601 } 04602 04603 lock = lock_rec_get_next(rec, lock); 04604 } 04605 04606 lock_mutex_exit_kernel(); 04607 04608 return(TRUE); 04609 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3044 of file lock0lock.c.
References kernel_mutex, lock_rec_inherit_to_gap(), lock_rec_reset_and_release_wait(), mutex_enter, and mutex_exit().
Referenced by btr_cur_pess_upd_restore_supremum().
03046 : heir record */ 03047 rec_t* rec) /* in: record */ 03048 { 03049 mutex_enter(&kernel_mutex); 03050 03051 lock_rec_reset_and_release_wait(heir); 03052 03053 lock_rec_inherit_to_gap(heir, rec); 03054 03055 mutex_exit(&kernel_mutex); 03056 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3173 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_move(), page_get_infimum_rec(), page_is_comp(), page_rec_is_comp(), and ut_ad.
Referenced by btr_cur_optimistic_update(), and btr_cur_pessimistic_update().
03175 : record whose lock state is restored */ 03176 page_t* page) /* in: page (rec is not necessarily on this page) 03177 whose infimum stored the lock state; lock bits are 03178 reset on the infimum */ 03179 { 03180 ulint comp; 03181 lock_mutex_enter_kernel(); 03182 comp = page_is_comp(page); 03183 ut_ad(!comp == !page_rec_is_comp(rec)); 03184 03185 lock_rec_move(rec, page_get_infimum_rec(page), comp); 03186 03187 lock_mutex_exit_kernel(); 03188 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3152 of file lock0lock.c.
References buf_frame_align(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_move(), page_get_infimum_rec(), page_is_comp(), and ut_ad.
Referenced by btr_cur_optimistic_update(), and btr_cur_pessimistic_update().
03154 : page containing the record */ 03155 rec_t* rec) /* in: record whose lock state is stored 03156 on the infimum record of the same page; lock 03157 bits are reset on the record */ 03158 { 03159 ut_ad(page == buf_frame_align(rec)); 03160 03161 lock_mutex_enter_kernel(); 03162 03163 lock_rec_move(page_get_infimum_rec(page), rec, page_is_comp(page)); 03164 03165 lock_mutex_exit_kernel(); 03166 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3800 of file lock0lock.c.
References kernel_mutex, lock, lock_get_mode(), lock_get_wait(), lock_grant(), lock_rec_get_first(), lock_rec_get_next(), lock_rec_has_to_wait_in_queue(), lock_rec_reset_nth_bit(), mutex_enter, mutex_exit(), NULL, page_rec_is_comp(), rec_get_heap_no(), ut_a, ut_ad, and ut_print_timestamp().
Referenced by row_unlock_for_mysql().
03802 : transaction that has set a record 03803 lock */ 03804 rec_t* rec, /* in: record */ 03805 ulint lock_mode) /* in: LOCK_S or LOCK_X */ 03806 { 03807 lock_t* lock; 03808 lock_t* release_lock = NULL; 03809 ulint heap_no; 03810 03811 ut_ad(trx && rec); 03812 03813 mutex_enter(&kernel_mutex); 03814 03815 heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec)); 03816 03817 lock = lock_rec_get_first(rec); 03818 03819 /* Find the last lock with the same lock_mode and transaction 03820 from the record. */ 03821 03822 while (lock != NULL) { 03823 if (lock->trx == trx && lock_get_mode(lock) == lock_mode) { 03824 release_lock = lock; 03825 ut_a(!lock_get_wait(lock)); 03826 } 03827 03828 lock = lock_rec_get_next(rec, lock); 03829 } 03830 03831 /* If a record lock is found, release the record lock */ 03832 03833 if (UNIV_LIKELY(release_lock != NULL)) { 03834 lock_rec_reset_nth_bit(release_lock, heap_no); 03835 } else { 03836 mutex_exit(&kernel_mutex); 03837 ut_print_timestamp(stderr); 03838 fprintf(stderr, 03839 " InnoDB: Error: unlock row could not find a %lu mode lock on the record\n", 03840 (ulong)lock_mode); 03841 03842 return; 03843 } 03844 03845 /* Check if we can now grant waiting lock requests */ 03846 03847 lock = lock_rec_get_first(rec); 03848 03849 while (lock != NULL) { 03850 if (lock_get_wait(lock) 03851 && !lock_rec_has_to_wait_in_queue(lock)) { 03852 03853 /* Grant the lock */ 03854 lock_grant(lock); 03855 } 03856 03857 lock = lock_rec_get_next(rec, lock); 03858 } 03859 03860 mutex_exit(&kernel_mutex); 03861 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4615 of file lock0lock.c.
References buf_page_get, index(), kernel_mutex, lock, lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_get_first_on_page_addr(), lock_rec_get_n_bits(), lock_rec_get_next_on_page(), lock_rec_get_nth_bit(), lock_rec_queue_validate(), mem_heap_free, mtr_commit(), mtr_start(), NULL, page, page_find_rec_with_heap_no(), page_t, rec_get_offsets, REC_OFFS_NORMAL_SIZE, RW_X_LATCH, SYNC_NO_ORDER_CHECK, TRUE, TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, trx_in_trx_list(), TRX_PREPARED, ut_a, and ut_ad.
Referenced by lock_validate().
04617 : TRUE if ok */ 04618 ulint space, /* in: space id */ 04619 ulint page_no)/* in: page number */ 04620 { 04621 dict_index_t* index; 04622 page_t* page; 04623 lock_t* lock; 04624 rec_t* rec; 04625 ulint nth_lock = 0; 04626 ulint nth_bit = 0; 04627 ulint i; 04628 mtr_t mtr; 04629 mem_heap_t* heap = NULL; 04630 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 04631 ulint* offsets = offsets_; 04632 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 04633 04634 #ifdef UNIV_SYNC_DEBUG 04635 ut_ad(!mutex_own(&kernel_mutex)); 04636 #endif /* UNIV_SYNC_DEBUG */ 04637 04638 mtr_start(&mtr); 04639 04640 page = buf_page_get(space, page_no, RW_X_LATCH, &mtr); 04641 #ifdef UNIV_SYNC_DEBUG 04642 buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK); 04643 #endif /* UNIV_SYNC_DEBUG */ 04644 04645 lock_mutex_enter_kernel(); 04646 loop: 04647 lock = lock_rec_get_first_on_page_addr(space, page_no); 04648 04649 if (!lock) { 04650 goto function_exit; 04651 } 04652 04653 for (i = 0; i < nth_lock; i++) { 04654 04655 lock = lock_rec_get_next_on_page(lock); 04656 04657 if (!lock) { 04658 goto function_exit; 04659 } 04660 } 04661 04662 ut_a(trx_in_trx_list(lock->trx)); 04663 ut_a(lock->trx->conc_state == TRX_ACTIVE 04664 || lock->trx->conc_state == TRX_PREPARED 04665 || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); 04666 04667 for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) { 04668 04669 if (i == 1 || lock_rec_get_nth_bit(lock, i)) { 04670 04671 index = lock->index; 04672 rec = page_find_rec_with_heap_no(page, i); 04673 offsets = rec_get_offsets(rec, index, offsets, 04674 ULINT_UNDEFINED, &heap); 04675 04676 fprintf(stderr, 04677 "Validating %lu %lu\n", (ulong) space, (ulong) page_no); 04678 04679 lock_mutex_exit_kernel(); 04680 04681 lock_rec_queue_validate(rec, index, offsets); 04682 04683 lock_mutex_enter_kernel(); 04684 04685 nth_bit = i + 1; 04686 04687 goto loop; 04688 } 04689 } 04690 04691 nth_bit = 0; 04692 nth_lock++; 04693 04694 goto loop; 04695 04696 function_exit: 04697 lock_mutex_exit_kernel(); 04698 04699 mtr_commit(&mtr); 04700 04701 if (UNIV_LIKELY_NULL(heap)) { 04702 mem_heap_free(heap); 04703 } 04704 return(TRUE); 04705 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_release_off_kernel | ( | trx_t * | trx | ) |
Definition at line 3902 of file lock0lock.c.
References trx_struct::auto_inc_lock, count, kernel_mutex, lock, lock_get_mode(), lock_get_type(), trx_struct::lock_heap, LOCK_IS, lock_mutex_enter_kernel, lock_mutex_exit_kernel, LOCK_REC, lock_rec_dequeue_from_page(), LOCK_RELEASE_KERNEL_INTERVAL, LOCK_TABLE, lock_table_dequeue(), trx_sys_struct::max_trx_id, mem_heap_empty(), NULL, dict_table_struct::query_cache_inv_trx_id, trx_struct::trx_locks, trx_sys, trx_struct::undo_no, ut_a, ut_ad, ut_dulint_cmp(), ut_dulint_zero, and UT_LIST_GET_LAST.
Referenced by trx_commit_off_kernel().
03904 : transaction */ 03905 { 03906 dict_table_t* table; 03907 ulint count; 03908 lock_t* lock; 03909 03910 #ifdef UNIV_SYNC_DEBUG 03911 ut_ad(mutex_own(&kernel_mutex)); 03912 #endif /* UNIV_SYNC_DEBUG */ 03913 03914 lock = UT_LIST_GET_LAST(trx->trx_locks); 03915 03916 count = 0; 03917 03918 while (lock != NULL) { 03919 03920 count++; 03921 03922 if (lock_get_type(lock) == LOCK_REC) { 03923 03924 lock_rec_dequeue_from_page(lock); 03925 } else { 03926 ut_ad(lock_get_type(lock) & LOCK_TABLE); 03927 03928 if (lock_get_mode(lock) != LOCK_IS 03929 && 0 != ut_dulint_cmp(trx->undo_no, 03930 ut_dulint_zero)) { 03931 03932 /* The trx may have modified the table. We 03933 block the use of the MySQL query cache for 03934 all currently active transactions. */ 03935 03936 table = lock->un_member.tab_lock.table; 03937 03938 table->query_cache_inv_trx_id = 03939 trx_sys->max_trx_id; 03940 } 03941 03942 lock_table_dequeue(lock); 03943 } 03944 03945 if (count == LOCK_RELEASE_KERNEL_INTERVAL) { 03946 /* Release the kernel mutex for a while, so that we 03947 do not monopolize it */ 03948 03949 lock_mutex_exit_kernel(); 03950 03951 lock_mutex_enter_kernel(); 03952 03953 count = 0; 03954 } 03955 03956 lock = UT_LIST_GET_LAST(trx->trx_locks); 03957 } 03958 03959 mem_heap_empty(trx->lock_heap); 03960 03961 ut_a(trx->auto_inc_lock == NULL); 03962 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_reset_all_on_table | ( | dict_table_t * | table | ) |
Definition at line 4039 of file lock0lock.c.
References kernel_mutex, lock, lock_get_wait(), lock_reset_all_on_table_for_trx(), dict_table_struct::locks, mutex_enter, mutex_exit(), ut_a, and UT_LIST_GET_FIRST.
Referenced by row_discard_tablespace_for_mysql(), row_drop_table_for_mysql(), and row_truncate_table_for_mysql().
04041 : table to be dropped */ 04042 { 04043 lock_t* lock; 04044 04045 mutex_enter(&kernel_mutex); 04046 04047 lock = UT_LIST_GET_FIRST(table->locks); 04048 04049 while (lock) { 04050 ut_a(!lock_get_wait(lock)); 04051 04052 lock_reset_all_on_table_for_trx(table, lock->trx); 04053 04054 lock = UT_LIST_GET_FIRST(table->locks); 04055 } 04056 04057 mutex_exit(&kernel_mutex); 04058 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_sec_rec_cons_read_sees | ( | rec_t * | rec, | |
| dict_index_t * | index, | |||
| read_view_t * | view | |||
| ) |
Definition at line 536 of file lock0lock.c.
References buf_frame_align(), DICT_CLUSTERED, FALSE, index(), page_get_max_trx_id(), page_rec_is_user_rec(), recv_recovery_is_on(), TRUE, read_view_struct::up_limit_id, ut_ad, ut_dulint_cmp(), and UT_NOT_USED.
Referenced by row_search_for_mysql(), row_sel(), and row_sel_try_search_shortcut().
00538 : TRUE if certainly sees, or FALSE if an 00539 earlier version of the clustered index record 00540 might be needed: NOTE that a non-clustered 00541 index page contains so little information on 00542 its modifications that also in the case FALSE, 00543 the present version of rec may be the right, 00544 but we must check this from the clustered 00545 index record */ 00546 rec_t* rec, /* in: user record which should be read or 00547 passed over by a read cursor */ 00548 dict_index_t* index, /* in: non-clustered index */ 00549 read_view_t* view) /* in: consistent read view */ 00550 { 00551 dulint max_trx_id; 00552 00553 UT_NOT_USED(index); 00554 00555 ut_ad(!(index->type & DICT_CLUSTERED)); 00556 ut_ad(page_rec_is_user_rec(rec)); 00557 00558 /* NOTE that we might call this function while holding the search 00559 system latch. To obey the latching order we must NOT reserve the 00560 kernel mutex here! */ 00561 00562 if (recv_recovery_is_on()) { 00563 00564 return(FALSE); 00565 } 00566 00567 max_trx_id = page_get_max_trx_id(buf_frame_align(rec)); 00568 00569 if (ut_dulint_cmp(max_trx_id, view->up_limit_id) >= 0) { 00570 00571 return(FALSE); 00572 } 00573 00574 return(TRUE); 00575 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_sec_rec_modify_check_and_lock | ( | ulint | flags, | |
| rec_t * | rec, | |||
| dict_index_t * | index, | |||
| que_thr_t * | thr | |||
| ) |
Definition at line 4990 of file lock0lock.c.
References BTR_NO_LOCKING_FLAG, buf_frame_align(), DB_SUCCESS, DICT_CLUSTERED, err, index(), LOCK_IX, lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_lock(), LOCK_REC_NOT_GAP, lock_rec_queue_validate(), lock_table_has(), LOCK_X, mem_heap_free, NULL, page_update_max_trx_id(), rec_get_offsets, REC_OFFS_NORMAL_SIZE, thr_get_trx(), TRUE, and ut_ad.
Referenced by btr_cur_del_mark_set_sec_rec(), and btr_cur_upd_lock_and_undo().
04992 : DB_SUCCESS, DB_LOCK_WAIT, 04993 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 04994 ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, 04995 does nothing */ 04996 rec_t* rec, /* in: record which should be modified; 04997 NOTE: as this is a secondary index, we 04998 always have to modify the clustered index 04999 record first: see the comment below */ 05000 dict_index_t* index, /* in: secondary index */ 05001 que_thr_t* thr) /* in: query thread */ 05002 { 05003 ulint err; 05004 05005 if (flags & BTR_NO_LOCKING_FLAG) { 05006 05007 return(DB_SUCCESS); 05008 } 05009 05010 ut_ad(!(index->type & DICT_CLUSTERED)); 05011 05012 /* Another transaction cannot have an implicit lock on the record, 05013 because when we come here, we already have modified the clustered 05014 index record, and this would not have been possible if another active 05015 transaction had modified this secondary index record. */ 05016 05017 lock_mutex_enter_kernel(); 05018 05019 ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); 05020 05021 err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP, rec, index, thr); 05022 05023 lock_mutex_exit_kernel(); 05024 05025 #ifdef UNIV_DEBUG 05026 { 05027 mem_heap_t* heap = NULL; 05028 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 05029 const ulint* offsets; 05030 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 05031 05032 offsets = rec_get_offsets(rec, index, offsets_, 05033 ULINT_UNDEFINED, &heap); 05034 ut_ad(lock_rec_queue_validate(rec, index, offsets)); 05035 if (UNIV_LIKELY_NULL(heap)) { 05036 mem_heap_free(heap); 05037 } 05038 } 05039 #endif /* UNIV_DEBUG */ 05040 05041 if (err == DB_SUCCESS) { 05042 /* Update the page max trx id field */ 05043 05044 page_update_max_trx_id(buf_frame_align(rec), 05045 thr_get_trx(thr)->id); 05046 } 05047 05048 return(err); 05049 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_sec_rec_read_check_and_lock | ( | ulint | flags, | |
| rec_t * | rec, | |||
| dict_index_t * | index, | |||
| const ulint * | offsets, | |||
| ulint | mode, | |||
| ulint | gap_mode, | |||
| que_thr_t * | thr | |||
| ) |
Definition at line 5056 of file lock0lock.c.
References BTR_NO_LOCKING_FLAG, buf_frame_align(), DB_SUCCESS, DICT_CLUSTERED, err, FALSE, index(), LOCK_IS, LOCK_IX, lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_convert_impl_to_expl(), lock_rec_lock(), lock_rec_queue_validate(), LOCK_S, lock_table_has(), LOCK_X, page_get_max_trx_id(), page_rec_is_supremum(), page_rec_is_user_rec(), rec_offs_validate(), recv_recovery_is_on(), thr_get_trx(), trx_list_get_min_trx_id(), ut_ad, and ut_dulint_cmp().
Referenced by row_ins_set_exclusive_rec_lock(), row_ins_set_shared_rec_lock(), and sel_set_rec_lock().
05058 : DB_SUCCESS, DB_LOCK_WAIT, 05059 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 05060 ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, 05061 does nothing */ 05062 rec_t* rec, /* in: user record or page supremum record 05063 which should be read or passed over by a read 05064 cursor */ 05065 dict_index_t* index, /* in: secondary index */ 05066 const ulint* offsets,/* in: rec_get_offsets(rec, index) */ 05067 ulint mode, /* in: mode of the lock which the read cursor 05068 should set on records: LOCK_S or LOCK_X; the 05069 latter is possible in SELECT FOR UPDATE */ 05070 ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or 05071 LOCK_REC_NOT_GAP */ 05072 que_thr_t* thr) /* in: query thread */ 05073 { 05074 ulint err; 05075 05076 ut_ad(!(index->type & DICT_CLUSTERED)); 05077 ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec)); 05078 ut_ad(rec_offs_validate(rec, index, offsets)); 05079 05080 if (flags & BTR_NO_LOCKING_FLAG) { 05081 05082 return(DB_SUCCESS); 05083 } 05084 05085 lock_mutex_enter_kernel(); 05086 05087 ut_ad(mode != LOCK_X 05088 || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); 05089 ut_ad(mode != LOCK_S 05090 || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); 05091 05092 /* Some transaction may have an implicit x-lock on the record only 05093 if the max trx id for the page >= min trx id for the trx list or a 05094 database recovery is running. */ 05095 05096 if (((ut_dulint_cmp(page_get_max_trx_id(buf_frame_align(rec)), 05097 trx_list_get_min_trx_id()) >= 0) 05098 || recv_recovery_is_on()) 05099 && !page_rec_is_supremum(rec)) { 05100 05101 lock_rec_convert_impl_to_expl(rec, index, offsets); 05102 } 05103 05104 err = lock_rec_lock(FALSE, mode | gap_mode, rec, index, thr); 05105 05106 lock_mutex_exit_kernel(); 05107 05108 ut_ad(lock_rec_queue_validate(rec, index, offsets)); 05109 05110 return(err); 05111 }
Here is the call graph for this function:

Here is the caller graph for this function:

| trx_t* lock_sec_rec_some_has_impl_off_kernel | ( | rec_t * | rec, | |
| dict_index_t * | index, | |||
| const ulint * | offsets | |||
| ) |
Definition at line 1654 of file lock0lock.c.
References buf_frame_align(), buf_page_print(), DICT_CLUSTERED, index(), kernel_mutex, lock_check_trx_id_sanity(), NULL, page, page_get_max_trx_id(), page_rec_is_user_rec(), page_t, rec_offs_validate(), recv_recovery_is_on(), row_vers_impl_x_locked_off_kernel(), TRUE, trx_list_get_min_trx_id(), ut_ad, and ut_dulint_cmp().
Referenced by lock_rec_convert_impl_to_expl(), and lock_rec_queue_validate().
01656 : transaction which has the x-lock, or 01657 NULL */ 01658 rec_t* rec, /* in: user record */ 01659 dict_index_t* index, /* in: secondary index */ 01660 const ulint* offsets)/* in: rec_get_offsets(rec, index) */ 01661 { 01662 page_t* page; 01663 01664 #ifdef UNIV_SYNC_DEBUG 01665 ut_ad(mutex_own(&kernel_mutex)); 01666 #endif /* UNIV_SYNC_DEBUG */ 01667 ut_ad(!(index->type & DICT_CLUSTERED)); 01668 ut_ad(page_rec_is_user_rec(rec)); 01669 ut_ad(rec_offs_validate(rec, index, offsets)); 01670 01671 page = buf_frame_align(rec); 01672 01673 /* Some transaction may have an implicit x-lock on the record only 01674 if the max trx id for the page >= min trx id for the trx list, or 01675 database recovery is running. We do not write the changes of a page 01676 max trx id to the log, and therefore during recovery, this value 01677 for a page may be incorrect. */ 01678 01679 if (!(ut_dulint_cmp(page_get_max_trx_id(page), 01680 trx_list_get_min_trx_id()) >= 0) 01681 && !recv_recovery_is_on()) { 01682 01683 return(NULL); 01684 } 01685 01686 /* Ok, in this case it is possible that some transaction has an 01687 implicit x-lock. We have to look in the clustered index. */ 01688 01689 if (!lock_check_trx_id_sanity(page_get_max_trx_id(page), 01690 rec, index, offsets, TRUE)) { 01691 buf_page_print(page); 01692 01693 /* The page is corrupt: try to avoid a crash by returning 01694 NULL */ 01695 return(NULL); 01696 } 01697 01698 return(row_vers_impl_x_locked_off_kernel(rec, index, offsets)); 01699 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_sys_create | ( | ulint | n_cells | ) |
Definition at line 581 of file lock0lock.c.
References hash_create(), lock_latest_err_file, lock_sys, mem_alloc, os_file_create_tmpfile(), lock_sys_struct::rec_hash, and ut_a.
Referenced by innobase_start_or_create_for_mysql().
00583 : number of slots in lock hash table */ 00584 { 00585 lock_sys = mem_alloc(sizeof(lock_sys_t)); 00586 00587 lock_sys->rec_hash = hash_create(n_cells); 00588 00589 /* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */ 00590 00591 lock_latest_err_file = os_file_create_tmpfile(); 00592 ut_a(lock_latest_err_file); 00593 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint lock_table | ( | ulint | flags, | |
| dict_table_t * | table, | |||
| ulint | mode, | |||
| que_thr_t * | thr | |||
| ) |
Definition at line 3637 of file lock0lock.c.
References BTR_NO_LOCKING_FLAG, DB_SUCCESS, err, lock_mutex_enter_kernel, lock_mutex_exit_kernel, LOCK_S, lock_table_create(), lock_table_enqueue_waiting(), lock_table_has(), lock_table_other_has_incompatible(), LOCK_WAIT, LOCK_X, thr_get_trx(), ut_a, and ut_ad.
03639 : DB_SUCCESS, DB_LOCK_WAIT, 03640 DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ 03641 ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, 03642 does nothing */ 03643 dict_table_t* table, /* in: database table in dictionary cache */ 03644 ulint mode, /* in: lock mode */ 03645 que_thr_t* thr) /* in: query thread */ 03646 { 03647 trx_t* trx; 03648 ulint err; 03649 03650 ut_ad(table && thr); 03651 03652 if (flags & BTR_NO_LOCKING_FLAG) { 03653 03654 return(DB_SUCCESS); 03655 } 03656 03657 ut_a(flags == 0); 03658 03659 trx = thr_get_trx(thr); 03660 03661 lock_mutex_enter_kernel(); 03662 03663 /* Look for stronger locks the same trx already has on the table */ 03664 03665 if (lock_table_has(trx, table, mode)) { 03666 03667 lock_mutex_exit_kernel(); 03668 03669 return(DB_SUCCESS); 03670 } 03671 03672 /* We have to check if the new lock is compatible with any locks 03673 other transactions have in the table lock queue. */ 03674 03675 if (lock_table_other_has_incompatible(trx, LOCK_WAIT, table, mode)) { 03676 03677 /* Another trx has a request on the table in an incompatible 03678 mode: this trx may have to wait */ 03679 03680 err = lock_table_enqueue_waiting(mode | flags, table, thr); 03681 03682 lock_mutex_exit_kernel(); 03683 03684 return(err); 03685 } 03686 03687 lock_table_create(table, mode | flags, trx); 03688 03689 ut_a(!flags || mode == LOCK_S || mode == LOCK_X); 03690 03691 lock_mutex_exit_kernel(); 03692 03693 return(DB_SUCCESS); 03694 }
Here is the call graph for this function:

| void lock_table_print | ( | FILE * | file, | |
| lock_t * | lock | |||
| ) |
Definition at line 4066 of file lock0lock.c.
References kernel_mutex, lock, LOCK_AUTO_INC, lock_get_mode(), lock_get_type(), lock_get_wait(), LOCK_IS, LOCK_IX, LOCK_S, LOCK_TABLE, LOCK_X, TRUE, ut_a, ut_ad, and ut_print_name().
Referenced by lock_deadlock_recursive(), and lock_print_info_all_transactions().
04068 : file where to print */ 04069 lock_t* lock) /* in: table type lock */ 04070 { 04071 #ifdef UNIV_SYNC_DEBUG 04072 ut_ad(mutex_own(&kernel_mutex)); 04073 #endif /* UNIV_SYNC_DEBUG */ 04074 ut_a(lock_get_type(lock) == LOCK_TABLE); 04075 04076 fputs("TABLE LOCK table ", file); 04077 ut_print_name(file, lock->trx, TRUE, 04078 lock->un_member.tab_lock.table->name); 04079 fprintf(file, " trx id %lu %lu", 04080 (ulong) (lock->trx)->id.high, (ulong) (lock->trx)->id.low); 04081 04082 if (lock_get_mode(lock) == LOCK_S) { 04083 fputs(" lock mode S", file); 04084 } else if (lock_get_mode(lock) == LOCK_X) { 04085 fputs(" lock mode X", file); 04086 } else if (lock_get_mode(lock) == LOCK_IS) { 04087 fputs(" lock mode IS", file); 04088 } else if (lock_get_mode(lock) == LOCK_IX) { 04089 fputs(" lock mode IX", file); 04090 } else if (lock_get_mode(lock) == LOCK_AUTO_INC) { 04091 fputs(" lock mode AUTO-INC", file); 04092 } else { 04093 fprintf(file, " unknown lock mode %lu", (ulong) lock_get_mode(lock)); 04094 } 04095 04096 if (lock_get_wait(lock)) { 04097 fputs(" waiting", file); 04098 } 04099 04100 putc('\n', file); 04101 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool lock_table_queue_validate | ( | dict_table_t * | table | ) |
Definition at line 4459 of file lock0lock.c.
References FALSE, kernel_mutex, lock, lock_get_mode(), lock_get_wait(), lock_table_has_to_wait_in_queue(), lock_table_other_has_incompatible(), dict_table_struct::locks, TRUE, TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, TRX_PREPARED, ut_a, ut_ad, UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by lock_validate().
04461 : TRUE if ok */ 04462 dict_table_t* table) /* in: table */ 04463 { 04464 lock_t* lock; 04465 ibool is_waiting; 04466 04467 #ifdef UNIV_SYNC_DEBUG 04468 ut_ad(mutex_own(&kernel_mutex)); 04469 #endif /* UNIV_SYNC_DEBUG */ 04470 04471 is_waiting = FALSE; 04472 04473 lock = UT_LIST_GET_FIRST(table->locks); 04474 04475 while (lock) { 04476 ut_a(((lock->trx)->conc_state == TRX_ACTIVE) 04477 || ((lock->trx)->conc_state == TRX_PREPARED) 04478 || ((lock->trx)->conc_state == TRX_COMMITTED_IN_MEMORY)); 04479 04480 if (!lock_get_wait(lock)) { 04481 04482 ut_a(!is_waiting); 04483 04484 ut_a(!lock_table_other_has_incompatible(lock->trx, 0, 04485 table, lock_get_mode(lock))); 04486 } else { 04487 is_waiting = TRUE; 04488 04489 ut_a(lock_table_has_to_wait_in_queue(lock)); 04490 } 04491 04492 lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock); 04493 } 04494 04495 return(TRUE); 04496 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_table_unlock | ( | lock_t * | lock | ) |
Definition at line 3868 of file lock0lock.c.
References kernel_mutex, lock, lock_table_dequeue(), mutex_enter, and mutex_exit().
03870 : lock */ 03871 { 03872 mutex_enter(&kernel_mutex); 03873 03874 lock_table_dequeue(lock); 03875 03876 mutex_exit(&kernel_mutex); 03877 }
Here is the call graph for this function:

| void lock_table_unlock_auto_inc | ( | trx_t * | trx | ) |
Definition at line 3884 of file lock0lock.c.
References trx_struct::auto_inc_lock, kernel_mutex, lock_table_dequeue(), mutex_enter, and mutex_exit().
Referenced by row_unlock_table_autoinc_for_mysql().
03886 : transaction */ 03887 { 03888 if (trx->auto_inc_lock) { 03889 mutex_enter(&kernel_mutex); 03890 03891 lock_table_dequeue(trx->auto_inc_lock); 03892 03893 mutex_exit(&kernel_mutex); 03894 } 03895 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2953 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_free_all_from_discard_page(), lock_rec_move(), page_get_supremum_rec(), page_is_comp(), and ut_ad.
Referenced by btr_lift_page_up().
02955 : index page to which copied */ 02956 page_t* page) /* in: index page; NOT the root! */ 02957 { 02958 ulint comp; 02959 lock_mutex_enter_kernel(); 02960 comp = page_is_comp(page); 02961 ut_ad(comp == page_is_comp(new_page)); 02962 02963 /* Move the locks on the supremum of the old page to the supremum 02964 of new_page */ 02965 02966 lock_rec_move(page_get_supremum_rec(new_page), 02967 page_get_supremum_rec(page), comp); 02968 lock_rec_free_all_from_discard_page(page); 02969 02970 lock_mutex_exit_kernel(); 02971 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_update_delete | ( | rec_t * | rec | ) |
Definition at line 3126 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_inherit_to_gap(), lock_rec_reset_and_release_wait(), and page_rec_get_next().
Referenced by btr_cur_optimistic_delete(), and btr_cur_pessimistic_delete().
03128 : the record to be removed */ 03129 { 03130 lock_mutex_enter_kernel(); 03131 03132 /* Let the next record inherit the locks from rec, in gap mode */ 03133 03134 lock_rec_inherit_to_gap(page_rec_get_next(rec), rec); 03135 03136 /* Reset the lock bits on rec and release waiting transactions */ 03137 03138 lock_rec_reset_and_release_wait(rec); 03139 03140 lock_mutex_exit_kernel(); 03141 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3062 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_free_all_from_discard_page(), lock_rec_get_first_on_page(), lock_rec_inherit_to_gap(), lock_rec_reset_and_release_wait(), NULL, page_get_infimum_rec(), page_rec_get_next(), and page_rec_is_supremum().
Referenced by btr_discard_only_page_on_level(), and btr_discard_page().
03064 : record which will inherit the locks */ 03065 page_t* page) /* in: index page which will be discarded */ 03066 { 03067 rec_t* rec; 03068 03069 lock_mutex_enter_kernel(); 03070 03071 if (NULL == lock_rec_get_first_on_page(page)) { 03072 /* No locks exist on page, nothing to do */ 03073 03074 lock_mutex_exit_kernel(); 03075 03076 return; 03077 } 03078 03079 /* Inherit all the locks on the page to the record and reset all 03080 the locks on the page */ 03081 03082 rec = page_get_infimum_rec(page); 03083 03084 for (;;) { 03085 lock_rec_inherit_to_gap(heir, rec); 03086 03087 /* Reset the locks on rec, releasing waiting transactions */ 03088 03089 lock_rec_reset_and_release_wait(rec); 03090 03091 if (page_rec_is_supremum(rec)) { 03092 03093 break; 03094 } 03095 03096 rec = page_rec_get_next(rec); 03097 } 03098 03099 lock_rec_free_all_from_discard_page(page); 03100 03101 lock_mutex_exit_kernel(); 03102 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_update_insert | ( | rec_t * | rec | ) |
Definition at line 3108 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_inherit_to_gap_if_gap_lock(), and page_rec_get_next().
Referenced by btr_cur_optimistic_insert(), and btr_cur_pessimistic_insert().
03110 : the inserted record */ 03111 { 03112 lock_mutex_enter_kernel(); 03113 03114 /* Inherit the gap-locking locks for rec, in gap mode, from the next 03115 record */ 03116 03117 lock_rec_inherit_to_gap_if_gap_lock(rec, page_rec_get_next(rec)); 03118 03119 lock_mutex_exit_kernel(); 03120 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2997 of file lock0lock.c.
References buf_frame_align(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_free_all_from_discard_page(), lock_rec_inherit_to_gap(), lock_rec_move(), lock_rec_reset_and_release_wait(), page_get_supremum_rec(), page_is_comp(), page_rec_get_next(), and ut_ad.
Referenced by btr_compress().
02999 : left page to which merged */ 03000 rec_t* orig_pred, /* in: original predecessor of supremum 03001 on the left page before merge */ 03002 page_t* right_page) /* in: merged index page which will be 03003 discarded */ 03004 { 03005 rec_t* left_next_rec; 03006 rec_t* left_supremum; 03007 ulint comp; 03008 lock_mutex_enter_kernel(); 03009 comp = page_is_comp(left_page); 03010 ut_ad(comp == page_is_comp(right_page)); 03011 ut_ad(left_page == buf_frame_align(orig_pred)); 03012 03013 left_next_rec = page_rec_get_next(orig_pred); 03014 left_supremum = page_get_supremum_rec(left_page); 03015 03016 if (UNIV_LIKELY(left_next_rec != left_supremum)) { 03017 03018 /* Inherit the locks on the supremum of the left page to the 03019 first record which was moved from the right page */ 03020 03021 lock_rec_inherit_to_gap(left_next_rec, left_supremum); 03022 03023 /* Reset the locks on the supremum of the left page, 03024 releasing waiting transactions */ 03025 03026 lock_rec_reset_and_release_wait(left_supremum); 03027 } 03028 03029 /* Move the locks from the supremum of right page to the supremum 03030 of the left page */ 03031 03032 lock_rec_move(left_supremum, page_get_supremum_rec(right_page), comp); 03033 03034 lock_rec_free_all_from_discard_page(right_page); 03035 03036 lock_mutex_exit_kernel(); 03037 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2896 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_free_all_from_discard_page(), lock_rec_inherit_to_gap(), lock_rec_reset_and_release_wait(), and page_get_supremum_rec().
Referenced by btr_compress().
02898 : original successor of infimum 02899 on the right page before merge */ 02900 page_t* left_page) /* in: merged index page which will be 02901 discarded */ 02902 { 02903 lock_mutex_enter_kernel(); 02904 02905 /* Inherit the locks from the supremum of the left page to the 02906 original successor of infimum on the right page, to which the left 02907 page was merged */ 02908 02909 lock_rec_inherit_to_gap(orig_succ, page_get_supremum_rec(left_page)); 02910 02911 /* Reset the locks on the supremum of the left page, releasing 02912 waiting transactions */ 02913 02914 lock_rec_reset_and_release_wait(page_get_supremum_rec(left_page)); 02915 02916 lock_rec_free_all_from_discard_page(left_page); 02917 02918 lock_mutex_exit_kernel(); 02919 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2930 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_move(), page_get_supremum_rec(), page_is_comp(), and ut_ad.
Referenced by btr_root_raise_and_insert().
02932 : index page to which copied */ 02933 page_t* root) /* in: root page */ 02934 { 02935 ulint comp; 02936 lock_mutex_enter_kernel(); 02937 comp = page_is_comp(root); 02938 ut_ad(comp == page_is_comp(new_page)); 02939 02940 /* Move the locks on the supremum of the root to the supremum 02941 of new_page */ 02942 02943 lock_rec_move(page_get_supremum_rec(new_page), 02944 page_get_supremum_rec(root), comp); 02945 lock_mutex_exit_kernel(); 02946 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2977 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_inherit_to_gap(), page_get_infimum_rec(), page_get_supremum_rec(), and page_rec_get_next().
Referenced by btr_page_split_and_insert().
02979 : right page */ 02980 page_t* left_page) /* in: left page */ 02981 { 02982 lock_mutex_enter_kernel(); 02983 02984 /* Inherit the locks to the supremum of the left page from the 02985 successor of the infimum on the right page */ 02986 02987 lock_rec_inherit_to_gap(page_get_supremum_rec(left_page), 02988 page_rec_get_next(page_get_infimum_rec(right_page))); 02989 02990 lock_mutex_exit_kernel(); 02991 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2867 of file lock0lock.c.
References lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_inherit_to_gap(), lock_rec_move(), page_get_infimum_rec(), page_get_supremum_rec(), page_is_comp(), page_rec_get_next(), and ut_ad.
Referenced by btr_page_split_and_insert().
02869 : right page */ 02870 page_t* left_page) /* in: left page */ 02871 { 02872 ulint comp; 02873 lock_mutex_enter_kernel(); 02874 comp = page_is_comp(left_page); 02875 ut_ad(comp == page_is_comp(right_page)); 02876 02877 /* Move the locks on the supremum of the left page to the supremum 02878 of the right page */ 02879 02880 lock_rec_move(page_get_supremum_rec(right_page), 02881 page_get_supremum_rec(left_page), comp); 02882 02883 /* Inherit the locks to the supremum of left page from the successor 02884 of the infimum on right page */ 02885 02886 lock_rec_inherit_to_gap(page_get_supremum_rec(left_page), 02887 page_rec_get_next(page_get_infimum_rec(right_page))); 02888 02889 lock_mutex_exit_kernel(); 02890 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool lock_validate | ( | void | ) |
Definition at line 4711 of file lock0lock.c.
References hash(), HASH_GET_FIRST, hash_get_n_cells(), HASH_GET_NEXT, lock, lock_get_type(), lock_mutex_enter_kernel, lock_mutex_exit_kernel, lock_rec_validate_page(), lock_sys, LOCK_TABLE, lock_table_queue_validate(), lock_sys_struct::rec_hash, TRUE, trx_in_trx_list(), trx_struct::trx_locks, trx_sys, ut_a, ut_dulint_cmp(), ut_dulint_create(), ut_dulint_zero, UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by lock_print_info_all_transactions().
04713 : TRUE if ok */ 04714 { 04715 lock_t* lock; 04716 trx_t* trx; 04717 dulint limit; 04718 ulint space; 04719 ulint page_no; 04720 ulint i; 04721 04722 lock_mutex_enter_kernel(); 04723 04724 trx = UT_LIST_GET_FIRST(trx_sys->trx_list); 04725 04726 while (trx) { 04727 lock = UT_LIST_GET_FIRST(trx->trx_locks); 04728 04729 while (lock) { 04730 if (lock_get_type(lock) & LOCK_TABLE) { 04731 04732 lock_table_queue_validate( 04733 lock->un_member.tab_lock.table); 04734 } 04735 04736 lock = UT_LIST_GET_NEXT(trx_locks, lock); 04737 } 04738 04739 trx = UT_LIST_GET_NEXT(trx_list, trx); 04740 } 04741 04742 for (i = 0; i < hash_get_n_cells(lock_sys->rec_hash); i++) { 04743 04744 limit = ut_dulint_zero; 04745 04746 for (;;) { 04747 lock = HASH_GET_FIRST(lock_sys->rec_hash, i); 04748 04749 while (lock) { 04750 ut_a(trx_in_trx_list(lock->trx)); 04751 04752 space = lock->un_member.rec_lock.space; 04753 page_no = lock->un_member.rec_lock.page_no; 04754 04755 if (ut_dulint_cmp( 04756 ut_dulint_create(space, page_no), 04757 limit) >= 0) { 04758 break; 04759 } 04760 04761 lock = HASH_GET_NEXT(hash, lock); 04762 } 04763 04764 if (!lock) { 04765 04766 break; 04767 } 04768 04769 lock_mutex_exit_kernel(); 04770 04771 lock_rec_validate_page(space, page_no); 04772 04773 lock_mutex_enter_kernel(); 04774 04775 limit = ut_dulint_create(space, page_no + 1); 04776 } 04777 } 04778 04779 lock_mutex_exit_kernel(); 04780 04781 return(TRUE); 04782 }
Here is the call graph for this function:

Here is the caller graph for this function:

| FILE* lock_latest_err_file |
Definition at line 361 of file lock0lock.c.
Referenced by innobase_shutdown_for_mysql(), lock_deadlock_occurs(), lock_deadlock_recursive(), lock_print_info_summary(), and lock_sys_create().
Definition at line 320 of file lock0lock.c.
Definition at line 320 of file lock0lock.c.
Referenced by lock_get_n_rec_locks(), lock_rec_create(), lock_rec_dequeue_from_page(), lock_rec_discard(), lock_rec_get_first_on_page(), lock_rec_get_first_on_page_addr(), lock_sys_create(), and lock_validate().
1.4.7

