mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Bug#59354 : Bug #12659252 : ASSERT !OTHER_LOCK AT LOCK_REC_ADD_TO_QUEUE DURING A DELETE OPERATION
The converted implicit lock should wait for the prior conflicting lock if found. rb://1437 approved by Marko
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
SET @start_global_value = @@global.innodb_trx_purge_view_update_only_debug;
|
||||
SELECT @start_global_value;
|
||||
@start_global_value
|
||||
0
|
||||
select @@global.innodb_trx_purge_view_update_only_debug in (0, 1);
|
||||
@@global.innodb_trx_purge_view_update_only_debug in (0, 1)
|
||||
1
|
||||
select @@global.innodb_trx_purge_view_update_only_debug;
|
||||
@@global.innodb_trx_purge_view_update_only_debug
|
||||
0
|
||||
select @@session.innodb_trx_purge_view_update_only_debug;
|
||||
ERROR HY000: Variable 'innodb_trx_purge_view_update_only_debug' is a GLOBAL variable
|
||||
show global variables like 'innodb_trx_purge_view_update_only_debug';
|
||||
Variable_name Value
|
||||
innodb_trx_purge_view_update_only_debug OFF
|
||||
show session variables like 'innodb_trx_purge_view_update_only_debug';
|
||||
Variable_name Value
|
||||
innodb_trx_purge_view_update_only_debug OFF
|
||||
select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
|
||||
select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
|
||||
set global innodb_trx_purge_view_update_only_debug=1;
|
||||
select @@global.innodb_trx_purge_view_update_only_debug;
|
||||
@@global.innodb_trx_purge_view_update_only_debug
|
||||
1
|
||||
select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG ON
|
||||
select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG ON
|
||||
set @@global.innodb_trx_purge_view_update_only_debug=0;
|
||||
select @@global.innodb_trx_purge_view_update_only_debug;
|
||||
@@global.innodb_trx_purge_view_update_only_debug
|
||||
0
|
||||
select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
|
||||
select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
|
||||
set session innodb_trx_purge_view_update_only_debug='some';
|
||||
ERROR HY000: Variable 'innodb_trx_purge_view_update_only_debug' is a GLOBAL variable and should be set with SET GLOBAL
|
||||
set @@session.innodb_trx_purge_view_update_only_debug='some';
|
||||
ERROR HY000: Variable 'innodb_trx_purge_view_update_only_debug' is a GLOBAL variable and should be set with SET GLOBAL
|
||||
set global innodb_trx_purge_view_update_only_debug=1.1;
|
||||
ERROR 42000: Incorrect argument type to variable 'innodb_trx_purge_view_update_only_debug'
|
||||
set global innodb_trx_purge_view_update_only_debug='foo';
|
||||
ERROR 42000: Variable 'innodb_trx_purge_view_update_only_debug' can't be set to the value of 'foo'
|
||||
set global innodb_trx_purge_view_update_only_debug=-2;
|
||||
set global innodb_trx_purge_view_update_only_debug=1e1;
|
||||
ERROR 42000: Incorrect argument type to variable 'innodb_trx_purge_view_update_only_debug'
|
||||
set global innodb_trx_purge_view_update_only_debug=2;
|
||||
ERROR 42000: Variable 'innodb_trx_purge_view_update_only_debug' can't be set to the value of '2'
|
||||
SET @@global.innodb_trx_purge_view_update_only_debug = @start_global_value;
|
||||
SELECT @@global.innodb_trx_purge_view_update_only_debug;
|
||||
@@global.innodb_trx_purge_view_update_only_debug
|
||||
0
|
@@ -0,0 +1,53 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug.inc
|
||||
|
||||
SET @start_global_value = @@global.innodb_trx_purge_view_update_only_debug;
|
||||
SELECT @start_global_value;
|
||||
|
||||
#
|
||||
# exists as global only
|
||||
#
|
||||
select @@global.innodb_trx_purge_view_update_only_debug in (0, 1);
|
||||
select @@global.innodb_trx_purge_view_update_only_debug;
|
||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
select @@session.innodb_trx_purge_view_update_only_debug;
|
||||
show global variables like 'innodb_trx_purge_view_update_only_debug';
|
||||
show session variables like 'innodb_trx_purge_view_update_only_debug';
|
||||
select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
|
||||
#
|
||||
# show that it's writable
|
||||
#
|
||||
set global innodb_trx_purge_view_update_only_debug=1;
|
||||
select @@global.innodb_trx_purge_view_update_only_debug;
|
||||
select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
set @@global.innodb_trx_purge_view_update_only_debug=0;
|
||||
select @@global.innodb_trx_purge_view_update_only_debug;
|
||||
select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
|
||||
--error ER_GLOBAL_VARIABLE
|
||||
set session innodb_trx_purge_view_update_only_debug='some';
|
||||
--error ER_GLOBAL_VARIABLE
|
||||
set @@session.innodb_trx_purge_view_update_only_debug='some';
|
||||
|
||||
#
|
||||
# incorrect types
|
||||
#
|
||||
--error ER_WRONG_TYPE_FOR_VAR
|
||||
set global innodb_trx_purge_view_update_only_debug=1.1;
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
set global innodb_trx_purge_view_update_only_debug='foo';
|
||||
set global innodb_trx_purge_view_update_only_debug=-2;
|
||||
--error ER_WRONG_TYPE_FOR_VAR
|
||||
set global innodb_trx_purge_view_update_only_debug=1e1;
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
set global innodb_trx_purge_view_update_only_debug=2;
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
|
||||
SET @@global.innodb_trx_purge_view_update_only_debug = @start_global_value;
|
||||
SELECT @@global.innodb_trx_purge_view_update_only_debug;
|
@@ -696,6 +696,8 @@ static SHOW_VAR innodb_status_variables[]= {
|
||||
#ifdef UNIV_DEBUG
|
||||
{"purge_trx_id_age",
|
||||
(char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG},
|
||||
{"purge_view_trx_id_age",
|
||||
(char*) &export_vars.innodb_purge_view_trx_id_age, SHOW_LONG},
|
||||
#endif /* UNIV_DEBUG */
|
||||
{NullS, NullS, SHOW_LONG}
|
||||
};
|
||||
@@ -11689,6 +11691,13 @@ static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug,
|
||||
btr_cur_limit_optimistic_insert_debug, PLUGIN_VAR_RQCMDARG,
|
||||
"Artificially limit the number of records per B-tree page (0=unlimited).",
|
||||
NULL, NULL, 0, 0, UINT_MAX32, 0);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug,
|
||||
srv_purge_view_update_only_debug, PLUGIN_VAR_NOCMDARG,
|
||||
"Pause actual purging any delete-marked records, but merely update the purge view. "
|
||||
"It is to create artificially the situation the purge view have been updated "
|
||||
"but the each purges were not done yet.",
|
||||
NULL, NULL, FALSE);
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks,
|
||||
@@ -11768,6 +11777,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
#ifdef UNIV_DEBUG
|
||||
MYSQL_SYSVAR(trx_rseg_n_slots_debug),
|
||||
MYSQL_SYSVAR(limit_optimistic_insert_debug),
|
||||
MYSQL_SYSVAR(trx_purge_view_update_only_debug),
|
||||
#endif /* UNIV_DEBUG */
|
||||
MYSQL_SYSVAR(print_all_deadlocks),
|
||||
NULL
|
||||
|
@@ -797,14 +797,22 @@ lock_rec_get_page_no(
|
||||
remains set when the waiting lock is granted,
|
||||
or if the lock is inherited to a neighboring
|
||||
record */
|
||||
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK
|
||||
#define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created
|
||||
by other transaction */
|
||||
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_MODE_MASK
|
||||
# error
|
||||
#endif
|
||||
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK
|
||||
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK
|
||||
# error
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/** Checks if this is a waiting lock created by lock->trx itself.
|
||||
@param type_mode lock->type_mode
|
||||
@return whether it is a waiting lock belonging to lock->trx */
|
||||
#define lock_is_wait_not_by_other(type_mode) \
|
||||
((type_mode & (LOCK_CONV_BY_OTHER | LOCK_WAIT)) == LOCK_WAIT)
|
||||
|
||||
/** Lock operation struct */
|
||||
typedef struct lock_op_struct lock_op_t;
|
||||
/** Lock operation struct */
|
||||
|
@@ -265,6 +265,10 @@ extern ulint srv_fatal_semaphore_wait_threshold;
|
||||
#define SRV_SEMAPHORE_WAIT_EXTENSION 7200
|
||||
extern ulint srv_dml_needed_delay;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
extern my_bool srv_purge_view_update_only_debug;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
|
||||
query threads, and lock table: we allocate
|
||||
it from dynamic memory to get it to the
|
||||
@@ -747,6 +751,8 @@ struct export_var_struct{
|
||||
ulint innodb_truncated_status_writes; /*!< srv_truncated_status_writes */
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint innodb_purge_trx_id_age; /*!< max_trx_id - purged trx_id */
|
||||
ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id
|
||||
- purged view's min trx_id */
|
||||
#endif /* UNIV_DEBUG */
|
||||
};
|
||||
|
||||
|
@@ -789,12 +789,16 @@ lock_reset_lock_and_trx_wait(
|
||||
/*=========================*/
|
||||
lock_t* lock) /*!< in: record lock */
|
||||
{
|
||||
ut_ad((lock->trx)->wait_lock == lock);
|
||||
ut_ad(lock_get_wait(lock));
|
||||
|
||||
/* Reset the back pointer in trx to this waiting lock request */
|
||||
|
||||
if (!(lock->type_mode & LOCK_CONV_BY_OTHER)) {
|
||||
ut_ad((lock->trx)->wait_lock == lock);
|
||||
(lock->trx)->wait_lock = NULL;
|
||||
} else {
|
||||
ut_ad(lock_get_type_low(lock) == LOCK_REC);
|
||||
}
|
||||
lock->type_mode &= ~LOCK_WAIT;
|
||||
}
|
||||
|
||||
@@ -1430,9 +1434,9 @@ lock_rec_has_expl(
|
||||
|
||||
while (lock) {
|
||||
if (lock->trx == trx
|
||||
&& !lock_is_wait_not_by_other(lock->type_mode)
|
||||
&& lock_mode_stronger_or_eq(lock_get_mode(lock),
|
||||
precise_mode & LOCK_MODE_MASK)
|
||||
&& !lock_get_wait(lock)
|
||||
&& (!lock_rec_get_rec_not_gap(lock)
|
||||
|| (precise_mode & LOCK_REC_NOT_GAP)
|
||||
|| heap_no == PAGE_HEAP_NO_SUPREMUM)
|
||||
@@ -1730,7 +1734,7 @@ lock_rec_create(
|
||||
|
||||
HASH_INSERT(lock_t, hash, lock_sys->rec_hash,
|
||||
lock_rec_fold(space, page_no), lock);
|
||||
if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
|
||||
if (lock_is_wait_not_by_other(type_mode)) {
|
||||
|
||||
lock_set_lock_and_trx_wait(lock, trx);
|
||||
}
|
||||
@@ -1761,10 +1765,11 @@ lock_rec_enqueue_waiting(
|
||||
const buf_block_t* block, /*!< in: buffer block containing
|
||||
the record */
|
||||
ulint heap_no,/*!< in: heap number of the record */
|
||||
lock_t* lock, /*!< in: lock object; NULL if a new
|
||||
one should be created. */
|
||||
dict_index_t* index, /*!< in: index of record */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
lock_t* lock;
|
||||
trx_t* trx;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
@@ -1799,9 +1804,17 @@ lock_rec_enqueue_waiting(
|
||||
ut_ad(0);
|
||||
}
|
||||
|
||||
if (lock == NULL) {
|
||||
/* Enqueue the lock request that will wait to be granted */
|
||||
lock = lock_rec_create(type_mode | LOCK_WAIT,
|
||||
block, heap_no, index, trx);
|
||||
} else {
|
||||
ut_ad(lock->type_mode & LOCK_WAIT);
|
||||
ut_ad(lock->type_mode & LOCK_CONV_BY_OTHER);
|
||||
|
||||
lock->type_mode &= ~LOCK_CONV_BY_OTHER;
|
||||
lock_set_lock_and_trx_wait(lock, trx);
|
||||
}
|
||||
|
||||
/* Check if a deadlock occurs: if yes, remove the lock request and
|
||||
return an error code */
|
||||
@@ -2046,6 +2059,7 @@ lock_rec_lock_slow(
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
trx_t* trx;
|
||||
lock_t* lock;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
|
||||
@@ -2060,7 +2074,27 @@ lock_rec_lock_slow(
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
if (lock_rec_has_expl(mode, block, heap_no, trx)) {
|
||||
lock = lock_rec_has_expl(mode, block, heap_no, trx);
|
||||
if (lock) {
|
||||
if (lock->type_mode & LOCK_CONV_BY_OTHER) {
|
||||
/* This lock or lock waiting was created by the other
|
||||
transaction, not by the transaction (trx) itself.
|
||||
So, the transaction (trx) should treat it collectly
|
||||
according as whether granted or not. */
|
||||
|
||||
if (lock->type_mode & LOCK_WAIT) {
|
||||
/* This lock request was not granted yet.
|
||||
Should wait for granted. */
|
||||
|
||||
goto enqueue_waiting;
|
||||
} else {
|
||||
/* This lock request was already granted.
|
||||
Just clearing the flag. */
|
||||
|
||||
lock->type_mode &= ~LOCK_CONV_BY_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/* The trx already has a strong enough lock on rec: do
|
||||
nothing */
|
||||
|
||||
@@ -2070,8 +2104,10 @@ lock_rec_lock_slow(
|
||||
the queue, as this transaction does not have a lock strong
|
||||
enough already granted on the record, we have to wait. */
|
||||
|
||||
ut_ad(lock == NULL);
|
||||
enqueue_waiting:
|
||||
return(lock_rec_enqueue_waiting(mode, block, heap_no,
|
||||
index, thr));
|
||||
lock, index, thr));
|
||||
} else if (!impl) {
|
||||
/* Set the requested lock on the record */
|
||||
|
||||
@@ -2213,7 +2249,8 @@ lock_grant(
|
||||
TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait
|
||||
for it */
|
||||
|
||||
if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
|
||||
if (!(lock->type_mode & LOCK_CONV_BY_OTHER)
|
||||
&& lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
|
||||
trx_end_lock_wait(lock->trx);
|
||||
}
|
||||
}
|
||||
@@ -2230,6 +2267,7 @@ lock_rec_cancel(
|
||||
{
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad(lock_get_type_low(lock) == LOCK_REC);
|
||||
ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER));
|
||||
|
||||
/* Reset the bit (there can be only one set bit) in the lock bitmap */
|
||||
lock_rec_reset_nth_bit(lock, lock_rec_find_set_bit(lock));
|
||||
@@ -2372,8 +2410,12 @@ lock_rec_reset_and_release_wait(
|
||||
lock = lock_rec_get_first(block, heap_no);
|
||||
|
||||
while (lock != NULL) {
|
||||
if (lock_get_wait(lock)) {
|
||||
if (lock_is_wait_not_by_other(lock->type_mode)) {
|
||||
lock_rec_cancel(lock);
|
||||
} else if (lock_get_wait(lock)) {
|
||||
/* just reset LOCK_WAIT */
|
||||
lock_rec_reset_nth_bit(lock, heap_no);
|
||||
lock_reset_lock_and_trx_wait(lock);
|
||||
} else {
|
||||
lock_rec_reset_nth_bit(lock, heap_no);
|
||||
}
|
||||
@@ -3646,6 +3688,7 @@ lock_table_create(
|
||||
|
||||
ut_ad(table && trx);
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad(!(type_mode & LOCK_CONV_BY_OTHER));
|
||||
|
||||
if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) {
|
||||
++table->n_waiting_or_granted_auto_inc_locks;
|
||||
@@ -4199,6 +4242,7 @@ lock_cancel_waiting_and_release(
|
||||
lock_t* lock) /*!< in: waiting lock request */
|
||||
{
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER));
|
||||
|
||||
if (lock_get_type_low(lock) == LOCK_REC) {
|
||||
|
||||
@@ -5240,7 +5284,7 @@ lock_rec_insert_check_and_lock(
|
||||
err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP
|
||||
| LOCK_INSERT_INTENTION,
|
||||
block, next_rec_heap_no,
|
||||
index, thr);
|
||||
NULL, index, thr);
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
@@ -5316,10 +5360,23 @@ lock_rec_convert_impl_to_expl(
|
||||
|
||||
if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, block,
|
||||
heap_no, impl_trx)) {
|
||||
ulint type_mode = (LOCK_REC | LOCK_X
|
||||
| LOCK_REC_NOT_GAP);
|
||||
|
||||
/* If the delete-marked record was locked already,
|
||||
we should reserve lock waiting for impl_trx as
|
||||
implicit lock. Because cannot lock at this moment.*/
|
||||
|
||||
if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))
|
||||
&& lock_rec_other_has_conflicting(
|
||||
LOCK_X | LOCK_REC_NOT_GAP, block,
|
||||
heap_no, impl_trx)) {
|
||||
|
||||
type_mode |= (LOCK_WAIT | LOCK_CONV_BY_OTHER);
|
||||
}
|
||||
|
||||
lock_rec_add_to_queue(
|
||||
LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP,
|
||||
block, heap_no, index, impl_trx);
|
||||
type_mode, block, heap_no, index, impl_trx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2254,7 +2254,10 @@ row_ins_index_entry(
|
||||
err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,
|
||||
n_ext, thr);
|
||||
if (err != DB_FAIL) {
|
||||
|
||||
if (index == dict_table_get_first_index(index->table)
|
||||
&& thr_get_trx(thr)->mysql_thd != 0) {
|
||||
DEBUG_SYNC_C("row_ins_clust_index_entry_leaf_after");
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
@@ -2103,6 +2103,14 @@ srv_export_innodb_status(void)
|
||||
export_vars.innodb_purge_trx_id_age =
|
||||
trx_sys->max_trx_id - purge_sys->done_trx_no;
|
||||
}
|
||||
|
||||
if (!purge_sys->view
|
||||
|| trx_sys->max_trx_id < purge_sys->view->up_limit_id) {
|
||||
export_vars.innodb_purge_view_trx_id_age = 0;
|
||||
} else {
|
||||
export_vars.innodb_purge_view_trx_id_age =
|
||||
trx_sys->max_trx_id - purge_sys->view->up_limit_id;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
mutex_exit(&srv_innodb_monitor_mutex);
|
||||
|
@@ -61,6 +61,10 @@ UNIV_INTERN mysql_pfs_key_t trx_purge_latch_key;
|
||||
UNIV_INTERN mysql_pfs_key_t purge_sys_bh_mutex_key;
|
||||
#endif /* UNIV_PFS_MUTEX */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
UNIV_INTERN my_bool srv_purge_view_update_only_debug;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/*****************************************************************//**
|
||||
Checks if trx_id is >= purge_view: then it is guaranteed that its update
|
||||
undo log still exists in the system.
|
||||
@@ -1180,6 +1184,12 @@ trx_purge(
|
||||
|
||||
rw_lock_x_unlock(&(purge_sys->latch));
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (srv_purge_view_update_only_debug) {
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
purge_sys->state = TRX_PURGE_ON;
|
||||
|
||||
purge_sys->handle_limit = purge_sys->n_pages_handled + limit;
|
||||
|
Reference in New Issue
Block a user