MDEV-18288 Transportable Tablespaces leave AUTO_INCREMENT in mismatched state,...

MDEV-18288 Transportable Tablespaces leave AUTO_INCREMENT in mismatched state, causing INSERT errors in newly imported tables when .cfg is not used.

During import, if cfg file is not specified, we don't update the autoinc
field in innodb dictionary object dict_table_t. The next insert tries to
insert from the starting position of auto increment and fails.

It can be observed that the issue is resolved once server is restarted
as the persistent value is read correctly from PAGE_ROOT_AUTO_INC from
index root page. The patch fixes the issue by reading the the auto
increment value directly from PAGE_ROOT_AUTO_INC during import if cfg
file is not specified.

Test Fix:

1. import_bugs.test: Embedded mode warning has absolute path. Regular
expression replacement in test.

2. full_crc32_import.test: Table level auto increment mismatch after
import. It was using the auto increment data from the table prior to
discard and import which is not right. This value has cached auto
increment value higher than the actual inserted value and value stored
in PAGE_ROOT_AUTO_INC. Updated the result file and added validation for
checking the maximum value of auto increment column.
parent 6fadbf8e
...@@ -48,7 +48,15 @@ t1 CREATE TABLE `t1` ( ...@@ -48,7 +48,15 @@ t1 CREATE TABLE `t1` (
`b` blob DEFAULT NULL, `b` blob DEFAULT NULL,
`c` blob DEFAULT NULL, `c` blob DEFAULT NULL,
PRIMARY KEY (`a`) PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC ) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
# Auto increment value must be more than maximum column value
SELECT MAX(a) FROM t1;
MAX(a)
45
SELECT auto_increment FROM information_schema.tables
WHERE table_name like 't1';
auto_increment
46
UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200); UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200);
explain SELECT a FROM t1 where b = repeat("de", 100); explain SELECT a FROM t1 where b = repeat("de", 100);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
...@@ -130,7 +138,15 @@ t1 CREATE TABLE `t1` ( ...@@ -130,7 +138,15 @@ t1 CREATE TABLE `t1` (
`c2` point NOT NULL, `c2` point NOT NULL,
`c3` linestring NOT NULL, `c3` linestring NOT NULL,
PRIMARY KEY (`c1`) PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=16372 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC ) ENGINE=InnoDB AUTO_INCREMENT=14325 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
# Auto increment value must be more than maximum column value
SELECT MAX(c1) FROM t1;
MAX(c1)
14324
SELECT auto_increment FROM information_schema.tables
WHERE table_name like 't1';
auto_increment
14325
UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)'); UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)');
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
COUNT(*) COUNT(*)
......
...@@ -10,3 +10,38 @@ ALTER TABLE imp_t1 IMPORT TABLESPACE; ...@@ -10,3 +10,38 @@ ALTER TABLE imp_t1 IMPORT TABLESPACE;
ERROR HY000: Schema mismatch (ROW_FORMAT mismatch) ERROR HY000: Schema mismatch (ROW_FORMAT mismatch)
DROP TABLE imp_t1, t1; DROP TABLE imp_t1, t1;
SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm; SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm;
#
# MDEV-18288: Transportable Tablespaces leave AUTO_INCREMENT in mismatched
# state, causing INSERT errors in newly imported tables when .cfg is not used.
#
CREATE TABLE t1(
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE t2 LIKE t1;
ALTER TABLE t2 DISCARD TABLESPACE;
INSERT INTO t1() VALUES();
INSERT INTO t1() VALUES();
FLUSH TABLES test.t1 FOR EXPORT;
# Copy data file
# Skip CFG file copy
UNLOCK TABLES;
DROP TABLE t1;
ALTER TABLE t2 IMPORT TABLESPACE;
Warnings:
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification
SELECT * FROM t2 ORDER BY id;
id
1
2
INSERT INTO t2() VALUES();
INSERT INTO t2() VALUES();
INSERT INTO t2() VALUES();
SELECT * FROM t2 ORDER BY id;
id
1
2
3
4
5
DROP TABLE t2;
...@@ -60,6 +60,12 @@ ALTER TABLE t1 DROP INDEX b; ...@@ -60,6 +60,12 @@ ALTER TABLE t1 DROP INDEX b;
ALTER TABLE t1 IMPORT TABLESPACE; ALTER TABLE t1 IMPORT TABLESPACE;
--enable_warnings --enable_warnings
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--echo # Auto increment value must be more than maximum column value
SELECT MAX(a) FROM t1;
SELECT auto_increment FROM information_schema.tables
WHERE table_name like 't1';
UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200); UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200);
--replace_column 9 # --replace_column 9 #
explain SELECT a FROM t1 where b = repeat("de", 100); explain SELECT a FROM t1 where b = repeat("de", 100);
...@@ -142,6 +148,12 @@ ALTER TABLE t1 DROP INDEX idx1; ...@@ -142,6 +148,12 @@ ALTER TABLE t1 DROP INDEX idx1;
ALTER TABLE t1 IMPORT TABLESPACE; ALTER TABLE t1 IMPORT TABLESPACE;
--disable_warnings --disable_warnings
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--echo # Auto increment value must be more than maximum column value
SELECT MAX(c1) FROM t1;
SELECT auto_increment FROM information_schema.tables
WHERE table_name like 't1';
UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)'); UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)');
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
DELETE FROM t1; DELETE FROM t1;
......
...@@ -17,3 +17,44 @@ ALTER TABLE imp_t1 IMPORT TABLESPACE; ...@@ -17,3 +17,44 @@ ALTER TABLE imp_t1 IMPORT TABLESPACE;
DROP TABLE imp_t1, t1; DROP TABLE imp_t1, t1;
SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm; SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm;
--echo #
--echo # MDEV-18288: Transportable Tablespaces leave AUTO_INCREMENT in mismatched
--echo # state, causing INSERT errors in newly imported tables when .cfg is not used.
--echo #
CREATE TABLE t1(
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE t2 LIKE t1;
ALTER TABLE t2 DISCARD TABLESPACE;
INSERT INTO t1() VALUES();
INSERT INTO t1() VALUES();
FLUSH TABLES test.t1 FOR EXPORT;
--echo # Copy data file
--copy_file $datadir/test/t1.ibd $datadir/test/t2.ibd
--echo # Skip CFG file copy
#--copy_file $datadir/test/t1.cfg $datadir/test/t2.cfg
--remove_file $datadir/test/t1.cfg
UNLOCK TABLES;
DROP TABLE t1;
--replace_regex /opening '.*\/test\//opening '.\/test\//
ALTER TABLE t2 IMPORT TABLESPACE;
SELECT * FROM t2 ORDER BY id;
INSERT INTO t2() VALUES();
INSERT INTO t2() VALUES();
INSERT INTO t2() VALUES();
SELECT * FROM t2 ORDER BY id;
DROP TABLE t2;
...@@ -4718,13 +4718,16 @@ row_import_for_mysql( ...@@ -4718,13 +4718,16 @@ row_import_for_mysql(
table->flags2 &= ~DICT_TF2_DISCARDED & ((1U << DICT_TF2_BITS) - 1); table->flags2 &= ~DICT_TF2_DISCARDED & ((1U << DICT_TF2_BITS) - 1);
/* Set autoinc value read from .cfg file, if one was specified. /* Set autoinc value read from .cfg file, if one was specified.
Otherwise, keep the PAGE_ROOT_AUTO_INC as is. */ Otherwise, read the PAGE_ROOT_AUTO_INC and set it to table autoinc. */
if (autoinc) { if (autoinc) {
ib::info() << table->name << " autoinc value set to " ib::info() << table->name << " autoinc value set to "
<< autoinc; << autoinc;
table->autoinc = autoinc--; table->autoinc = autoinc--;
btr_write_autoinc(dict_table_get_first_index(table), autoinc); btr_write_autoinc(dict_table_get_first_index(table), autoinc);
} else if (table->persistent_autoinc) {
autoinc = btr_read_autoinc(dict_table_get_first_index(table));
table->autoinc = ++autoinc;
} }
return(row_import_cleanup(prebuilt, trx, err)); return(row_import_cleanup(prebuilt, trx, err));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment