2169
lock_t* lock) /* in: waiting lock request */
2169
lock_t* lock) /* in/out: waiting lock request */
2171
2171
ut_ad(mutex_own(&kernel_mutex));
2173
2173
lock_reset_lock_and_trx_wait(lock);
2175
2175
if (lock_get_mode(lock) == LOCK_AUTO_INC) {
2176
trx_t* trx = lock->trx;
2177
dict_table_t* table = lock->un_member.tab_lock.table;
2177
if (lock->trx->auto_inc_lock != NULL) {
2179
if (table->autoinc_trx == trx) {
2178
2180
fprintf(stderr,
2179
2181
"InnoDB: Error: trx already had"
2180
2182
" an AUTO-INC lock!\n");
2184
table->autoinc_trx = trx;
2186
ib_vector_push(trx->autoinc_locks, lock);
2183
/* Store pointer to lock to trx so that we know to
2184
release it at the end of the SQL statement */
2186
lock->trx->auto_inc_lock = lock;
2189
2190
#ifdef UNIV_DEBUG
3531
3532
++table->n_waiting_or_granted_auto_inc_locks;
3535
/* For AUTOINC locking we reuse the lock instance only if
3536
there is no wait involved else we allocate the waiting lock
3537
from the transaction lock heap. */
3534
3538
if (type_mode == LOCK_AUTO_INC) {
3535
/* Only one trx can have the lock on the table
3536
at a time: we may use the memory preallocated
3537
to the table object */
3539
lock = table->auto_inc_lock;
3541
ut_a(trx->auto_inc_lock == NULL);
3542
trx->auto_inc_lock = lock;
3540
lock = table->autoinc_lock;
3542
table->autoinc_trx = trx;
3544
ib_vector_push(trx->autoinc_locks, lock);
3544
3546
lock = mem_heap_alloc(trx->lock_heap, sizeof(lock_t));
3571
3573
/*==================*/
3572
3574
lock_t* lock) /* in: table lock */
3574
3577
dict_table_t* table;
3577
3579
ut_ad(mutex_own(&kernel_mutex));
3579
3582
table = lock->un_member.tab_lock.table;
3582
if (lock == trx->auto_inc_lock) {
3583
trx->auto_inc_lock = NULL;
3584
/* Remove the table from the transaction's AUTOINC vector, if
3585
the lock that is being release is an AUTOINC lock. */
3586
if (lock_get_mode(lock) == LOCK_AUTO_INC) {
3588
/* The table's AUTOINC lock can get transferred to
3589
another transaction before we get here. */
3590
if (table->autoinc_trx == trx) {
3591
table->autoinc_trx = NULL;
3594
/* The locks must be freed in the reverse order from
3595
the one in which they were acquired. This is to avoid
3596
traversing the AUTOINC lock vector unnecessarily.
3598
We only store locks that were granted in the
3599
trx->autoinc_locks vector (see lock_table_create()
3600
and lock_grant()). Therefore it can be empty and we
3601
need to check for that. */
3603
if (!ib_vector_is_empty(trx->autoinc_locks)) {
3604
lock_t* autoinc_lock;
3606
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
3607
ut_a(autoinc_lock == lock);
3585
3610
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);
3586
3611
--table->n_waiting_or_granted_auto_inc_locks;
3958
3983
/*************************************************************************
3959
Releases an auto-inc lock a transaction possibly has on a table.
3960
Releases possible other transactions waiting for this lock. */
3963
lock_table_unlock_auto_inc(
3964
/*=======================*/
3965
trx_t* trx) /* in: transaction */
3967
if (trx->auto_inc_lock) {
3968
mutex_enter(&kernel_mutex);
3970
lock_table_dequeue(trx->auto_inc_lock);
3972
mutex_exit(&kernel_mutex);
3976
/*************************************************************************
3977
3984
Releases transaction locks, and releases possible other transactions waiting
3978
3985
because of these locks. */
4066
4078
trx_end_lock_wait(lock->trx);
4081
/* True if a lock mode is S or X */
4082
#define IS_LOCK_S_OR_X(lock) \
4083
(lock_get_mode(lock) == LOCK_S \
4084
|| lock_get_mode(lock) == LOCK_X)
4069
4087
/*************************************************************************
4070
Resets all record and table locks of a transaction on a table to be dropped.
4071
No lock is allowed to be a wait lock. */
4088
Removes locks of a transaction on a table to be dropped.
4089
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
4090
also removed in addition to other table-level and record-level locks.
4091
No lock, that is going to be removed, is allowed to be a wait lock. */
4074
lock_reset_all_on_table_for_trx(
4075
/*============================*/
4076
dict_table_t* table, /* in: table to be dropped */
4077
trx_t* trx) /* in: a transaction */
4094
lock_remove_all_on_table_for_trx(
4095
/*=============================*/
4096
dict_table_t* table, /* in: table to be dropped */
4097
trx_t* trx, /* in: a transaction */
4098
ibool remove_also_table_sx_locks)/* in: also removes
4099
table S and X locks */
4080
4102
lock_t* prev_lock;
4106
4130
/*************************************************************************
4107
Resets all locks, both table and record locks, on a table to be dropped.
4108
No lock is allowed to be a wait lock. */
4131
Removes locks on a table to be dropped or truncated.
4132
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
4133
also removed in addition to other table-level and record-level locks.
4134
No lock, that is going to be removed, is allowed to be a wait lock. */
4111
lock_reset_all_on_table(
4112
/*====================*/
4113
dict_table_t* table) /* in: table to be dropped */
4137
lock_remove_all_on_table(
4138
/*=====================*/
4139
dict_table_t* table, /* in: table to be dropped
4141
ibool remove_also_table_sx_locks)/* in: also removes
4142
table S and X locks */
4117
4147
mutex_enter(&kernel_mutex);
4119
4149
lock = UT_LIST_GET_FIRST(table->locks);
4122
ut_a(!lock_get_wait(lock));
4124
lock_reset_all_on_table_for_trx(table, lock->trx);
4126
lock = UT_LIST_GET_FIRST(table->locks);
4151
while (lock != NULL) {
4153
prev_lock = UT_LIST_GET_PREV(un_member.tab_lock.locks,
4156
/* If we should remove all locks (remove_also_table_sx_locks
4157
is TRUE), or if the lock is not table-level S or X lock,
4158
then check we are not going to remove a wait lock. */
4159
if (remove_also_table_sx_locks
4160
|| !(lock_get_type(lock) == LOCK_TABLE
4161
&& IS_LOCK_S_OR_X(lock))) {
4163
ut_a(!lock_get_wait(lock));
4166
lock_remove_all_on_table_for_trx(table, lock->trx,
4167
remove_also_table_sx_locks);
4169
if (prev_lock == NULL) {
4170
if (lock == UT_LIST_GET_FIRST(table->locks)) {
4171
/* lock was not removed, pick its successor */
4172
lock = UT_LIST_GET_NEXT(
4173
un_member.tab_lock.locks, lock);
4175
/* lock was removed, pick the first one */
4176
lock = UT_LIST_GET_FIRST(table->locks);
4178
} else if (UT_LIST_GET_NEXT(un_member.tab_lock.locks,
4179
prev_lock) != lock) {
4180
/* If lock was removed by
4181
lock_remove_all_on_table_for_trx() then pick the
4182
successor of prev_lock ... */
4183
lock = UT_LIST_GET_NEXT(
4184
un_member.tab_lock.locks, prev_lock);
4186
/* ... otherwise pick the successor of lock. */
4187
lock = UT_LIST_GET_NEXT(
4188
un_member.tab_lock.locks, lock);
4129
4192
mutex_exit(&kernel_mutex);
4266
4329
#ifndef UNIV_HOTBACKUP
4332
/* Print the number of lock structs from lock_print_info_summary() only
4333
in non-production builds for performance reasons, see
4334
http://bugs.mysql.com/36942 */
4335
#define PRINT_NUM_OF_LOCK_STRUCTS
4336
#endif /* UNIV_DEBUG */
4338
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
4267
4339
/*************************************************************************
4268
4340
Calculates the number of record lock structs in the record lock hash table. */
4331
4404
"History list length %lu\n",
4332
4405
(ulong) trx_sys->rseg_history_len);
4407
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
4335
4409
"Total number of lock structs in row lock hash table %lu\n",
4336
4410
(ulong) lock_get_n_rec_locks());
4411
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
4339
4414
/*************************************************************************
4688
4763
block = buf_page_get(space, fil_space_get_zip_size(space),
4689
4764
page_no, RW_X_LATCH, &mtr);
4690
#ifdef UNIV_SYNC_DEBUG
4691
4765
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
4692
#endif /* UNIV_SYNC_DEBUG */
4693
4767
page = block->frame;
4695
4769
lock_mutex_enter_kernel();
5327
5401
/***********************************************************************
5402
Release the last lock from the transaction's autoinc locks. */
5405
lock_release_autoinc_last_lock(
5406
/*===========================*/
5407
ib_vector_t* autoinc_locks) /* in/out: vector of AUTOINC locks */
5412
ut_ad(mutex_own(&kernel_mutex));
5413
ut_a(!ib_vector_is_empty(autoinc_locks));
5415
/* The lock to be release must be the last lock acquired. */
5416
last = ib_vector_size(autoinc_locks) - 1;
5417
lock = ib_vector_get(autoinc_locks, last);
5419
/* Should have only AUTOINC locks in the vector. */
5420
ut_a(lock_get_mode(lock) == LOCK_AUTO_INC);
5421
ut_a(lock_get_type(lock) == LOCK_TABLE);
5423
ut_a(lock->un_member.tab_lock.table != NULL);
5425
/* This will remove the lock from the trx autoinc_locks too. */
5426
lock_table_dequeue(lock);
5429
/***********************************************************************
5430
Release all the transaction's autoinc locks. */
5433
lock_release_autoinc_locks(
5434
/*=======================*/
5435
trx_t* trx) /* in/out: transaction */
5437
ut_ad(mutex_own(&kernel_mutex));
5439
ut_a(trx->autoinc_locks != NULL);
5441
/* We release the locks in the reverse order. This is to
5442
avoid searching the vector for the element to delete at
5443
the lower level. See (lock_table_remove_low()) for details. */
5444
while (!ib_vector_is_empty(trx->autoinc_locks)) {
5446
/* lock_table_remove_low() will also remove the lock from
5447
the transaction's autoinc_locks vector. */
5448
lock_release_autoinc_last_lock(trx->autoinc_locks);
5451
/* Should release all locks. */
5452
ut_a(ib_vector_is_empty(trx->autoinc_locks));
5455
/***********************************************************************
5328
5456
Gets the type of a lock. Non-inline version for using outside of the
5329
5457
lock module. */