Loading innobase/include/lock0lock.h +20 −1 Original line number Diff line number Diff line Loading @@ -381,7 +381,9 @@ lock_table( /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ does nothing; if LOCK_TABLE_EXP bits are set, creates an explicit table lock */ dict_table_t* table, /* in: database table in dictionary cache */ ulint mode, /* in: lock mode */ que_thr_t* thr); /* in: query thread */ Loading @@ -394,6 +396,14 @@ lock_is_on_table( /* out: TRUE if there are lock(s) */ dict_table_t* table); /* in: database table in dictionary cache */ /************************************************************************* Releases a table lock. Releases possible other transactions waiting for this lock. */ void lock_table_unlock( /*==============*/ lock_t* lock); /* in: lock */ /************************************************************************* Releases an auto-inc lock a transaction possibly has on a table. Releases possible other transactions waiting for this lock. */ Loading @@ -410,6 +420,14 @@ lock_release_off_kernel( /*====================*/ trx_t* trx); /* in: transaction */ /************************************************************************* Releases table locks, and releases possible other transactions waiting because of these locks. */ void lock_release_tables_off_kernel( /*===========================*/ trx_t* trx); /* in: transaction */ /************************************************************************* Cancels a waiting lock request and releases possible other transactions waiting behind it. */ Loading Loading @@ -536,6 +554,7 @@ extern lock_sys_t* lock_sys; /* Lock types */ #define LOCK_TABLE 16 /* these type values should be so high that */ #define LOCK_REC 32 /* they can be ORed to the lock mode */ #define LOCK_TABLE_EXP 80 /* explicit table lock */ #define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the type_mode field in a lock */ /* Waiting lock flag */ Loading innobase/include/row0mysql.h +16 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,22 @@ row_lock_table_autoinc_for_mysql( row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL table handle */ /************************************************************************* Unlocks a table lock possibly reserved by trx. */ void row_unlock_table_for_mysql( /*=======================*/ trx_t* trx); /* in: transaction */ /************************************************************************* Sets a table lock on the table mentioned in prebuilt. */ int row_lock_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL table handle */ /************************************************************************* Does an insert for MySQL. */ int Loading innobase/include/trx0trx.h +2 −0 Original line number Diff line number Diff line Loading @@ -421,6 +421,8 @@ struct trx_struct{ lock_t* auto_inc_lock; /* possible auto-inc lock reserved by the transaction; note that it is also in the lock list trx_locks */ ulint n_tables_locked;/* number of table locks reserved by the transaction, stored in trx_locks */ UT_LIST_NODE_T(trx_t) trx_list; /* list of transactions */ UT_LIST_NODE_T(trx_t) Loading innobase/lock/lock0lock.c +118 −12 Original line number Diff line number Diff line Loading @@ -2001,6 +2001,10 @@ lock_grant( release it at the end of the SQL statement */ lock->trx->auto_inc_lock = lock; } else if (lock_get_type(lock) == LOCK_TABLE_EXP) { ut_ad(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); lock->trx->n_tables_locked++; } #ifdef UNIV_DEBUG Loading Loading @@ -2939,7 +2943,7 @@ lock_deadlock_occurs( } if (ret == LOCK_VICTIM_IS_START) { if (lock_get_type(lock) == LOCK_TABLE) { if (lock_get_type(lock) & LOCK_TABLE) { table = lock->un_member.tab_lock.table; index = NULL; } else { Loading Loading @@ -3015,7 +3019,7 @@ lock_deadlock_recursive( /* Look at the locks ahead of wait_lock in the lock queue */ for (;;) { if (lock_get_type(lock) == LOCK_TABLE) { if (lock_get_type(lock) & LOCK_TABLE) { lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock); } else { Loading Loading @@ -3347,7 +3351,9 @@ lock_table( /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ does nothing; if LOCK_TABLE_EXP bits are set, creates an explicit table lock */ dict_table_t* table, /* in: database table in dictionary cache */ ulint mode, /* in: lock mode */ que_thr_t* thr) /* in: query thread */ Loading @@ -3362,6 +3368,8 @@ lock_table( return(DB_SUCCESS); } ut_ad(flags == 0 || flags == LOCK_TABLE_EXP); trx = thr_get_trx(thr); lock_mutex_enter_kernel(); Loading Loading @@ -3390,7 +3398,12 @@ lock_table( return(err); } lock_table_create(table, mode, trx); lock_table_create(table, mode | flags, trx); if (flags) { ut_ad(mode == LOCK_S || mode == LOCK_X); trx->n_tables_locked++; } lock_mutex_exit_kernel(); Loading Loading @@ -3471,7 +3484,8 @@ lock_table_dequeue( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(in_lock) == LOCK_TABLE); ut_ad(lock_get_type(in_lock) == LOCK_TABLE || lock_get_type(in_lock) == LOCK_TABLE_EXP); lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock); Loading @@ -3495,6 +3509,22 @@ lock_table_dequeue( /*=========================== LOCK RELEASE ==============================*/ /************************************************************************* Releases a table lock. Releases possible other transactions waiting for this lock. */ void lock_table_unlock( /*==============*/ lock_t* lock) /* in: lock */ { mutex_enter(&kernel_mutex); lock_table_dequeue(lock); mutex_exit(&kernel_mutex); } /************************************************************************* Releases an auto-inc lock a transaction possibly has on a table. Releases possible other transactions waiting for this lock. */ Loading Loading @@ -3542,7 +3572,7 @@ lock_release_off_kernel( lock_rec_dequeue_from_page(lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); ut_ad(lock_get_type(lock) & LOCK_TABLE); if (lock_get_mode(lock) != LOCK_IS && (trx->insert_undo || trx->update_undo)) { Loading @@ -3558,6 +3588,11 @@ lock_release_off_kernel( } lock_table_dequeue(lock); if (lock_get_type(lock) == LOCK_TABLE_EXP) { ut_ad(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); trx->n_tables_locked--; } } if (count == LOCK_RELEASE_KERNEL_INTERVAL) { Loading @@ -3577,6 +3612,73 @@ lock_release_off_kernel( mem_heap_empty(trx->lock_heap); ut_a(trx->auto_inc_lock == NULL); ut_a(trx->n_tables_locked == 0); } /************************************************************************* Releases table locks, and releases possible other transactions waiting because of these locks. */ void lock_release_tables_off_kernel( /*===========================*/ trx_t* trx) /* in: transaction */ { dict_table_t* table; ulint count; lock_t* lock; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ lock = UT_LIST_GET_LAST(trx->trx_locks); count = 0; while (lock != NULL) { count++; if (lock_get_type(lock) == LOCK_TABLE_EXP) { ut_ad(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); if (trx->insert_undo || trx->update_undo) { /* The trx may have modified the table. We block the use of the MySQL query cache for all currently active transactions. */ table = lock->un_member.tab_lock.table; table->query_cache_inv_trx_id = trx_sys->max_trx_id; } lock_table_dequeue(lock); trx->n_tables_locked--; lock = UT_LIST_GET_LAST(trx->trx_locks); continue; } if (count == LOCK_RELEASE_KERNEL_INTERVAL) { /* Release the kernel mutex for a while, so that we do not monopolize it */ lock_mutex_exit_kernel(); lock_mutex_enter_kernel(); count = 0; } lock = UT_LIST_GET_PREV(trx_locks, lock); } mem_heap_empty(trx->lock_heap); ut_a(trx->n_tables_locked == 0); } /************************************************************************* Loading @@ -3596,7 +3698,7 @@ lock_cancel_waiting_and_release( lock_rec_dequeue_from_page(lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); ut_ad(lock_get_type(lock) & LOCK_TABLE); lock_table_dequeue(lock); } Loading Loading @@ -3637,7 +3739,7 @@ lock_reset_all_on_table_for_trx( ut_a(!lock_get_wait(lock)); lock_rec_discard(lock); } else if (lock_get_type(lock) == LOCK_TABLE } else if (lock_get_type(lock) & LOCK_TABLE && lock->un_member.tab_lock.table == table) { ut_a(!lock_get_wait(lock)); Loading Loading @@ -3689,8 +3791,12 @@ lock_table_print( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_a(lock_get_type(lock) == LOCK_TABLE); ut_a(lock_get_type(lock) == LOCK_TABLE || lock_get_type(lock) == LOCK_TABLE_EXP); if (lock_get_type(lock) == LOCK_TABLE_EXP) { fputs("EXPLICIT ", file); } fputs("TABLE LOCK table ", file); ut_print_name(file, lock->un_member.tab_lock.table->name); fprintf(file, " trx id %lu %lu", Loading Loading @@ -4009,7 +4115,7 @@ lock_print_info( lock_rec_print(file, lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); ut_ad(lock_get_type(lock) & LOCK_TABLE); lock_table_print(file, lock); } Loading Loading @@ -4290,7 +4396,7 @@ lock_validate(void) lock = UT_LIST_GET_FIRST(trx->trx_locks); while (lock) { if (lock_get_type(lock) == LOCK_TABLE) { if (lock_get_type(lock) & LOCK_TABLE) { lock_table_queue_validate( lock->un_member.tab_lock.table); Loading innobase/row/row0mysql.c +86 −2 Original line number Diff line number Diff line Loading @@ -696,7 +696,91 @@ row_lock_table_autoinc_for_mysql( trx_start_if_not_started(trx); err = lock_table(0, prebuilt->table, LOCK_AUTO_INC, thr); err = lock_table(0, prebuilt->table, prebuilt->select_lock_type, thr); trx->error_state = err; if (err != DB_SUCCESS) { que_thr_stop_for_mysql(thr); was_lock_wait = row_mysql_handle_errors(&err, trx, thr, NULL); if (was_lock_wait) { goto run_again; } trx->op_info = (char *) ""; return(err); } que_thr_stop_for_mysql_no_error(thr, trx); trx->op_info = (char *) ""; return((int) err); } /************************************************************************* Unlocks a table lock possibly reserved by trx. */ void row_unlock_table_for_mysql( /*=======================*/ trx_t* trx) /* in: transaction */ { if (!trx->n_tables_locked) { return; } mutex_enter(&kernel_mutex); lock_release_tables_off_kernel(trx); mutex_exit(&kernel_mutex); } /************************************************************************* Sets a table lock on the table mentioned in prebuilt. */ int row_lock_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL table handle */ { trx_t* trx = prebuilt->trx; que_thr_t* thr; ulint err; ibool was_lock_wait; ut_ad(trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); trx->op_info = (char *) "setting table lock"; if (prebuilt->sel_graph == NULL) { /* Build a dummy select query graph */ row_prebuild_sel_graph(prebuilt); } /* We use the select query graph as the dummy graph needed in the lock module call */ thr = que_fork_get_first_thr(prebuilt->sel_graph); que_thr_move_to_run_state_for_mysql(thr, trx); run_again: thr->run_node = thr; thr->prev_node = thr->common.parent; /* It may be that the current session has not yet started its transaction, or it has been committed: */ trx_start_if_not_started(trx); err = lock_table(LOCK_TABLE_EXP, prebuilt->table, prebuilt->select_lock_type, thr); trx->error_state = err; Loading Loading
innobase/include/lock0lock.h +20 −1 Original line number Diff line number Diff line Loading @@ -381,7 +381,9 @@ lock_table( /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ does nothing; if LOCK_TABLE_EXP bits are set, creates an explicit table lock */ dict_table_t* table, /* in: database table in dictionary cache */ ulint mode, /* in: lock mode */ que_thr_t* thr); /* in: query thread */ Loading @@ -394,6 +396,14 @@ lock_is_on_table( /* out: TRUE if there are lock(s) */ dict_table_t* table); /* in: database table in dictionary cache */ /************************************************************************* Releases a table lock. Releases possible other transactions waiting for this lock. */ void lock_table_unlock( /*==============*/ lock_t* lock); /* in: lock */ /************************************************************************* Releases an auto-inc lock a transaction possibly has on a table. Releases possible other transactions waiting for this lock. */ Loading @@ -410,6 +420,14 @@ lock_release_off_kernel( /*====================*/ trx_t* trx); /* in: transaction */ /************************************************************************* Releases table locks, and releases possible other transactions waiting because of these locks. */ void lock_release_tables_off_kernel( /*===========================*/ trx_t* trx); /* in: transaction */ /************************************************************************* Cancels a waiting lock request and releases possible other transactions waiting behind it. */ Loading Loading @@ -536,6 +554,7 @@ extern lock_sys_t* lock_sys; /* Lock types */ #define LOCK_TABLE 16 /* these type values should be so high that */ #define LOCK_REC 32 /* they can be ORed to the lock mode */ #define LOCK_TABLE_EXP 80 /* explicit table lock */ #define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the type_mode field in a lock */ /* Waiting lock flag */ Loading
innobase/include/row0mysql.h +16 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,22 @@ row_lock_table_autoinc_for_mysql( row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL table handle */ /************************************************************************* Unlocks a table lock possibly reserved by trx. */ void row_unlock_table_for_mysql( /*=======================*/ trx_t* trx); /* in: transaction */ /************************************************************************* Sets a table lock on the table mentioned in prebuilt. */ int row_lock_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL table handle */ /************************************************************************* Does an insert for MySQL. */ int Loading
innobase/include/trx0trx.h +2 −0 Original line number Diff line number Diff line Loading @@ -421,6 +421,8 @@ struct trx_struct{ lock_t* auto_inc_lock; /* possible auto-inc lock reserved by the transaction; note that it is also in the lock list trx_locks */ ulint n_tables_locked;/* number of table locks reserved by the transaction, stored in trx_locks */ UT_LIST_NODE_T(trx_t) trx_list; /* list of transactions */ UT_LIST_NODE_T(trx_t) Loading
innobase/lock/lock0lock.c +118 −12 Original line number Diff line number Diff line Loading @@ -2001,6 +2001,10 @@ lock_grant( release it at the end of the SQL statement */ lock->trx->auto_inc_lock = lock; } else if (lock_get_type(lock) == LOCK_TABLE_EXP) { ut_ad(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); lock->trx->n_tables_locked++; } #ifdef UNIV_DEBUG Loading Loading @@ -2939,7 +2943,7 @@ lock_deadlock_occurs( } if (ret == LOCK_VICTIM_IS_START) { if (lock_get_type(lock) == LOCK_TABLE) { if (lock_get_type(lock) & LOCK_TABLE) { table = lock->un_member.tab_lock.table; index = NULL; } else { Loading Loading @@ -3015,7 +3019,7 @@ lock_deadlock_recursive( /* Look at the locks ahead of wait_lock in the lock queue */ for (;;) { if (lock_get_type(lock) == LOCK_TABLE) { if (lock_get_type(lock) & LOCK_TABLE) { lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock); } else { Loading Loading @@ -3347,7 +3351,9 @@ lock_table( /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ does nothing; if LOCK_TABLE_EXP bits are set, creates an explicit table lock */ dict_table_t* table, /* in: database table in dictionary cache */ ulint mode, /* in: lock mode */ que_thr_t* thr) /* in: query thread */ Loading @@ -3362,6 +3368,8 @@ lock_table( return(DB_SUCCESS); } ut_ad(flags == 0 || flags == LOCK_TABLE_EXP); trx = thr_get_trx(thr); lock_mutex_enter_kernel(); Loading Loading @@ -3390,7 +3398,12 @@ lock_table( return(err); } lock_table_create(table, mode, trx); lock_table_create(table, mode | flags, trx); if (flags) { ut_ad(mode == LOCK_S || mode == LOCK_X); trx->n_tables_locked++; } lock_mutex_exit_kernel(); Loading Loading @@ -3471,7 +3484,8 @@ lock_table_dequeue( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(in_lock) == LOCK_TABLE); ut_ad(lock_get_type(in_lock) == LOCK_TABLE || lock_get_type(in_lock) == LOCK_TABLE_EXP); lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock); Loading @@ -3495,6 +3509,22 @@ lock_table_dequeue( /*=========================== LOCK RELEASE ==============================*/ /************************************************************************* Releases a table lock. Releases possible other transactions waiting for this lock. */ void lock_table_unlock( /*==============*/ lock_t* lock) /* in: lock */ { mutex_enter(&kernel_mutex); lock_table_dequeue(lock); mutex_exit(&kernel_mutex); } /************************************************************************* Releases an auto-inc lock a transaction possibly has on a table. Releases possible other transactions waiting for this lock. */ Loading Loading @@ -3542,7 +3572,7 @@ lock_release_off_kernel( lock_rec_dequeue_from_page(lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); ut_ad(lock_get_type(lock) & LOCK_TABLE); if (lock_get_mode(lock) != LOCK_IS && (trx->insert_undo || trx->update_undo)) { Loading @@ -3558,6 +3588,11 @@ lock_release_off_kernel( } lock_table_dequeue(lock); if (lock_get_type(lock) == LOCK_TABLE_EXP) { ut_ad(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); trx->n_tables_locked--; } } if (count == LOCK_RELEASE_KERNEL_INTERVAL) { Loading @@ -3577,6 +3612,73 @@ lock_release_off_kernel( mem_heap_empty(trx->lock_heap); ut_a(trx->auto_inc_lock == NULL); ut_a(trx->n_tables_locked == 0); } /************************************************************************* Releases table locks, and releases possible other transactions waiting because of these locks. */ void lock_release_tables_off_kernel( /*===========================*/ trx_t* trx) /* in: transaction */ { dict_table_t* table; ulint count; lock_t* lock; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ lock = UT_LIST_GET_LAST(trx->trx_locks); count = 0; while (lock != NULL) { count++; if (lock_get_type(lock) == LOCK_TABLE_EXP) { ut_ad(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); if (trx->insert_undo || trx->update_undo) { /* The trx may have modified the table. We block the use of the MySQL query cache for all currently active transactions. */ table = lock->un_member.tab_lock.table; table->query_cache_inv_trx_id = trx_sys->max_trx_id; } lock_table_dequeue(lock); trx->n_tables_locked--; lock = UT_LIST_GET_LAST(trx->trx_locks); continue; } if (count == LOCK_RELEASE_KERNEL_INTERVAL) { /* Release the kernel mutex for a while, so that we do not monopolize it */ lock_mutex_exit_kernel(); lock_mutex_enter_kernel(); count = 0; } lock = UT_LIST_GET_PREV(trx_locks, lock); } mem_heap_empty(trx->lock_heap); ut_a(trx->n_tables_locked == 0); } /************************************************************************* Loading @@ -3596,7 +3698,7 @@ lock_cancel_waiting_and_release( lock_rec_dequeue_from_page(lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); ut_ad(lock_get_type(lock) & LOCK_TABLE); lock_table_dequeue(lock); } Loading Loading @@ -3637,7 +3739,7 @@ lock_reset_all_on_table_for_trx( ut_a(!lock_get_wait(lock)); lock_rec_discard(lock); } else if (lock_get_type(lock) == LOCK_TABLE } else if (lock_get_type(lock) & LOCK_TABLE && lock->un_member.tab_lock.table == table) { ut_a(!lock_get_wait(lock)); Loading Loading @@ -3689,8 +3791,12 @@ lock_table_print( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_a(lock_get_type(lock) == LOCK_TABLE); ut_a(lock_get_type(lock) == LOCK_TABLE || lock_get_type(lock) == LOCK_TABLE_EXP); if (lock_get_type(lock) == LOCK_TABLE_EXP) { fputs("EXPLICIT ", file); } fputs("TABLE LOCK table ", file); ut_print_name(file, lock->un_member.tab_lock.table->name); fprintf(file, " trx id %lu %lu", Loading Loading @@ -4009,7 +4115,7 @@ lock_print_info( lock_rec_print(file, lock); } else { ut_ad(lock_get_type(lock) == LOCK_TABLE); ut_ad(lock_get_type(lock) & LOCK_TABLE); lock_table_print(file, lock); } Loading Loading @@ -4290,7 +4396,7 @@ lock_validate(void) lock = UT_LIST_GET_FIRST(trx->trx_locks); while (lock) { if (lock_get_type(lock) == LOCK_TABLE) { if (lock_get_type(lock) & LOCK_TABLE) { lock_table_queue_validate( lock->un_member.tab_lock.table); Loading
innobase/row/row0mysql.c +86 −2 Original line number Diff line number Diff line Loading @@ -696,7 +696,91 @@ row_lock_table_autoinc_for_mysql( trx_start_if_not_started(trx); err = lock_table(0, prebuilt->table, LOCK_AUTO_INC, thr); err = lock_table(0, prebuilt->table, prebuilt->select_lock_type, thr); trx->error_state = err; if (err != DB_SUCCESS) { que_thr_stop_for_mysql(thr); was_lock_wait = row_mysql_handle_errors(&err, trx, thr, NULL); if (was_lock_wait) { goto run_again; } trx->op_info = (char *) ""; return(err); } que_thr_stop_for_mysql_no_error(thr, trx); trx->op_info = (char *) ""; return((int) err); } /************************************************************************* Unlocks a table lock possibly reserved by trx. */ void row_unlock_table_for_mysql( /*=======================*/ trx_t* trx) /* in: transaction */ { if (!trx->n_tables_locked) { return; } mutex_enter(&kernel_mutex); lock_release_tables_off_kernel(trx); mutex_exit(&kernel_mutex); } /************************************************************************* Sets a table lock on the table mentioned in prebuilt. */ int row_lock_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL table handle */ { trx_t* trx = prebuilt->trx; que_thr_t* thr; ulint err; ibool was_lock_wait; ut_ad(trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); trx->op_info = (char *) "setting table lock"; if (prebuilt->sel_graph == NULL) { /* Build a dummy select query graph */ row_prebuild_sel_graph(prebuilt); } /* We use the select query graph as the dummy graph needed in the lock module call */ thr = que_fork_get_first_thr(prebuilt->sel_graph); que_thr_move_to_run_state_for_mysql(thr, trx); run_again: thr->run_node = thr; thr->prev_node = thr->common.parent; /* It may be that the current session has not yet started its transaction, or it has been committed: */ trx_start_if_not_started(trx); err = lock_table(LOCK_TABLE_EXP, prebuilt->table, prebuilt->select_lock_type, thr); trx->error_state = err; Loading