mirror of
https://github.com/MariaDB/server.git
synced 2025-08-27 13:04:36 +03:00
The SQL layer never acquires metadata locks (MDL) on the tables that the tables that DML statement accesses is modifying. However, the storage engine must access the parent table in order to ensure that the child table will not refer to a non-existing record in the parent table. During certain DDL operations, the InnoDB table metadata (dict_table_t) may be be freed and rebuilt. This would cause a race condition with a concurrent INSERT that is attempting to report a FOREIGN KEY violation. We work around the insufficient MDL during DML by acquiring exclusive InnoDB table locks on all child tables during DDL. To avoid deadlocks, we will follow the following order of acquisition: 1. tables whose REFERENCES clauses point to the current table 2. the current table that is being subjected to DDL 3. mysql.innodb_table_stats 4. mysql.innodb_index_stats 5. the InnoDB dictionary tables (SYS_TABLES and so on) 6. exclusive dict_sys.latch
84 lines
3.5 KiB
Plaintext
84 lines
3.5 KiB
Plaintext
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
|
|
SET GLOBAL innodb_file_per_table=1;
|
|
#
|
|
# Bug#21644827 - FTS, ASSERT !SRV_READ_ONLY_MODE || M_IMPL.M_LOG_MODE ==
|
|
# MTR_LOG_NO_REDO
|
|
#
|
|
SET GLOBAL innodb_file_per_table=ON;
|
|
create table t1 (a int not null, d varchar(15) not null, b
|
|
varchar(198) not null, c char(156)) engine=InnoDB
|
|
row_format=redundant;
|
|
insert into t1 values(123, 'abcdef', 'jghikl', 'mnop');
|
|
insert into t1 values(456, 'abcdef', 'jghikl', 'mnop');
|
|
insert into t1 values(789, 'abcdef', 'jghikl', 'mnop');
|
|
insert into t1 values(134, 'kasdfsdsadf', 'adfjlasdkfjasd', 'adfsadflkasdasdfljasdf');
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
insert into t1 select * from t1;
|
|
SET GLOBAL innodb_file_per_table=OFF;
|
|
create table t2 (a int not null, d varchar(15) not null, b
|
|
varchar(198) not null, c char(156), fulltext ftsic(c)) engine=InnoDB
|
|
row_format=redundant;
|
|
insert into t2 select * from t1;
|
|
create table t3 (a int not null, d varchar(15) not null, b varchar(198),
|
|
c varchar(150), index k1(c(99), b(56)), index k2(b(5), c(10))) engine=InnoDB
|
|
row_format=redundant;
|
|
insert into t3 values(444, 'dddd', 'bbbbb', 'aaaaa');
|
|
insert into t3 values(555, 'eeee', 'ccccc', 'aaaaa');
|
|
SET GLOBAL innodb_fast_shutdown=0;
|
|
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --innodb-read-only
|
|
SELECT COUNT(*) FROM t1;
|
|
COUNT(*)
|
|
4096
|
|
SELECT COUNT(*) FROM t2;
|
|
COUNT(*)
|
|
4096
|
|
SELECT COUNT(*) FROM t3;
|
|
COUNT(*)
|
|
2
|
|
TRUNCATE TABLE t1;
|
|
ERROR HY000: Table 't1' is read only
|
|
TRUNCATE TABLE t2;
|
|
ERROR HY000: Table 't2' is read only
|
|
TRUNCATE TABLE t3;
|
|
ERROR HY000: Table 't3' is read only
|
|
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
|
|
TRUNCATE TABLE t1;
|
|
TRUNCATE TABLE t2;
|
|
TRUNCATE TABLE t3;
|
|
corrupted SYS_TABLES.MIX_LEN for test/t1
|
|
corrupted SYS_TABLES.MIX_LEN for test/t2
|
|
corrupted SYS_TABLES.MIX_LEN for test/t3
|
|
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
|
|
TRUNCATE TABLE t1;
|
|
ERROR 42S02: Table 'test.t1' doesn't exist in engine
|
|
TRUNCATE TABLE t2;
|
|
TRUNCATE TABLE t3;
|
|
SELECT COUNT(*) FROM t1;
|
|
ERROR 42S02: Table 'test.t1' doesn't exist in engine
|
|
SELECT COUNT(*) FROM t2;
|
|
COUNT(*)
|
|
0
|
|
SELECT COUNT(*) FROM t3;
|
|
COUNT(*)
|
|
0
|
|
RENAME TABLE t1 TO tee_one;
|
|
ERROR HY000: Error on rename of './test/t1' to './test/tee_one' (errno: 155 "The table does not exist in the storage engine")
|
|
DROP TABLE t1;
|
|
Warnings:
|
|
Warning 1932 Table 'test.t1' doesn't exist in engine
|
|
DROP TABLE t2,t3;
|
|
FOUND 6 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
|
|
# restart
|
|
ib_buffer_pool
|
|
ib_logfile0
|
|
ibdata1
|
|
db.opt
|