mariadb/mysql-test/suite/innodb/t/alter_large_dml.test
Thirunarayanan Balathandayuthapani 64900e3d7c MDEV-15641 InnoDB crash while committing table-rebuilding ALTER TABLE
Problem:
========
 There is a possibility that there can be more concurrent DMLs While the
alter table thread is waiting for upgrading to MDL_EXCLUSIVE before commit phase.
In commit phase, InnoDB acquires dict_operation_lock and it already holds MDL_EXCLUSIVE
on the table. After that, InnoDB applies the concurrent DML logs in commit phase.
This could lead to blocking of the following things:

  1) DML on the particular table (due to MDL_EXCLUSIVE on the table)
  2) InnoDB DDLs (due to dict_operation_lock)
  3) Purge thread, stats thread, the master thread (due to dict_operation_lock)

Fix:
====
Apply the concurrent DML logs in commit phase but before acquiring
dict_operation_lock in commit phase. It makes sure that (2), (3) can't be
blocked for longer time.
2019-07-10 12:43:51 +05:30

53 lines
1.6 KiB
Text

--source include/big_test.inc
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_sequence.inc
CREATE TABLE t1(f1 char(200), f2 char(200), f3 char(200),
f4 char(200), f5 char(200), f6 char(200),
f7 char(200), f8 char(200))ENGINE=InnoDB;
INSERT INTO t1 SELECT '','','','','','','','' FROM seq_1_to_16384;
SET DEBUG_SYNC = 'inplace_after_index_build SIGNAL rebuilt WAIT_FOR dml_pause';
SET DEBUG_SYNC = 'alter_table_inplace_before_lock_upgrade SIGNAL dml_restart WAIT_FOR dml_done';
SET DEBUG_SYNC = 'row_log_table_apply2_before SIGNAL ddl_start';
--send
ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
--connect(con1,localhost,root,,test)
SET DEBUG_SYNC = 'now WAIT_FOR rebuilt';
BEGIN;
INSERT INTO t1 SELECT '','','','','','','','' FROM seq_1_to_16384;
SET DEBUG_SYNC = 'now SIGNAL dml_pause';
SET DEBUG_SYNC = 'now WAIT_FOR dml_restart';
ROLLBACK;
BEGIN;
INSERT INTO t1 SELECT '','','','','','','','' FROM seq_1_to_16384;
INSERT INTO t1 SELECT '','','','','','','','' FROM seq_1_to_16384;
INSERT INTO t1 SELECT '','','','','','','','' FROM seq_1_to_16384;
INSERT INTO t1 SELECT '','','','','','','','' FROM seq_1_to_16384;
INSERT INTO t1 SELECT '','','','','','','','' FROM seq_1_to_16384;
ROLLBACK;
BEGIN;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
ROLLBACK;
SET DEBUG_SYNC = 'now SIGNAL dml_done';
--connect(con2, localhost,root,,test)
SET DEBUG_SYNC = 'now WAIT_FOR ddl_start';
CREATE TABLE t2(f1 INT NOT NULL)ENGINE=InnoDB;
connection default;
reap;
SHOW CREATE TABLE t1;
SELECT COUNT(*) FROM t1;
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1, t2;