mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
72 lines
3 KiB
Text
72 lines
3 KiB
Text
--source include/have_innodb.inc
|
|
--source include/have_debug_sync.inc
|
|
--source include/count_sessions.inc
|
|
|
|
--disable_query_log
|
|
call mtr.add_suppression("InnoDB: Transaction was aborted due to ");
|
|
--enable_query_log
|
|
|
|
# Purge can cause deadlock in the test, requesting page's RW_X_LATCH for trx
|
|
# ids reseting, after trx 2 acqured RW_S_LATCH and suspended in debug sync point
|
|
# lock_trx_handle_wait_enter, waiting for upd_cont signal, which must be
|
|
# emitted after the last SELECT in this test. The last SELECT will hang waiting
|
|
# for purge RW_X_LATCH releasing, and trx 2 will be rolled back by timeout.
|
|
|
|
# There is deadlock_report_before_lock_releasing sync point in
|
|
# Deadlock::report(), which is waiting for sel_cont signal under
|
|
# lock_sys_t lock. The signal must be issued after "UPDATE t SET b = 100"
|
|
# rollback, and that rollback is executing undo record, which is blocked on
|
|
# dict_sys latch request. dict_sys is locked by the thread of statistics
|
|
# update(dict_stats_save()), and during that update lock_sys lock is requested,
|
|
# and can't be acquired as Deadlock::report() holds it. We have to disable
|
|
# statistics update to make the test stable.
|
|
|
|
CREATE TABLE t (a int PRIMARY KEY, b int) engine = InnoDB STATS_PERSISTENT=0;
|
|
CREATE TABLE t2 (a int PRIMARY KEY) engine = InnoDB STATS_PERSISTENT=0;
|
|
|
|
INSERT INTO t VALUES (10, 10), (20, 20), (30, 30);
|
|
INSERT INTO t2 VALUES (10), (20), (30);
|
|
|
|
BEGIN; # trx 1
|
|
# The following update is necessary to increase the transaction weight, which is
|
|
# calculated as the number of locks + the number of undo records during deadlock
|
|
# report. Victim's transaction should have minimum weight. We need trx 2 to be
|
|
# choosen as victim, that's why we need to increase the current transaction
|
|
# weight.
|
|
UPDATE t2 SET a = a + 100;
|
|
SELECT * FROM t WHERE a = 20 FOR UPDATE;
|
|
|
|
--connect(con_2,localhost,root,,)
|
|
# RC is necessary to do semi-consistent read
|
|
SET innodb_snapshot_isolation=OFF;
|
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
|
BEGIN; # trx 2
|
|
# The first time it will be hit on trying to lock (20,20), the second hit
|
|
# will be on (30,30).
|
|
SET DEBUG_SYNC = 'lock_trx_handle_wait_before_unlocked_wait_lock_check SIGNAL upd_locked WAIT_FOR upd_cont';
|
|
# We must not modify primary key fields to cause rr_sequential() read record
|
|
# function choosing in mysql_update(), i.e. both query_plan.using_filesort and
|
|
# query_plan.using_io_buffer must be false during init_read_record() call.
|
|
--send UPDATE t SET b = 100
|
|
|
|
--connection default
|
|
SET DEBUG_SYNC="now WAIT_FOR upd_locked";
|
|
SET DEBUG_SYNC="lock_wait_before_suspend SIGNAL upd_cont";
|
|
--send SELECT * FROM t WHERE a = 10 FOR UPDATE
|
|
|
|
--connection con_2
|
|
# If the bug is not fixed, lock_trx_handle_wait() wrongly returns DB_SUCCESS
|
|
# instead of DB_DEADLOCK, row_search_mvcc() of trx 2 behaves so as if (20,20)
|
|
# was locked. Some debug assertion must crash the server. If the bug is fixed,
|
|
# trx 2 must just be rolled back by deadlock detector.
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
|
|
--disconnect con_2
|
|
|
|
--connection default
|
|
--reap
|
|
SET DEBUG_SYNC = 'RESET';
|
|
DROP TABLE t;
|
|
DROP TABLE t2;
|
|
--source include/wait_until_count_sessions.inc
|