mirror of
https://github.com/MariaDB/server.git
synced 2025-04-22 15:15:41 +02:00

The root cause is the WAL logging of file operation when the actual operation fails afterwards. It creates a situation with a log entry for a operation that would always fail. I could simulate both the backup scenario error and Innodb recovery failure exploiting the weakness. We are following WAL for file rename operation and once logged the operation must eventually complete successfully, or it is a major catastrophe. Right now, we fail for rename and handle it as normal error and it is the problem. I created a patch to address RENAME operation to a non existing schema where the destination schema directory is missing. The patch checks for the missing schema before logging in an attempt to avoid the failure after WAL log is written/flushed. I also checked that the schema cannot be dropped or there cannot be any race with other rename to the same file. This is protected by the MDL lock in SQL today. The patch should this be a good improvement over the current situation and solves the issue at hand.
34 lines
1.2 KiB
Text
34 lines
1.2 KiB
Text
CREATE DATABASE test_jfg;
|
|
CREATE DATABASE test_jfg2;
|
|
CREATE TABLE test_jfg.test (a int unsigned PRIMARY KEY) ENGINE=InnoDB;
|
|
RENAME TABLE test_jfg.test TO test_jfg2.test;
|
|
SELECT REPLACE(path,'\\','/') path
|
|
FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES WHERE PATH LIKE '%test%';
|
|
path
|
|
./test_jfg2/test.ibd
|
|
DROP DATABASE test_jfg;
|
|
# restart
|
|
DROP DATABASE test_jfg2;
|
|
CREATE DATABASE abc_def;
|
|
CREATE DATABASE abc_def2;
|
|
CREATE TABLE abc_def.test (a int unsigned PRIMARY KEY) ENGINE=InnoDB;
|
|
RENAME TABLE abc_def.test TO abc_def2.test1;
|
|
SELECT REPLACE(path,'\\','/') path
|
|
FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES WHERE PATH LIKE '%test%';
|
|
path
|
|
./abc_def2/test1.ibd
|
|
DROP DATABASE abc_def;
|
|
# restart
|
|
DROP DATABASE abc_def2;
|
|
call mtr.add_suppression("InnoDB: Cannot rename '.*t1.ibd' to '.*non_existing_db.*' because the target schema directory doesn't exist");
|
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
|
INSERT INTO t1 VALUES(100);
|
|
RENAME TABLE t1 TO non_existing_db.t1;
|
|
ERROR HY000: Error on rename of './test/t1' to './non_existing_db/t1' (errno: 168 "Unknown (generic) error from engine")
|
|
FOUND 1 /\[ERROR\] InnoDB: Cannot rename '.*t1\.ibd' to '.*non_existing_db/ in mysqld.1.err
|
|
SET GLOBAL innodb_fast_shutdown=2;
|
|
# restart
|
|
SELECT * FROM t1;
|
|
a
|
|
100
|
|
DROP TABLE t1;
|