diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result new file mode 100644 index 00000000000..7e4ba8e67eb --- /dev/null +++ b/mysql-test/main/derived_split_innodb.result @@ -0,0 +1,60 @@ +# +# MDEV-16917: do not use splitting for derived with join cache +# +CREATE TABLE t1 ( +n1 int(10) NOT NULL, +n2 int(10) NOT NULL, +c1 char(1) NOT NULL, +KEY c1 (c1), +KEY n1_c1_n2 (n1,c1,n2) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (0, 2, 'a'), (1, 3, 'a'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +EXPLAIN SELECT t1.n1 FROM t1, (SELECT n1, n2 FROM t1 WHERE c1 = 'a' GROUP BY n1) as t +WHERE t.n1 = t1.n1 AND t.n2 = t1.n2 AND c1 = 'a' GROUP BY n1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index c1,n1_c1_n2 n1_c1_n2 9 NULL 2 Using where; Using index +1 PRIMARY ref key0 key0 8 test.t1.n1,test.t1.n2 2 +2 LATERAL DERIVED t1 ref c1,n1_c1_n2 n1_c1_n2 4 test.t1.n1 1 Using where; Using index +SELECT t1.n1 FROM t1, (SELECT n1, n2 FROM t1 WHERE c1 = 'a' GROUP BY n1) as t +WHERE t.n1 = t1.n1 AND t.n2 = t1.n2 AND c1 = 'a' GROUP BY n1; +n1 +0 +1 +DROP TABLE t1; +# +# MDEV-17211: splittable materialized derived joining 3 tables with +# GROUP BY list containing fields from 2 of them +# +CREATE TABLE t1 ( +id1 int, i1 int, id2 int, +PRIMARY KEY (id1), KEY (i1), KEY (id2) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1); +CREATE TABLE t2 (id2 int, i2 int) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1, 1); +CREATE TABLE t3 (id3 int, i3 int, PRIMARY KEY (id3)) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,1); +EXPLAIN SELECT id3 +FROM (SELECT t3.id3, t2.i2, t1.id2 FROM t3,t1,t2 +WHERE t3.i3=t1.id1 AND t2.id2=t1.id2 +GROUP BY t3.id3, t1.id2) AS t, +t2 +WHERE t2.id2=t.id2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where +1 PRIMARY ref key0 key0 5 test.t2.id2 2 +2 DERIVED t3 ALL NULL NULL NULL NULL 1 Using where; Using temporary; Using filesort +2 DERIVED t1 eq_ref PRIMARY,id2 PRIMARY 4 test.t3.i3 1 +2 DERIVED t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +SELECT id3 +FROM (SELECT t3.id3, t2.i2, t1.id2 FROM t3,t1,t2 +WHERE t3.i3=t1.id1 AND t2.id2=t1.id2 +GROUP BY t3.id3, t1.id2) AS t, +t2 +WHERE t2.id2=t.id2; +id3 +1 +DROP TABLE t1,t2,t3; diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test new file mode 100644 index 00000000000..5e5e3d5d723 --- /dev/null +++ b/mysql-test/main/derived_split_innodb.test @@ -0,0 +1,55 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-16917: do not use splitting for derived with join cache +--echo # + +CREATE TABLE t1 ( + n1 int(10) NOT NULL, + n2 int(10) NOT NULL, + c1 char(1) NOT NULL, + KEY c1 (c1), + KEY n1_c1_n2 (n1,c1,n2) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (0, 2, 'a'), (1, 3, 'a'); + +ANALYZE TABLE t1; + +Let $q= +SELECT t1.n1 FROM t1, (SELECT n1, n2 FROM t1 WHERE c1 = 'a' GROUP BY n1) as t + WHERE t.n1 = t1.n1 AND t.n2 = t1.n2 AND c1 = 'a' GROUP BY n1; + +eval EXPLAIN $q; +eval $q; + +DROP TABLE t1; + +--echo # +--echo # MDEV-17211: splittable materialized derived joining 3 tables with +--echo # GROUP BY list containing fields from 2 of them +--echo # + +CREATE TABLE t1 ( + id1 int, i1 int, id2 int, + PRIMARY KEY (id1), KEY (i1), KEY (id2) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1); + +CREATE TABLE t2 (id2 int, i2 int) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1, 1); + +CREATE TABLE t3 (id3 int, i3 int, PRIMARY KEY (id3)) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,1); + +let $q= +SELECT id3 + FROM (SELECT t3.id3, t2.i2, t1.id2 FROM t3,t1,t2 + WHERE t3.i3=t1.id1 AND t2.id2=t1.id2 + GROUP BY t3.id3, t1.id2) AS t, + t2 + WHERE t2.id2=t.id2; + +eval EXPLAIN $q; +eval $q; + +DROP TABLE t1,t2,t3; diff --git a/mysql-test/suite/innodb/r/alter_algorithm,COPY.rdiff b/mysql-test/suite/innodb/r/alter_algorithm,COPY.rdiff deleted file mode 100644 index be71e125e22..00000000000 --- a/mysql-test/suite/innodb/r/alter_algorithm,COPY.rdiff +++ /dev/null @@ -1,92 +0,0 @@ ---- alter_algorithm.result 2018-05-06 23:42:08.022302601 +0530 -+++ alter_algorithm.reject 2018-05-06 23:42:16.382634082 +0530 -@@ -7,35 +7,44 @@ - INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); - SELECT @@alter_algorithm; - @@alter_algorithm --NOCOPY -+COPY - # All the following cases needs table rebuild - # Add and Drop primary key - ALTER TABLE t1 ADD COLUMN col1 INT NOT NULL,DROP PRIMARY KEY,ADD PRIMARY KEY(col1); --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Make existing column NULLABLE - ALTER TABLE t1 MODIFY f2 INT; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Make existing column NON-NULLABLE - ALTER TABLE t1 MODIFY f3 INT NOT NULL; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Drop Stored Column - ALTER TABLE t1 DROP COLUMN f5; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Add base non-generated column as a last column in the compressed table - ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Add base non-generated column but not in the last position - ALTER TABLE t1 ADD COLUMN f7 INT NOT NULL after f3; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Force the table to rebuild - ALTER TABLE t1 FORCE; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Row format changes - ALTER TABLE t1 ROW_FORMAT=COMPRESSED; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - # Engine table - ALTER TABLE t1 ENGINE=INNODB; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - DROP TABLE t1; - affected rows: 0 - CREATE TABLE t1(f1 INT PRIMARY KEY, f2 INT NOT NULL, -@@ -49,23 +58,23 @@ - INSERT INTO t1(f1, f2, f4, f5) VALUES(1, 2, 3, 4); - SELECT @@alter_algorithm; - @@alter_algorithm --NOCOPY -+COPY - ALTER TABLE t1 ADD INDEX idx1(f4); --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - ALTER TABLE t1 DROP INDEX idx; --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - ALTER TABLE t1 ADD UNIQUE INDEX u1(f2); --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - ALTER TABLE t1 DROP INDEX f4; --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - SET foreign_key_checks = 0; - affected rows: 0 - ALTER TABLE t1 ADD FOREIGN KEY(f5) REFERENCES t2(f1); --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 -+affected rows: 1 -+info: Records: 1 Duplicates: 0 Warnings: 0 - DROP TABLE t2, t1; - affected rows: 0 diff --git a/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff b/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff index 71891bbf473..e9a24820a50 100644 --- a/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff +++ b/mysql-test/suite/innodb/r/alter_algorithm,INPLACE.rdiff @@ -1,66 +1,101 @@ ---- alter_algorithm.result 2018-05-06 23:42:08.022302601 +0530 -+++ alter_algorithm.reject 2018-05-06 23:45:23.813346814 +0530 -@@ -7,35 +7,44 @@ +--- alter_algorithm.result ++++ alter_algorithm.reject +@@ -7,44 +7,44 @@ INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); SELECT @@alter_algorithm; @@alter_algorithm --NOCOPY +-COPY +INPLACE # All the following cases needs table rebuild # Add and Drop primary key ALTER TABLE t1 ADD COLUMN col1 INT NOT NULL,DROP PRIMARY KEY,ADD PRIMARY KEY(col1); --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Make existing column NULLABLE ALTER TABLE t1 MODIFY f2 INT; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Make existing column NON-NULLABLE ALTER TABLE t1 MODIFY f3 INT NOT NULL; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Drop Stored Column ALTER TABLE t1 DROP COLUMN f5; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Add base non-generated column as a last column in the compressed table ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Add base non-generated column but not in the last position ALTER TABLE t1 ADD COLUMN f7 INT NOT NULL after f3; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Force the table to rebuild ALTER TABLE t1 FORCE; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Row format changes ALTER TABLE t1 ROW_FORMAT=COMPRESSED; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 # Engine table ALTER TABLE t1 ENGINE=INNODB; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t1; affected rows: 0 CREATE TABLE t1(f1 INT PRIMARY KEY, f2 INT NOT NULL, -@@ -49,7 +58,7 @@ +@@ -58,23 +58,23 @@ INSERT INTO t1(f1, f2, f4, f5) VALUES(1, 2, 3, 4); SELECT @@alter_algorithm; @@alter_algorithm --NOCOPY +-COPY +INPLACE ALTER TABLE t1 ADD INDEX idx1(f4); +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + ALTER TABLE t1 DROP INDEX idx; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + ALTER TABLE t1 ADD UNIQUE INDEX u1(f2); +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + ALTER TABLE t1 DROP INDEX f4; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + SET foreign_key_checks = 0; + affected rows: 0 + ALTER TABLE t1 ADD FOREIGN KEY(f5) REFERENCES t2(f1); +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + DROP TABLE t2, t1; affected rows: 0 - info: Records: 0 Duplicates: 0 Warnings: 0 diff --git a/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff b/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff index 6e12b78fb9d..c432494dd53 100644 --- a/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff +++ b/mysql-test/suite/innodb/r/alter_algorithm,INSTANT.rdiff @@ -1,78 +1,87 @@ ---- alter_algorithm.result 2018-05-06 23:42:08.022302601 +0530 -+++ alter_algorithm.reject 2018-05-06 23:46:08.482772800 +0530 -@@ -7,35 +7,35 @@ +--- alter_algorithm.result ++++ alter_algorithm.reject +@@ -7,44 +7,35 @@ INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); SELECT @@alter_algorithm; @@alter_algorithm --NOCOPY +-COPY +INSTANT # All the following cases needs table rebuild # Add and Drop primary key ALTER TABLE t1 ADD COLUMN col1 INT NOT NULL,DROP PRIMARY KEY,ADD PRIMARY KEY(col1); --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Make existing column NULLABLE ALTER TABLE t1 MODIFY f2 INT; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Make existing column NON-NULLABLE ALTER TABLE t1 MODIFY f3 INT NOT NULL; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Drop Stored Column ALTER TABLE t1 DROP COLUMN f5; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Add base non-generated column as a last column in the compressed table ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Add base non-generated column but not in the last position ALTER TABLE t1 ADD COLUMN f7 INT NOT NULL after f3; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Force the table to rebuild ALTER TABLE t1 FORCE; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Row format changes ALTER TABLE t1 ROW_FORMAT=COMPRESSED; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors # Engine table ALTER TABLE t1 ENGINE=INNODB; --ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +Got one of the listed errors DROP TABLE t1; affected rows: 0 CREATE TABLE t1(f1 INT PRIMARY KEY, f2 INT NOT NULL, -@@ -49,23 +49,18 @@ +@@ -58,23 +49,18 @@ INSERT INTO t1(f1, f2, f4, f5) VALUES(1, 2, 3, 4); SELECT @@alter_algorithm; @@alter_algorithm --NOCOPY +-COPY +INSTANT ALTER TABLE t1 ADD INDEX idx1(f4); --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY ALTER TABLE t1 DROP INDEX idx; --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: DROP INDEX. Try ALGORITHM=NOCOPY ALTER TABLE t1 ADD UNIQUE INDEX u1(f2); --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY ALTER TABLE t1 DROP INDEX f4; --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: DROP INDEX. Try ALGORITHM=NOCOPY SET foreign_key_checks = 0; affected rows: 0 ALTER TABLE t1 ADD FOREIGN KEY(f5) REFERENCES t2(f1); --affected rows: 0 --info: Records: 0 Duplicates: 0 Warnings: 0 +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY DROP TABLE t2, t1; affected rows: 0 diff --git a/mysql-test/suite/innodb/r/alter_algorithm,NOCOPY.rdiff b/mysql-test/suite/innodb/r/alter_algorithm,NOCOPY.rdiff new file mode 100644 index 00000000000..3ec1eed2e3b --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_algorithm,NOCOPY.rdiff @@ -0,0 +1,92 @@ +--- alter_algorithm.result ++++ alter_algorithm.reject +@@ -7,44 +7,35 @@ + INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); + SELECT @@alter_algorithm; + @@alter_algorithm +-COPY ++NOCOPY + # All the following cases needs table rebuild + # Add and Drop primary key + ALTER TABLE t1 ADD COLUMN col1 INT NOT NULL,DROP PRIMARY KEY,ADD PRIMARY KEY(col1); +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Make existing column NULLABLE + ALTER TABLE t1 MODIFY f2 INT; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Make existing column NON-NULLABLE + ALTER TABLE t1 MODIFY f3 INT NOT NULL; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Drop Stored Column + ALTER TABLE t1 DROP COLUMN f5; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Add base non-generated column as a last column in the compressed table + ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Add base non-generated column but not in the last position + ALTER TABLE t1 ADD COLUMN f7 INT NOT NULL after f3; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Force the table to rebuild + ALTER TABLE t1 FORCE; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Row format changes + ALTER TABLE t1 ROW_FORMAT=COMPRESSED; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + # Engine table + ALTER TABLE t1 ENGINE=INNODB; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++Got one of the listed errors + DROP TABLE t1; + affected rows: 0 + CREATE TABLE t1(f1 INT PRIMARY KEY, f2 INT NOT NULL, +@@ -58,23 +49,23 @@ + INSERT INTO t1(f1, f2, f4, f5) VALUES(1, 2, 3, 4); + SELECT @@alter_algorithm; + @@alter_algorithm +-COPY ++NOCOPY + ALTER TABLE t1 ADD INDEX idx1(f4); +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + ALTER TABLE t1 DROP INDEX idx; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + ALTER TABLE t1 ADD UNIQUE INDEX u1(f2); +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + ALTER TABLE t1 DROP INDEX f4; +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + SET foreign_key_checks = 0; + affected rows: 0 + ALTER TABLE t1 ADD FOREIGN KEY(f5) REFERENCES t2(f1); +-affected rows: 1 +-info: Records: 1 Duplicates: 0 Warnings: 0 ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 + DROP TABLE t2, t1; + affected rows: 0 diff --git a/mysql-test/suite/innodb/r/alter_algorithm.result b/mysql-test/suite/innodb/r/alter_algorithm.result index ee91159bf7a..9a031d9066a 100644 --- a/mysql-test/suite/innodb/r/alter_algorithm.result +++ b/mysql-test/suite/innodb/r/alter_algorithm.result @@ -7,35 +7,44 @@ PRIMARY KEY(f1))ROW_FORMAT=COMPRESSED, ENGINE=INNODB; INSERT INTO t1(f1, f2, f3) VALUES(1, 1, 1); SELECT @@alter_algorithm; @@alter_algorithm -NOCOPY +COPY # All the following cases needs table rebuild # Add and Drop primary key ALTER TABLE t1 ADD COLUMN col1 INT NOT NULL,DROP PRIMARY KEY,ADD PRIMARY KEY(col1); -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Make existing column NULLABLE ALTER TABLE t1 MODIFY f2 INT; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Make existing column NON-NULLABLE ALTER TABLE t1 MODIFY f3 INT NOT NULL; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Drop Stored Column ALTER TABLE t1 DROP COLUMN f5; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Add base non-generated column as a last column in the compressed table ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Add base non-generated column but not in the last position ALTER TABLE t1 ADD COLUMN f7 INT NOT NULL after f3; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Force the table to rebuild ALTER TABLE t1 FORCE; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Row format changes ALTER TABLE t1 ROW_FORMAT=COMPRESSED; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # Engine table ALTER TABLE t1 ENGINE=INNODB; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 DROP TABLE t1; affected rows: 0 CREATE TABLE t1(f1 INT PRIMARY KEY, f2 INT NOT NULL, @@ -49,23 +58,23 @@ FOREIGN KEY `fidx` (f1) REFERENCES t1(f1))ENGINE=INNODB; INSERT INTO t1(f1, f2, f4, f5) VALUES(1, 2, 3, 4); SELECT @@alter_algorithm; @@alter_algorithm -NOCOPY +COPY ALTER TABLE t1 ADD INDEX idx1(f4); -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t1 DROP INDEX idx; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t1 ADD UNIQUE INDEX u1(f2); -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t1 DROP INDEX f4; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 SET foreign_key_checks = 0; affected rows: 0 ALTER TABLE t1 ADD FOREIGN KEY(f5) REFERENCES t2(f1); -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 DROP TABLE t2, t1; affected rows: 0 diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_bzip2.result b/mysql-test/suite/innodb/r/innodb-page_compression_bzip2.result index 61507ddbe5c..5411f5149d1 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_bzip2.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_bzip2.result @@ -147,7 +147,8 @@ count(*) select count(*) from innodb_page_compressed9 where c1 < 500000; count(*) 5000 -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; Level Code Message show create table innodb_normal; @@ -156,6 +157,10 @@ innodb_normal CREATE TABLE `innodb_normal` ( `c1` int(11) DEFAULT NULL, `b` char(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 `page_compressed`=1 `page_compression_level`=8 +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; Level Code Message @@ -174,6 +179,7 @@ update innodb_page_compressed6 set c1 = c1 + 1; update innodb_page_compressed7 set c1 = c1 + 1; update innodb_page_compressed8 set c1 = c1 + 1; update innodb_page_compressed9 set c1 = c1 + 1; +commit; select count(*) from innodb_compressed; count(*) 5000 diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_lz4.result b/mysql-test/suite/innodb/r/innodb-page_compression_lz4.result index 6cef1978ca0..aefb5c8a0be 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_lz4.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_lz4.result @@ -147,7 +147,8 @@ count(*) select count(*) from innodb_page_compressed9 where c1 < 500000; count(*) 5000 -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; Level Code Message show create table innodb_normal; @@ -156,6 +157,10 @@ innodb_normal CREATE TABLE `innodb_normal` ( `c1` int(11) DEFAULT NULL, `b` char(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 `page_compressed`=1 `page_compression_level`=8 +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; Level Code Message diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_lzma.result b/mysql-test/suite/innodb/r/innodb-page_compression_lzma.result index c7ab859e102..606de870d7c 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_lzma.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_lzma.result @@ -147,7 +147,8 @@ count(*) select count(*) from innodb_page_compressed9 where c1 < 500000; count(*) 5000 -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; Level Code Message show create table innodb_normal; @@ -156,6 +157,10 @@ innodb_normal CREATE TABLE `innodb_normal` ( `c1` int(11) DEFAULT NULL, `b` char(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 `page_compressed`=1 `page_compression_level`=8 +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; Level Code Message @@ -174,6 +179,7 @@ update innodb_page_compressed6 set c1 = c1 + 1; update innodb_page_compressed7 set c1 = c1 + 1; update innodb_page_compressed8 set c1 = c1 + 1; update innodb_page_compressed9 set c1 = c1 + 1; +commit; select count(*) from innodb_compressed; count(*) 5000 diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_lzo.result b/mysql-test/suite/innodb/r/innodb-page_compression_lzo.result index 379abcc9968..66783c35d6c 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_lzo.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_lzo.result @@ -147,7 +147,8 @@ count(*) select count(*) from innodb_page_compressed9 where c1 < 500000; count(*) 5000 -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; Level Code Message show create table innodb_normal; @@ -156,6 +157,10 @@ innodb_normal CREATE TABLE `innodb_normal` ( `c1` int(11) DEFAULT NULL, `b` char(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 `page_compressed`=1 `page_compression_level`=8 +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; Level Code Message @@ -174,6 +179,7 @@ update innodb_page_compressed6 set c1 = c1 + 1; update innodb_page_compressed7 set c1 = c1 + 1; update innodb_page_compressed8 set c1 = c1 + 1; update innodb_page_compressed9 set c1 = c1 + 1; +commit; select count(*) from innodb_compressed; count(*) 5000 diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_tables.result b/mysql-test/suite/innodb/r/innodb-page_compression_tables.result index 33b36428040..439f409ea59 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_tables.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_tables.result @@ -88,8 +88,12 @@ select count(*) from innodb_dynamic where c1 < 1500000; count(*) 5000 set global innodb_compression_algorithm = 0; -alter table innodb_compact engine=innodb page_compressed=DEFAULT; -alter table innodb_dynamic engine=innodb page_compressed=DEFAULT; +alter table innodb_compact page_compressed=DEFAULT, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE +alter table innodb_compact page_compressed=DEFAULT; +alter table innodb_dynamic page_compressed=DEFAULT, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE +alter table innodb_dynamic page_compressed=DEFAULT; show create table innodb_compact; Table Create Table innodb_compact CREATE TABLE `innodb_compact` ( diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_zip.result b/mysql-test/suite/innodb/r/innodb-page_compression_zip.result index bb9ceb29e17..9dcf676cb3d 100644 --- a/mysql-test/suite/innodb/r/innodb-page_compression_zip.result +++ b/mysql-test/suite/innodb/r/innodb-page_compression_zip.result @@ -147,7 +147,8 @@ count(*) select count(*) from innodb_page_compressed9 where c1 < 500000; count(*) 5000 -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; Level Code Message show create table innodb_normal; @@ -156,6 +157,10 @@ innodb_normal CREATE TABLE `innodb_normal` ( `c1` int(11) DEFAULT NULL, `b` char(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 `page_compressed`=1 `page_compression_level`=8 +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; +ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; Level Code Message diff --git a/mysql-test/suite/innodb/t/alter_algorithm.test b/mysql-test/suite/innodb/t/alter_algorithm.test index 5a720489281..23cddd46225 100644 --- a/mysql-test/suite/innodb/t/alter_algorithm.test +++ b/mysql-test/suite/innodb/t/alter_algorithm.test @@ -3,7 +3,7 @@ let $algorithm = `SELECT @@ALTER_ALGORITHM`; let $error_code = 0; if ($algorithm == "NOCOPY") { - let $error_code = ER_ALTER_OPERATION_NOT_SUPPORTED; + let $error_code = ER_ALTER_OPERATION_NOT_SUPPORTED, ER_ALTER_OPERATION_NOT_SUPPORTED_REASON; } if ($algorithm == "INSTANT") { diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test b/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test index 69a632d6010..2b4a9ea22a9 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test @@ -2,8 +2,6 @@ -- source include/have_innodb_bzip2.inc -- source include/not_embedded.inc -let $innodb_compression_algorithm_orig=`select @@innodb_compression_algorithm`; - # bzip2 set global innodb_compression_algorithm = 5; @@ -79,9 +77,14 @@ select count(*) from innodb_page_compressed7 where c1 < 500000; select count(*) from innodb_page_compressed8 where c1 < 500000; select count(*) from innodb_page_compressed9 where c1 < 500000; -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; show create table innodb_normal; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; show create table innodb_compressed; @@ -95,6 +98,7 @@ update innodb_page_compressed6 set c1 = c1 + 1; update innodb_page_compressed7 set c1 = c1 + 1; update innodb_page_compressed8 set c1 = c1 + 1; update innodb_page_compressed9 set c1 = c1 + 1; +commit; select count(*) from innodb_compressed; select count(*) from innodb_page_compressed1; select count(*) from innodb_page_compressed1 where c1 < 500000; @@ -236,8 +240,3 @@ drop table innodb_page_compressed6; drop table innodb_page_compressed7; drop table innodb_page_compressed8; drop table innodb_page_compressed9; - -# reset system ---disable_query_log -EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig; ---enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test index 1b1df674e3c..49255d3a1ac 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test @@ -2,8 +2,6 @@ -- source include/have_innodb_lz4.inc -- source include/not_embedded.inc -let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`; - # lz4 set global innodb_compression_algorithm = 2; @@ -79,9 +77,14 @@ select count(*) from innodb_page_compressed7 where c1 < 500000; select count(*) from innodb_page_compressed8 where c1 < 500000; select count(*) from innodb_page_compressed9 where c1 < 500000; -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; show create table innodb_normal; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; show create table innodb_compressed; @@ -237,8 +240,3 @@ drop table innodb_page_compressed6; drop table innodb_page_compressed7; drop table innodb_page_compressed8; drop table innodb_page_compressed9; - -# reset system ---disable_query_log -EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig; ---enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test b/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test index 9cec3e7a947..e05c08f7515 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test @@ -2,8 +2,6 @@ -- source include/have_innodb_lzma.inc -- source include/not_embedded.inc -let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`; - # lzma set global innodb_compression_algorithm = 4; @@ -79,9 +77,14 @@ select count(*) from innodb_page_compressed7 where c1 < 500000; select count(*) from innodb_page_compressed8 where c1 < 500000; select count(*) from innodb_page_compressed9 where c1 < 500000; -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; show create table innodb_normal; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; show create table innodb_compressed; @@ -95,6 +98,7 @@ update innodb_page_compressed6 set c1 = c1 + 1; update innodb_page_compressed7 set c1 = c1 + 1; update innodb_page_compressed8 set c1 = c1 + 1; update innodb_page_compressed9 set c1 = c1 + 1; +commit; select count(*) from innodb_compressed; select count(*) from innodb_page_compressed1; select count(*) from innodb_page_compressed1 where c1 < 500000; @@ -236,8 +240,3 @@ drop table innodb_page_compressed6; drop table innodb_page_compressed7; drop table innodb_page_compressed8; drop table innodb_page_compressed9; - -# reset system ---disable_query_log -EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig; ---enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test b/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test index 65c7e5dd3d9..af831bd2467 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test @@ -2,8 +2,6 @@ -- source include/have_innodb_lzo.inc -- source include/not_embedded.inc -let $innodb_compression_algorithm_orig=`select @@innodb_compression_algorithm`; - # lzo set global innodb_compression_algorithm = 3; @@ -79,9 +77,14 @@ select count(*) from innodb_page_compressed7 where c1 < 500000; select count(*) from innodb_page_compressed8 where c1 < 500000; select count(*) from innodb_page_compressed9 where c1 < 500000; -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; show create table innodb_normal; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; show create table innodb_compressed; @@ -95,6 +98,7 @@ update innodb_page_compressed6 set c1 = c1 + 1; update innodb_page_compressed7 set c1 = c1 + 1; update innodb_page_compressed8 set c1 = c1 + 1; update innodb_page_compressed9 set c1 = c1 + 1; +commit; select count(*) from innodb_compressed; select count(*) from innodb_page_compressed1; select count(*) from innodb_page_compressed1 where c1 < 500000; @@ -189,8 +193,3 @@ drop table innodb_page_compressed6; drop table innodb_page_compressed7; drop table innodb_page_compressed8; drop table innodb_page_compressed9; - -# reset system ---disable_query_log -eval set global innodb_compression_algorithm = $innodb_compression_algorithm_orig; ---enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_tables.test b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test index bf83ebf5e82..a51a697931a 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_tables.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test @@ -70,8 +70,12 @@ select count(*) from innodb_dynamic where c1 < 1500000; # none set global innodb_compression_algorithm = 0; -alter table innodb_compact engine=innodb page_compressed=DEFAULT; -alter table innodb_dynamic engine=innodb page_compressed=DEFAULT; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compact page_compressed=DEFAULT, algorithm=instant; +alter table innodb_compact page_compressed=DEFAULT; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_dynamic page_compressed=DEFAULT, algorithm=instant; +alter table innodb_dynamic page_compressed=DEFAULT; show create table innodb_compact; show create table innodb_dynamic; diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_zip.test b/mysql-test/suite/innodb/t/innodb-page_compression_zip.test index 0c843314eee..45e62722972 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_zip.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_zip.test @@ -1,8 +1,6 @@ --source include/have_innodb.inc --source include/not_embedded.inc -let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`; - # zlib set global innodb_compression_algorithm = 1; @@ -78,9 +76,14 @@ select count(*) from innodb_page_compressed7 where c1 < 500000; select count(*) from innodb_page_compressed8 where c1 < 500000; select count(*) from innodb_page_compressed9 where c1 < 500000; -alter table innodb_normal page_compressed=1 page_compression_level=8; +alter table innodb_normal page_compressed=1 page_compression_level=8, +algorithm=instant; show warnings; show create table innodb_normal; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=instant; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0, algorithm=nocopy; alter table innodb_compressed row_format=default page_compressed=1 page_compression_level=8 key_block_size=0; show warnings; show create table innodb_compressed; @@ -187,8 +190,3 @@ drop table innodb_page_compressed6; drop table innodb_page_compressed7; drop table innodb_page_compressed8; drop table innodb_page_compressed9; - -# reset system ---disable_query_log -EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig; ---enable_query_log diff --git a/sql/opt_split.cc b/sql/opt_split.cc index 611e70376c8..fc3f08464f4 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -267,6 +267,13 @@ void TABLE::deny_splitting() } +double TABLE::get_materialization_cost() +{ + DBUG_ASSERT(spl_opt_info != NULL); + return spl_opt_info->unsplit_cost; +} + + /* This structure is auxiliary and used only in the function that follows it */ struct SplM_field_ext_info: public SplM_field_info { @@ -888,6 +895,8 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, continue; JOIN_TAB *tab= join->map2table[tablenr]; TABLE *table= tab->table; + if (keyuse_ext->table != table) + continue; do { uint key= keyuse_ext->key; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 77347472521..a60ddeb3017 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7919,3 +7919,5 @@ ER_VERS_QUERY_IN_PARTITION eng "SYSTEM_TIME partitions in table %`s does not support historical query" ER_KEY_DOESNT_SUPPORT eng "%s index %`s does not support this operation" +ER_ALTER_OPERATION_TABLE_OPTIONS_NEED_REBUILD + eng "Changing table options requires the table to be rebuilt" diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3b927510c80..3f864ab304e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7308,7 +7308,11 @@ best_access_path(JOIN *join, } } - tmp += s->startup_cost; + /* Splitting technique cannot be used with join cache */ + if (s->table->is_splittable()) + tmp+= s->table->get_materialization_cost(); + else + tmp+= s->startup_cost; /* We estimate the cost of evaluating WHERE clause for found records as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus @@ -7330,6 +7334,7 @@ best_access_path(JOIN *join, best_ref_depends_map= 0; best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map & join->outer_join))); + spl_plan= 0; } } diff --git a/sql/table.h b/sql/table.h index b75fa9074a4..1cc26928151 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1489,6 +1489,7 @@ public: bool is_splittable() { return spl_opt_info != NULL; } void set_spl_opt_info(SplM_opt_info *spl_info); void deny_splitting(); + double get_materialization_cost(); // Now used only if is_splittable()==true void add_splitting_info_for_key_field(struct KEY_FIELD *key_field); /** diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 8febcb76a3b..45192dda16d 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -431,7 +431,7 @@ btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr) const rec_t* rec = cur.page_cur.rec; - if (page_rec_is_supremum(rec) || !rec_is_default_row(rec, index)) { + if (page_rec_is_supremum(rec) || !rec_is_metadata(rec, index)) { ib::error() << "Table " << index->table->name << " is missing instant ALTER metadata"; index->table->corrupted = true; @@ -452,7 +452,7 @@ incompatible: goto incompatible; } - /* Read the 'default row'. We can get here on server restart + /* Read the metadata. We can get here on server restart or when the table was evicted from the data dictionary cache and is now being accessed again. @@ -471,8 +471,8 @@ inconsistent: goto incompatible; } - /* In fact, because we only ever append fields to the 'default - value' record, it is also OK to perform READ UNCOMMITTED and + /* In fact, because we only ever append fields to the metadata + record, it is also OK to perform READ UNCOMMITTED and then ignore any extra fields, provided that trx_sys.is_registered(DB_TRX_ID). */ if (rec_offs_n_fields(offsets) > index->n_fields @@ -2270,10 +2270,9 @@ need_opposite_intention: ut_ad(index->is_instant()); /* This may be a search tuple for btr_pcur_restore_position(). */ - ut_ad(tuple->info_bits == REC_INFO_DEFAULT_ROW + ut_ad(tuple->info_bits == REC_INFO_METADATA || tuple->info_bits == REC_INFO_MIN_REC_FLAG); - } else if (rec_is_default_row(btr_cur_get_rec(cursor), - index)) { + } else if (rec_is_metadata(btr_cur_get_rec(cursor), index)) { /* Only user records belong in the adaptive hash index. */ } else { @@ -3412,7 +3411,7 @@ fail_err: } else if (index->disable_ahi) { # endif } else if (entry->info_bits & REC_INFO_MIN_REC_FLAG) { - ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW); + ut_ad(entry->info_bits == REC_INFO_METADATA); ut_ad(index->is_instant()); ut_ad(flags == BTR_NO_LOCKING_FLAG); } else { @@ -3620,7 +3619,7 @@ btr_cur_pessimistic_insert( if (index->disable_ahi); else # endif if (entry->info_bits & REC_INFO_MIN_REC_FLAG) { - ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW); + ut_ad(entry->info_bits == REC_INFO_METADATA); ut_ad(index->is_instant()); ut_ad((flags & ulint(~BTR_KEEP_IBUF_BITMAP)) == BTR_NO_LOCKING_FLAG); @@ -4100,9 +4099,9 @@ func_exit: /** Trim an update tuple due to instant ADD COLUMN, if needed. For normal records, the trailing instantly added fields that match -the 'default row' are omitted. +the initial default values are omitted. -For the special 'default row' record on a table on which instant +For the special metadata record on a table on which instant ADD COLUMN has already been executed, both ADD COLUMN and the rollback of ADD COLUMN need to be handled specially. @@ -4119,8 +4118,8 @@ btr_cur_trim( const que_thr_t* thr) { if (!index->is_instant()) { - } else if (UNIV_UNLIKELY(update->info_bits == REC_INFO_DEFAULT_ROW)) { - /* We are either updating a 'default row' + } else if (UNIV_UNLIKELY(update->info_bits == REC_INFO_METADATA)) { + /* We are either updating a metadata record (instantly adding columns to a table where instant ADD was already executed) or rolling back such an operation. */ ut_ad(!upd_get_nth_field(update, 0)->orig_len); @@ -4227,9 +4226,9 @@ btr_cur_optimistic_update( || trx_is_recv(thr_get_trx(thr))); #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ - const bool is_default_row = update->info_bits == REC_INFO_DEFAULT_ROW; + const bool is_metadata = update->info_bits == REC_INFO_METADATA; - if (UNIV_LIKELY(!is_default_row) + if (UNIV_LIKELY(!is_metadata) && !row_upd_changes_field_size_or_external(index, *offsets, update)) { @@ -4389,8 +4388,8 @@ any_extern: lock_rec_store_on_page_infimum(block, rec); } - if (UNIV_UNLIKELY(is_default_row)) { - ut_ad(new_entry->info_bits == REC_INFO_DEFAULT_ROW); + if (UNIV_UNLIKELY(is_metadata)) { + ut_ad(new_entry->info_bits == REC_INFO_METADATA); ut_ad(index->is_instant()); /* This can be innobase_add_instant_try() performing a subsequent instant ADD COLUMN, or its rollback by @@ -4416,9 +4415,9 @@ any_extern: cursor, new_entry, offsets, heap, 0/*n_ext*/, mtr); ut_a(rec); /* <- We calculated above the insert would fit */ - if (UNIV_UNLIKELY(is_default_row)) { + if (UNIV_UNLIKELY(is_metadata)) { /* We must empty the PAGE_FREE list, because if this - was a rollback, the shortened 'default row' record + was a rollback, the shortened metadata record would have too many fields, and we would be unable to know the size of the freed record. */ btr_page_reorganize(page_cursor, index, mtr); @@ -4623,7 +4622,7 @@ btr_cur_pessimistic_update( entry_heap); btr_cur_trim(new_entry, index, update, thr); - const bool is_default_row = new_entry->info_bits + const bool is_metadata = new_entry->info_bits & REC_INFO_MIN_REC_FLAG; /* We have to set appropriate extern storage bits in the new @@ -4717,8 +4716,8 @@ btr_cur_pessimistic_update( page, 1); } - if (UNIV_UNLIKELY(is_default_row)) { - ut_ad(new_entry->info_bits == REC_INFO_DEFAULT_ROW); + if (UNIV_UNLIKELY(is_metadata)) { + ut_ad(new_entry->info_bits == REC_INFO_METADATA); ut_ad(index->is_instant()); /* This can be innobase_add_instant_try() performing a subsequent instant ADD COLUMN, or its rollback by @@ -4757,9 +4756,9 @@ btr_cur_pessimistic_update( if (rec) { page_cursor->rec = rec; - if (UNIV_UNLIKELY(is_default_row)) { + if (UNIV_UNLIKELY(is_metadata)) { /* We must empty the PAGE_FREE list, because if this - was a rollback, the shortened 'default row' record + was a rollback, the shortened metadata record would have too many fields, and we would be unable to know the size of the freed record. */ btr_page_reorganize(page_cursor, index, mtr); @@ -4913,9 +4912,9 @@ btr_cur_pessimistic_update( ut_ad(row_get_rec_trx_id(rec, index, *offsets)); } - if (UNIV_UNLIKELY(is_default_row)) { + if (UNIV_UNLIKELY(is_metadata)) { /* We must empty the PAGE_FREE list, because if this - was a rollback, the shortened 'default row' record + was a rollback, the shortened metadata record would have too many fields, and we would be unable to know the size of the freed record. */ btr_page_reorganize(page_cursor, index, mtr); @@ -5413,16 +5412,16 @@ btr_cur_optimistic_delete_func( if (UNIV_UNLIKELY(page_is_root(block->frame) && page_get_n_recs(block->frame) == 1 + (cursor->index->is_instant() - && !rec_is_default_row(rec, cursor->index)))) { + && !rec_is_metadata(rec, cursor->index)))) { /* The whole index (and table) becomes logically empty. Empty the whole page. That is, if we are deleting the - only user record, also delete the 'default row' record + only user record, also delete the metadata record if one exists (it exists if and only if is_instant()). - If we are deleting the 'default row' record and the + If we are deleting the metadata record and the table becomes empty, clean up the whole page. */ dict_index_t* index = cursor->index; ut_ad(!index->is_instant() - || rec_is_default_row( + || rec_is_metadata( page_rec_get_next_const( page_get_infimum_rec(block->frame)), index)); @@ -5475,7 +5474,7 @@ btr_cur_optimistic_delete_func( page_cur_delete_rec(btr_cur_get_page_cur(cursor), cursor->index, offsets, mtr); /* We must empty the PAGE_FREE list, because - after rollback, this deleted 'default row' record + after rollback, this deleted metadata record would have too many fields, and we would be unable to know the size of the freed record. */ btr_page_reorganize(btr_cur_get_page_cur(cursor), @@ -5628,9 +5627,9 @@ btr_cur_pessimistic_delete( } if (page_is_leaf(page)) { - const bool is_default_row = rec_get_info_bits( + const bool is_metadata = rec_get_info_bits( rec, page_rec_is_comp(rec)) & REC_INFO_MIN_REC_FLAG; - if (UNIV_UNLIKELY(is_default_row)) { + if (UNIV_UNLIKELY(is_metadata)) { /* This should be rolling back instant ADD COLUMN. If this is a recovered transaction, then index->is_instant() will hold until the @@ -5648,15 +5647,15 @@ btr_cur_pessimistic_delete( } } else if (page_get_n_recs(page) == 1 + (index->is_instant() - && !rec_is_default_row(rec, index))) { + && !rec_is_metadata(rec, index))) { /* The whole index (and table) becomes logically empty. Empty the whole page. That is, if we are deleting the - only user record, also delete the 'default row' record + only user record, also delete the metadata record if one exists (it exists if and only if is_instant()). - If we are deleting the 'default row' record and the + If we are deleting the metadata record and the table becomes empty, clean up the whole page. */ ut_ad(!index->is_instant() - || rec_is_default_row( + || rec_is_metadata( page_rec_get_next_const( page_get_infimum_rec(page)), index)); @@ -5673,13 +5672,13 @@ btr_cur_pessimistic_delete( goto return_after_reservations; } - if (UNIV_LIKELY(!is_default_row)) { + if (UNIV_LIKELY(!is_metadata)) { btr_search_update_hash_on_delete(cursor); } else { page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, offsets, mtr); /* We must empty the PAGE_FREE list, because - after rollback, this deleted 'default row' record + after rollback, this deleted metadata record would carry too many fields, and we would be unable to know the size of the freed record. */ btr_page_reorganize(btr_cur_get_page_cur(cursor), diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index 46f563a7379..41661d226e1 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -151,13 +151,13 @@ btr_pcur_store_position( rec = page_rec_get_prev(rec); ut_ad(!page_rec_is_infimum(rec)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); cursor->rel_pos = BTR_PCUR_AFTER; } else if (page_rec_is_infimum_low(offs)) { rec = page_rec_get_next(rec); - if (rec_is_default_row(rec, index)) { + if (rec_is_metadata(rec, index)) { rec = page_rec_get_next(rec); ut_ad(!page_rec_is_supremum(rec)); } diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 1041ad8614a..0cb7611b433 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -111,7 +111,7 @@ rec_fold( ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_validate(rec, offsets)); ut_ad(page_rec_is_leaf(rec)); - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); ut_ad(n_fields > 0 || n_bytes > 0); n_fields_rec = rec_offs_n_fields(offsets); @@ -1190,7 +1190,7 @@ retry: rec = page_get_infimum_rec(page); rec = page_rec_get_next_low(rec, page_is_comp(page)); - if (rec_is_default_row(rec, index)) { + if (rec_is_metadata(rec, index)) { rec = page_rec_get_next_low(rec, page_is_comp(page)); } @@ -1398,7 +1398,7 @@ btr_search_build_page_hash_index( rec = page_rec_get_next_const(page_get_infimum_rec(page)); - if (rec_is_default_row(rec, index)) { + if (rec_is_metadata(rec, index)) { rec = page_rec_get_next_const(rec); if (!--n_recs) return; } @@ -1862,7 +1862,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) n_bytes, index->id); } - if (!page_rec_is_infimum(rec) && !rec_is_default_row(rec, index)) { + if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, index)) { offsets = rec_get_offsets( rec, index, offsets, true, btr_search_get_n_fields(n_fields, n_bytes), &heap); diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index 809a60d6431..5c9af8a7da6 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -44,7 +44,8 @@ byte data_error; /** Trim the tail of an index tuple before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple -match the 'default row', there will be no need to store them. +match the default values that were explicitly specified or implied during +ADD COLUMN, there will be no need to store them. NOTE: A page latch in the index must be held, so that the index may not lose 'instantness' before the trimmed tuple has been inserted or updated. diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 69eebab8e17..ed333caffe5 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1084,7 +1084,7 @@ dict_stats_analyze_index_level( btr_pcur_get_rec(&pcur), page_is_comp(page))) { ut_ad(btr_pcur_is_on_user_rec(&pcur)); if (level == 0) { - /* Skip the 'default row' pseudo-record */ + /* Skip the metadata pseudo-record */ ut_ad(index->is_instant()); btr_pcur_move_to_next_user_rec(&pcur, mtr); } diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 104700bc913..a558775a97a 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -3733,7 +3733,7 @@ fts_get_max_doc_id( goto func_exit; } - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); offsets = rec_get_offsets( rec, index, offsets, true, ULINT_UNDEFINED, &heap); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index f0009b2e0df..9c0645e3e3e 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -78,7 +78,7 @@ static const alter_table_operations INNOBASE_ALTER_REBUILD = ALTER_ADD_PK_INDEX | ALTER_DROP_PK_INDEX | ALTER_OPTIONS - /* ALTER_OPTIONS needs to check create_option_need_rebuild() */ + /* ALTER_OPTIONS needs to check alter_options_need_rebuild() */ | ALTER_COLUMN_NULLABLE | INNOBASE_DEFAULTS | ALTER_STORED_COLUMN_ORDER @@ -210,6 +210,9 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx (3) Allow the conversion only in non-strict mode. */ const bool allow_not_null; + /** The page_compression_level attribute, or 0 */ + const uint page_compression_level; + ha_innobase_inplace_ctx(row_prebuilt_t*& prebuilt_arg, dict_index_t** drop_arg, ulint num_to_drop_arg, @@ -226,7 +229,9 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx ulint add_autoinc_arg, ulonglong autoinc_col_min_value_arg, ulonglong autoinc_col_max_value_arg, - bool allow_not_null_flag) : + bool allow_not_null_flag, + bool page_compressed, + ulonglong page_compression_level_arg) : inplace_alter_handler_ctx(), prebuilt (prebuilt_arg), add_index (0), add_key_numbers (0), num_to_add_index (0), @@ -254,9 +259,15 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx old_n_cols(prebuilt_arg->table->n_cols), old_cols(prebuilt_arg->table->cols), old_col_names(prebuilt_arg->table->col_names), - allow_not_null(allow_not_null_flag) + allow_not_null(allow_not_null_flag), + page_compression_level(page_compressed + ? (page_compression_level_arg + ? uint(page_compression_level_arg) + : page_zip_level) + : 0) { ut_ad(old_n_cols >= DATA_N_SYS_COLS); + ut_ad(page_compression_level <= 9); #ifdef UNIV_DEBUG for (ulint i = 0; i < num_to_add_index; i++) { ut_ad(!add_index[i]->to_be_dropped); @@ -490,11 +501,11 @@ innobase_spatial_exist( return(false); } -/** Determine if CHANGE_CREATE_OPTION requires rebuilding the table. +/** Determine if ALTER_OPTIONS requires rebuilding the table. @param[in] ha_alter_info the ALTER TABLE operation @param[in] table metadata before ALTER TABLE @return whether it is mandatory to rebuild the table */ -static bool create_option_need_rebuild( +static bool alter_options_need_rebuild( const Alter_inplace_info* ha_alter_info, const TABLE* table) { @@ -513,12 +524,12 @@ static bool create_option_need_rebuild( } const ha_table_option_struct& alt_opt= - *ha_alter_info->create_info->option_struct; + *ha_alter_info->create_info->option_struct; const ha_table_option_struct& opt= *table->s->option_struct; - if (alt_opt.page_compressed != opt.page_compressed - || alt_opt.page_compression_level - != opt.page_compression_level + /* Allow an instant change to enable page_compressed, + and any change of page_compression_level. */ + if ((!alt_opt.page_compressed && opt.page_compressed) || alt_opt.encryption != opt.encryption || alt_opt.encryption_key_id != opt.encryption_key_id) { return(true); @@ -541,7 +552,7 @@ innobase_need_rebuild( if ((ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE | INNOBASE_ALTER_INSTANT)) == ALTER_OPTIONS) { - return create_option_need_rebuild(ha_alter_info, table); + return alter_options_need_rebuild(ha_alter_info, table); } return !!(ha_alter_info->handler_flags & INNOBASE_ALTER_REBUILD); @@ -689,7 +700,7 @@ instant_alter_column_possible( } return !(ha_alter_info->handler_flags & ALTER_OPTIONS) - || !create_option_need_rebuild(ha_alter_info, table); + || !alter_options_need_rebuild(ha_alter_info, table); } /** Check whether the non-const default value for the field @@ -849,9 +860,11 @@ ha_innobase::check_if_supported_inplace_alter( { DBUG_ENTER("check_if_supported_inplace_alter"); - if ((table->versioned(VERS_TIMESTAMP) - || altered_table->versioned(VERS_TIMESTAMP)) - && innobase_need_rebuild(ha_alter_info, table)) { + const bool need_rebuild = innobase_need_rebuild(ha_alter_info, table); + + if (need_rebuild + && (table->versioned(VERS_TIMESTAMP) + || altered_table->versioned(VERS_TIMESTAMP))) { ha_alter_info->unsupported_reason = "Not implemented for system-versioned tables"; DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); @@ -907,15 +920,15 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } -#if 0 - if (altered_table->file->ht != ht) { - /* Non-native partitioning table engine. No longer supported, - due to implementation of native InnoDB partitioning. */ - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } -#endif - - if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) { + switch (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) { + case ALTER_OPTIONS: + if (alter_options_need_rebuild(ha_alter_info, table)) { + ha_alter_info->unsupported_reason = my_get_err_msg( + ER_ALTER_OPERATION_TABLE_OPTIONS_NEED_REBUILD); + break; + } + /* fall through */ + case 0: DBUG_RETURN(HA_ALTER_INPLACE_INSTANT); } @@ -1294,9 +1307,8 @@ next_column: if (!online) { /* We already determined that only a non-locking operation is possible. */ - } else if (((ha_alter_info->handler_flags - & ALTER_ADD_PK_INDEX) - || innobase_need_rebuild(ha_alter_info, table)) + } else if ((need_rebuild || (ha_alter_info->handler_flags + & ALTER_ADD_PK_INDEX)) && (innobase_fulltext_exist(altered_table) || innobase_spatial_exist(altered_table) || innobase_indexed_virtual_exist(altered_table))) { @@ -1394,10 +1406,9 @@ cannot_create_many_fulltext_index: } // FIXME: implement Online DDL for system-versioned tables - if ((table->versioned(VERS_TRX_ID) - || altered_table->versioned(VERS_TRX_ID)) - && innobase_need_rebuild(ha_alter_info, table)) { - + if (need_rebuild && + (table->versioned(VERS_TRX_ID) + || altered_table->versioned(VERS_TRX_ID))) { if (ha_alter_info->online) { ha_alter_info->unsupported_reason = "Not implemented for system-versioned tables"; @@ -1406,7 +1417,7 @@ cannot_create_many_fulltext_index: online = false; } - if (fts_need_rebuild || innobase_need_rebuild(ha_alter_info, table)) { + if (need_rebuild || fts_need_rebuild) { DBUG_RETURN(online ? HA_ALTER_INPLACE_COPY_NO_LOCK : HA_ALTER_INPLACE_COPY_LOCK); @@ -4225,7 +4236,7 @@ innobase_add_virtual_try( return innodb_update_n_cols(user_table, new_n, trx); } -/** Insert into SYS_COLUMNS and insert/update the 'default row' +/** Insert into SYS_COLUMNS and insert/update the hidden metadata record for instant ADD COLUMN. @param[in,out] ctx ALTER TABLE context for the current partition @param[in] altered_table MySQL table that is being altered @@ -4293,7 +4304,7 @@ innobase_add_instant_try( /* For fixed-length NOT NULL 'core' columns, get a dummy default value from SQL. Note that we will preserve the old values of these - columns when updating the 'default row' + columns when updating the metadata record, to avoid unnecessary updates. */ ulint len = (*af)->pack_length(); DBUG_ASSERT(d->type.mtype != DATA_INT @@ -4360,7 +4371,7 @@ innobase_add_instant_try( memset(roll_ptr, 0, sizeof roll_ptr); dtuple_t* entry = row_build_index_entry(row, NULL, index, ctx->heap); - entry->info_bits = REC_INFO_DEFAULT_ROW; + entry->info_bits = REC_INFO_METADATA; mtr_t mtr; mtr.start(); @@ -4380,7 +4391,7 @@ innobase_add_instant_try( NULL, trx, ctx->heap, NULL); dberr_t err; - if (rec_is_default_row(rec, index)) { + if (rec_is_metadata(rec, index)) { ut_ad(page_rec_is_user_rec(rec)); if (!page_has_next(block->frame) && page_rec_is_last(rec, block->frame)) { @@ -4393,7 +4404,7 @@ innobase_add_instant_try( page as a result of the update. */ upd_t* update = upd_create(index->n_fields, ctx->heap); update->n_fields = n; - update->info_bits = REC_INFO_DEFAULT_ROW; + update->info_bits = REC_INFO_METADATA; /* Add the default values for instantly added columns */ for (unsigned i = 0; i < n; i++) { upd_field_t* uf = upd_get_nth_field(update, i); @@ -4430,8 +4441,8 @@ empty_table: ut_ad(page_is_root(block->frame)); btr_page_empty(block, NULL, index, 0, &mtr); index->remove_instant(); - mtr.commit(); - return false; + err = DB_SUCCESS; + goto func_exit; } /* Convert the table to the instant ADD COLUMN format. */ @@ -4440,20 +4451,12 @@ empty_table: mtr.start(); index->set_modified(mtr); if (page_t* root = btr_root_get(index, &mtr)) { - switch (fil_page_get_type(root)) { - case FIL_PAGE_TYPE_INSTANT: - DBUG_ASSERT(page_get_instant(root) - == index->n_core_fields); - break; - case FIL_PAGE_INDEX: - DBUG_ASSERT(!page_is_comp(root) - || !page_get_instant(root)); - break; - default: + if (fil_page_get_type(root) != FIL_PAGE_INDEX) { DBUG_ASSERT(!"wrong page type"); - goto func_exit; + goto err_exit; } + DBUG_ASSERT(!page_is_comp(root) || !page_get_instant(root)); mlog_write_ulint(root + FIL_PAGE_TYPE, FIL_PAGE_TYPE_INSTANT, MLOG_2BYTES, &mtr); @@ -4465,6 +4468,7 @@ empty_table: BTR_NO_LOCKING_FLAG, BTR_MODIFY_TREE, index, index->n_uniq, entry, 0, thr, false); } else { +err_exit: err = DB_CORRUPTION; } @@ -6827,11 +6831,14 @@ err_exit: } } + const ha_table_option_struct& alt_opt= + *ha_alter_info->create_info->option_struct; + if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) || ((ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE | INNOBASE_ALTER_INSTANT)) == ALTER_OPTIONS - && !create_option_need_rebuild(ha_alter_info, table))) { + && !alter_options_need_rebuild(ha_alter_info, table))) { if (heap) { ha_alter_info->handler_ctx @@ -6845,7 +6852,9 @@ err_exit: heap, indexed_table, col_names, ULINT_UNDEFINED, 0, 0, (ha_alter_info->ignore - || !thd_is_strict_mode(m_user_thd))); + || !thd_is_strict_mode(m_user_thd)), + alt_opt.page_compressed, + alt_opt.page_compression_level); } DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); @@ -6974,7 +6983,8 @@ found_col: add_autoinc_col_no, ha_alter_info->create_info->auto_increment_value, autoinc_col_max_value, - ha_alter_info->ignore || !thd_is_strict_mode(m_user_thd)); + ha_alter_info->ignore || !thd_is_strict_mode(m_user_thd), + alt_opt.page_compressed, alt_opt.page_compression_level); DBUG_RETURN(prepare_inplace_alter_table_dict( ha_alter_info, altered_table, table, @@ -7113,7 +7123,7 @@ ok_exit: if ((ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE | INNOBASE_ALTER_INSTANT)) == ALTER_OPTIONS - && !create_option_need_rebuild(ha_alter_info, table)) { + && !alter_options_need_rebuild(ha_alter_info, table)) { goto ok_exit; } @@ -8824,6 +8834,58 @@ get_col_list_to_be_dropped( } } +/** Change PAGE_COMPRESSED to ON or change the PAGE_COMPRESSION_LEVEL. +@param[in] level PAGE_COMPRESSION_LEVEL +@param[in] table table before the change +@param[in,out] trx data dictionary transaction +@param[in] table_name table name in MariaDB +@return whether the operation succeeded */ +MY_ATTRIBUTE((nonnull, warn_unused_result)) +static +bool +innobase_page_compression_try( + uint level, + const dict_table_t* table, + trx_t* trx, + const char* table_name) +{ + DBUG_ENTER("innobase_page_compression_try"); + DBUG_ASSERT(level >= 1); + DBUG_ASSERT(level <= 9); + + unsigned flags = table->flags + & ~(0xFU << DICT_TF_POS_PAGE_COMPRESSION_LEVEL); + flags |= 1U << DICT_TF_POS_PAGE_COMPRESSION + | level << DICT_TF_POS_PAGE_COMPRESSION_LEVEL; + + if (table->flags == flags) { + DBUG_RETURN(false); + } + + pars_info_t* info = pars_info_create(); + + pars_info_add_ull_literal(info, "id", table->id); + pars_info_add_int4_literal(info, "type", + dict_tf_to_sys_tables_type(flags)); + + dberr_t error = que_eval_sql(info, + "PROCEDURE CHANGE_COMPRESSION () IS\n" + "BEGIN\n" + "UPDATE SYS_TABLES SET TYPE=:type\n" + "WHERE ID=:id;\n" + "END;\n", + false, trx); + + if (error != DB_SUCCESS) { + my_error_innodb(error, table_name, 0); + trx->error_state = DB_SUCCESS; + trx->op_info = ""; + DBUG_RETURN(true); + } + + DBUG_RETURN(false); +} + /** Commit the changes made during prepare_inplace_alter_table() and inplace_alter_table() inside the data dictionary tables, when not rebuilding the table. @@ -8857,6 +8919,13 @@ commit_try_norebuild( || ctx->num_to_drop_vcol == ha_alter_info->alter_info->drop_list.elements); + if (ctx->page_compression_level + && innobase_page_compression_try(ctx->page_compression_level, + ctx->new_table, trx, + table_name)) { + DBUG_RETURN(true); + } + for (ulint i = 0; i < ctx->num_to_add_index; i++) { dict_index_t* index = ctx->add_index[i]; DBUG_ASSERT(dict_index_get_online_status(index) @@ -9002,6 +9071,57 @@ commit_cache_norebuild( { DBUG_ENTER("commit_cache_norebuild"); DBUG_ASSERT(!ctx->need_rebuild()); + DBUG_ASSERT(ctx->new_table->space != fil_system.temp_space); + DBUG_ASSERT(!ctx->new_table->is_temporary()); + + if (ctx->page_compression_level) { + DBUG_ASSERT(ctx->new_table->space != fil_system.sys_space); + ctx->new_table->flags &= + ~(0xFU << DICT_TF_POS_PAGE_COMPRESSION_LEVEL); + ctx->new_table->flags |= 1 << DICT_TF_POS_PAGE_COMPRESSION + | (ctx->page_compression_level + << DICT_TF_POS_PAGE_COMPRESSION_LEVEL); + + if (fil_space_t* space = ctx->new_table->space) { + bool update = !(space->flags + & FSP_FLAGS_MASK_PAGE_COMPRESSION); + mutex_enter(&fil_system.mutex); + space->flags = (~FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL + & (space->flags + | FSP_FLAGS_MASK_PAGE_COMPRESSION)) + | ctx->page_compression_level + << FSP_FLAGS_MEM_COMPRESSION_LEVEL; + mutex_exit(&fil_system.mutex); + + if (update) { + /* Maybe we should introduce an undo + log record for updating tablespace + flags, and perform the update already + in innobase_page_compression_try(). + + If the server is killed before the + following mini-transaction commit + becomes durable, fsp_flags_try_adjust() + will perform the equivalent adjustment + and warn "adjusting FSP_SPACE_FLAGS". */ + mtr_t mtr; + mtr.start(); + if (buf_block_t* b = buf_page_get( + page_id_t(space->id, 0), + page_size_t(space->flags), + RW_X_LATCH, &mtr)) { + mtr.set_named_space(space); + mlog_write_ulint( + FSP_HEADER_OFFSET + + FSP_SPACE_FLAGS + b->frame, + space->flags + & ~FSP_FLAGS_MEM_MASK, + MLOG_4BYTES, &mtr); + } + mtr.commit(); + } + } + } col_set drop_list; col_set v_drop_list; diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index d3361ad8b3b..0fa4cbe8777 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -638,7 +638,8 @@ struct dtuple_t { /** Trim the tail of an index tuple before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple - match the 'default row', there will be no need to store them. + match the default values that were explicitly specified or implied + during ADD COLUMN, there will be no need to store them. NOTE: A page latch in the index must be held, so that the index may not lose 'instantness' before the trimmed tuple has been inserted or updated. diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index 4132c24609b..dd7d31ac3bc 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -87,12 +87,12 @@ bits are stored in the most significant 5 bits of PAGE_DIRECTION_B. These FIL_PAGE_TYPE_INSTANT and PAGE_INSTANT may be assigned even if instant ADD COLUMN was not committed. Changes to these page header fields -are not undo-logged, but changes to the 'default value record' are. +are not undo-logged, but changes to the hidden metadata record are. If the server is killed and restarted, the page header fields could -remain set even though no 'default value record' is present. +remain set even though no metadata record is present. When the table becomes empty, the PAGE_INSTANT field and the -FIL_PAGE_TYPE can be reset and any 'default value record' be removed. */ +FIL_PAGE_TYPE can be reset and any metadata record be removed. */ #define PAGE_INSTANT 12 /** last insert direction: PAGE_LEFT, .... @@ -285,13 +285,11 @@ page_rec_is_comp(const byte* rec) } # ifdef UNIV_DEBUG -/** Determine if the record is the 'default row' pseudo-record +/** Determine if the record is the metadata pseudo-record in the clustered index. @param[in] rec leaf page record on an index page -@return whether the record is the 'default row' pseudo-record */ -inline -bool -page_rec_is_default_row(const rec_t* rec) +@return whether the record is the metadata pseudo-record */ +inline bool page_rec_is_metadata(const rec_t* rec) { return rec_get_info_bits(rec, page_rec_is_comp(rec)) & REC_INFO_MIN_REC_FLAG; diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 3ee993944e9..c1eae387377 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -70,9 +70,9 @@ enum rec_comp_status_t { REC_STATUS_COLUMNS_ADDED = 4 }; -/** The dtuple_t::info_bits of the 'default row' record. -@see rec_is_default_row() */ -static const byte REC_INFO_DEFAULT_ROW +/** The dtuple_t::info_bits of the metadata pseudo-record. +@see rec_is_metadata() */ +static const byte REC_INFO_METADATA = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED; #define REC_NEW_STATUS 3 /* This is single byte bit-field */ @@ -791,14 +791,12 @@ rec_offs_comp(const ulint* offsets) return(*rec_offs_base(offsets) & REC_OFFS_COMPACT); } -/** Determine if the record is the 'default row' pseudo-record +/** Determine if the record is the metadata pseudo-record in the clustered index. @param[in] rec leaf page record @param[in] index index of the record -@return whether the record is the 'default row' pseudo-record */ -inline -bool -rec_is_default_row(const rec_t* rec, const dict_index_t* index) +@return whether the record is the metadata pseudo-record */ +inline bool rec_is_metadata(const rec_t* rec, const dict_index_t* index) { bool is = rec_get_info_bits(rec, dict_table_is_comp(index->table)) & REC_INFO_MIN_REC_FLAG; diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 96454995e74..c38f94f5e73 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -688,7 +688,7 @@ struct row_prebuilt_t { to the Innobase format from the MySQL format */ const byte* default_rec; /*!< the default values of all columns - (a "default row") in MySQL format */ + (a "metadata") in MySQL format */ ulint hint_need_to_fetch_extra_cols; /*!< normally this is set to 0; if this is set to ROW_RETRIEVE_PRIMARY_KEY, diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index b7c4f8d37cd..c19797ab9da 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -337,7 +337,7 @@ lock_report_trx_id_insanity( trx_id_t max_trx_id) /*!< in: trx_sys.get_max_trx_id() */ { ut_ad(rec_offs_validate(rec, index, offsets)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); ib::error() << "Transaction id " << trx_id @@ -360,7 +360,7 @@ lock_check_trx_id_sanity( const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */ { ut_ad(rec_offs_validate(rec, index, offsets)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); trx_id_t max_trx_id = trx_sys.get_max_trx_id(); ut_ad(max_trx_id || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN); @@ -389,7 +389,7 @@ lock_clust_rec_cons_read_sees( ut_ad(dict_index_is_clust(index)); ut_ad(page_rec_is_user_rec(rec)); ut_ad(rec_offs_validate(rec, index, offsets)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); /* Temp-tables are not shared across connections and multiple transactions from different connections cannot simultaneously @@ -428,7 +428,7 @@ lock_sec_rec_cons_read_sees( { ut_ad(page_rec_is_user_rec(rec)); ut_ad(!index->is_primary()); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); /* NOTE that we might call this function while holding the search system latch. */ @@ -1222,7 +1222,7 @@ lock_sec_rec_some_has_impl( ut_ad(!dict_index_is_clust(index)); ut_ad(page_rec_is_user_rec(rec)); ut_ad(rec_offs_validate(rec, index, offsets)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); max_trx_id = page_get_max_trx_id(page); @@ -2696,8 +2696,8 @@ lock_move_reorganize_page( ulint old_heap_no; ulint new_heap_no; ut_d(const rec_t* const orec = rec1); - ut_ad(page_rec_is_default_row(rec1) - == page_rec_is_default_row(rec2)); + ut_ad(page_rec_is_metadata(rec1) + == page_rec_is_metadata(rec2)); if (comp) { old_heap_no = rec_get_heap_no_new(rec2); @@ -2718,7 +2718,7 @@ lock_move_reorganize_page( /* Clear the bit in old_lock. */ if (old_heap_no < lock->un_member.rec_lock.n_bits && lock_rec_reset_nth_bit(lock, old_heap_no)) { - ut_ad(!page_rec_is_default_row(orec)); + ut_ad(!page_rec_is_metadata(orec)); /* NOTE that the old lock bitmap could be too small for the new heap number! */ @@ -2799,8 +2799,8 @@ lock_move_rec_list_end( reset the lock bits on the old */ for (;;) { - ut_ad(page_rec_is_default_row(rec1) - == page_rec_is_default_row(rec2)); + ut_ad(page_rec_is_metadata(rec1) + == page_rec_is_metadata(rec2)); ut_d(const rec_t* const orec = rec1); ulint rec1_heap_no; @@ -2837,7 +2837,7 @@ lock_move_rec_list_end( if (rec1_heap_no < lock->un_member.rec_lock.n_bits && lock_rec_reset_nth_bit(lock, rec1_heap_no)) { - ut_ad(!page_rec_is_default_row(orec)); + ut_ad(!page_rec_is_metadata(orec)); if (type_mode & LOCK_WAIT) { lock_reset_lock_and_trx_wait(lock); @@ -2882,7 +2882,7 @@ lock_move_rec_list_start( ut_ad(block->frame == page_align(rec)); ut_ad(new_block->frame == page_align(old_end)); ut_ad(comp == page_rec_is_comp(old_end)); - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); lock_mutex_enter(); @@ -2908,8 +2908,8 @@ lock_move_rec_list_start( reset the lock bits on the old */ while (rec1 != rec) { - ut_ad(page_rec_is_default_row(rec1) - == page_rec_is_default_row(rec2)); + ut_ad(page_rec_is_metadata(rec1) + == page_rec_is_metadata(rec2)); ut_d(const rec_t* const prev = rec1); ulint rec1_heap_no; @@ -2934,7 +2934,7 @@ lock_move_rec_list_start( if (rec1_heap_no < lock->un_member.rec_lock.n_bits && lock_rec_reset_nth_bit(lock, rec1_heap_no)) { - ut_ad(!page_rec_is_default_row(prev)); + ut_ad(!page_rec_is_metadata(prev)); if (type_mode & LOCK_WAIT) { lock_reset_lock_and_trx_wait(lock); @@ -3014,8 +3014,8 @@ lock_rtr_move_rec_list( rec1 = rec_move[moved].old_rec; rec2 = rec_move[moved].new_rec; - ut_ad(!page_rec_is_default_row(rec1)); - ut_ad(!page_rec_is_default_row(rec2)); + ut_ad(!page_rec_is_metadata(rec1)); + ut_ad(!page_rec_is_metadata(rec2)); if (comp) { rec1_heap_no = rec_get_heap_no_new(rec1); @@ -3094,7 +3094,7 @@ lock_update_merge_right( page which will be discarded */ { - ut_ad(!page_rec_is_default_row(orig_succ)); + ut_ad(!page_rec_is_metadata(orig_succ)); lock_mutex_enter(); @@ -3346,7 +3346,7 @@ lock_update_insert( ulint donator_heap_no; ut_ad(block->frame == page_align(rec)); - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); /* Inherit the gap-locking locks for rec, in gap mode, from the next record */ @@ -3378,7 +3378,7 @@ lock_update_delete( ulint next_heap_no; ut_ad(page == page_align(rec)); - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); if (page_is_comp(page)) { heap_no = rec_get_heap_no_new(rec); @@ -4176,7 +4176,7 @@ lock_rec_unlock( ut_ad(block->frame == page_align(rec)); ut_ad(!trx->lock.wait_lock); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); heap_no = page_rec_get_heap_no(rec); @@ -4505,7 +4505,7 @@ lock_rec_print(FILE* file, const lock_t* lock) rec = page_find_rec_with_heap_no( buf_block_get_frame(block), i); - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); offsets = rec_get_offsets( rec, lock->index, offsets, true, @@ -4977,7 +4977,7 @@ lock_rec_queue_validate( lock = lock_rec_get_next_const(heap_no, lock)) { ut_ad(!trx_is_ac_nl_ro(lock->trx)); - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); if (index) { ut_a(lock->index == index); @@ -5312,7 +5312,7 @@ lock_rec_insert_check_and_lock( trx_t* trx = thr_get_trx(thr); const rec_t* next_rec = page_rec_get_next_const(rec); ulint heap_no = page_rec_get_heap_no(next_rec); - ut_ad(!rec_is_default_row(next_rec, index)); + ut_ad(!rec_is_metadata(next_rec, index)); lock_mutex_enter(); /* Because this code is invoked for a running transaction by @@ -5440,7 +5440,7 @@ lock_rec_convert_impl_to_expl_for_trx( { ut_ad(trx->is_referenced()); ut_ad(page_rec_is_leaf(rec)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); DEBUG_SYNC_C("before_lock_rec_convert_impl_to_expl_for_trx"); @@ -5517,7 +5517,7 @@ static void lock_rec_other_trx_holds_expl(trx_t *caller_trx, trx_t *trx, { if (trx) { - ut_ad(!page_rec_is_default_row(rec)); + ut_ad(!page_rec_is_metadata(rec)); lock_mutex_enter(); lock_rec_other_trx_holds_expl_arg arg= { page_rec_get_heap_no(rec), block, trx }; @@ -5564,7 +5564,7 @@ lock_rec_convert_impl_to_expl( ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets)); ut_ad(page_rec_is_leaf(rec)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); if (dict_index_is_clust(index)) { trx_id_t trx_id; @@ -5641,7 +5641,7 @@ lock_clust_rec_modify_check_and_lock( return(DB_SUCCESS); } - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); ut_ad(!index->table->is_temporary()); heap_no = rec_offs_comp(offsets) @@ -5697,7 +5697,7 @@ lock_sec_rec_modify_check_and_lock( ut_ad(block->frame == page_align(rec)); ut_ad(mtr->is_named_space(index->table->space)); ut_ad(page_rec_is_leaf(rec)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); if (flags & BTR_NO_LOCKING_FLAG) { @@ -5791,7 +5791,7 @@ lock_sec_rec_read_check_and_lock( return(DB_SUCCESS); } - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); heap_no = page_rec_get_heap_no(rec); /* Some transaction may have an implicit x-lock on the record only @@ -5853,7 +5853,7 @@ lock_clust_rec_read_check_and_lock( || gap_mode == LOCK_REC_NOT_GAP); ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(page_rec_is_leaf(rec)); - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); if ((flags & BTR_NO_LOCKING_FLAG) || srv_read_only_mode @@ -7100,7 +7100,7 @@ lock_update_split_and_merge( lock_mutex_enter(); left_next_rec = page_rec_get_next_const(orig_pred); - ut_ad(!page_rec_is_default_row(left_next_rec)); + ut_ad(!page_rec_is_metadata(left_next_rec)); /* Inherit the locks on the supremum of the left page to the first record which was moved from the right page */ diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index 7f3328bc723..e9459a42c7b 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -737,7 +737,7 @@ up_slot_match: & REC_INFO_MIN_REC_FLAG)) { ut_ad(!page_has_prev(page_align(mid_rec))); ut_ad(!page_rec_is_leaf(mid_rec) - || rec_is_default_row(mid_rec, index)); + || rec_is_metadata(mid_rec, index)); cmp = 1; goto low_rec_match; } diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index 43a097404e9..3f06ee0e1bc 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -2788,7 +2788,7 @@ page_find_rec_max_not_deleted( const rec_t* prev_rec = NULL; // remove warning /* Because the page infimum is never delete-marked - and never the 'default row' pseudo-record (MIN_REC_FLAG)), + and never the metadata pseudo-record (MIN_REC_FLAG)), prev_rec will always be assigned to it first. */ ut_ad(!rec_get_info_bits(rec, page_rec_is_comp(rec))); ut_ad(page_is_leaf(page)); diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 7a3aa44bc3f..6b391c2fe76 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -1905,7 +1905,7 @@ rec_copy_prefix_to_buf( case REC_STATUS_COLUMNS_ADDED: /* We would have !index->is_instant() when rolling back an instant ADD COLUMN operation. */ - ut_ad(index->is_instant() || page_rec_is_default_row(rec)); + ut_ad(index->is_instant() || page_rec_is_metadata(rec)); nulls++; const ulint n_rec = ulint(index->n_core_fields) + 1 + rec_get_n_add_field(nulls); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 8758db3c346..d402f6ee67e 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1462,9 +1462,9 @@ IndexPurge::open() UNIV_NOTHROW btr_pcur_open_at_index_side( true, m_index, BTR_MODIFY_LEAF, &m_pcur, true, 0, &m_mtr); btr_pcur_move_to_next_user_rec(&m_pcur, &m_mtr); - if (rec_is_default_row(btr_pcur_get_rec(&m_pcur), m_index)) { + if (rec_is_metadata(btr_pcur_get_rec(&m_pcur), m_index)) { ut_ad(btr_pcur_is_on_user_rec(&m_pcur)); - /* Skip the 'default row' pseudo-record. */ + /* Skip the metadata pseudo-record. */ } else { btr_pcur_move_to_prev_on_page(&m_pcur); } @@ -2267,8 +2267,8 @@ row_import_set_sys_max_row_id( if (page_rec_is_infimum(rec)) { /* The table is empty. */ err = DB_SUCCESS; - } else if (rec_is_default_row(rec, index)) { - /* The clustered index contains the 'default row', + } else if (rec_is_metadata(rec, index)) { + /* The clustered index contains the metadata record only, that is, the table is empty. */ err = DB_SUCCESS; } else { diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 37ae828d09d..7ab0f8eca37 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2652,7 +2652,7 @@ row_ins_clust_index_entry_low( #endif /* UNIV_DEBUG */ if (UNIV_UNLIKELY(entry->info_bits != 0)) { - ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW); + ut_ad(entry->info_bits == REC_INFO_METADATA); ut_ad(flags == BTR_NO_LOCKING_FLAG); ut_ad(index->is_instant()); ut_ad(!dict_index_is_online_ddl(index)); @@ -2667,7 +2667,8 @@ row_ins_clust_index_entry_low( err = DB_DUPLICATE_KEY; goto err_exit; case REC_INFO_MIN_REC_FLAG | REC_INFO_DELETED_FLAG: - /* The 'default row' is never delete-marked. + /* The metadata record never carries the delete-mark + in MariaDB Server 10.3. If a table loses its 'instantness', it happens by the rollback of this first-time insert, or by a call to btr_page_empty() on the root page @@ -2682,7 +2683,7 @@ row_ins_clust_index_entry_low( if (index->is_instant()) entry->trim(*index); - if (rec_is_default_row(btr_cur_get_rec(cursor), index)) { + if (rec_is_metadata(btr_cur_get_rec(cursor), index)) { goto do_insert; } diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index a6e35744446..e94a1cbfc6b 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -970,7 +970,7 @@ row_log_table_low( ut_ad(!"wrong page type"); } #endif /* UNIV_DEBUG */ - ut_ad(!rec_is_default_row(rec, index)); + ut_ad(!rec_is_metadata(rec, index)); ut_ad(page_rec_is_leaf(rec)); ut_ad(!page_is_comp(page_align(rec)) == !rec_offs_comp(offsets)); /* old_pk=row_log_table_get_pk() [not needed in INSERT] is a prefix diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index eaddb8b0432..ad44742e57b 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -1873,9 +1873,9 @@ row_merge_read_clustered_index( btr_pcur_open_at_index_side( true, clust_index, BTR_SEARCH_LEAF, &pcur, true, 0, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr); - if (rec_is_default_row(btr_pcur_get_rec(&pcur), clust_index)) { + if (rec_is_metadata(btr_pcur_get_rec(&pcur), clust_index)) { ut_ad(btr_pcur_is_on_user_rec(&pcur)); - /* Skip the 'default row' pseudo-record. */ + /* Skip the metadata pseudo-record. */ } else { ut_ad(!clust_index->is_instant()); btr_pcur_move_to_prev_on_page(&pcur); diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc index 21a44fc1825..04af5646e6b 100644 --- a/storage/innobase/row/row0row.cc +++ b/storage/innobase/row/row0row.cc @@ -1013,7 +1013,7 @@ row_search_on_row_ref( index = dict_table_get_first_index(table); if (UNIV_UNLIKELY(ref->info_bits != 0)) { - ut_ad(ref->info_bits == REC_INFO_DEFAULT_ROW); + ut_ad(ref->info_bits == REC_INFO_METADATA); ut_ad(ref->n_fields <= index->n_uniq); btr_pcur_open_at_index_side(true, index, mode, pcur, true, 0, mtr); @@ -1021,7 +1021,7 @@ row_search_on_row_ref( /* We do not necessarily have index->is_instant() here, because we could be executing a rollback of an instant ADD COLUMN operation. The function - rec_is_default_row() asserts index->is_instant(); + rec_is_metadata() asserts index->is_instant(); we do not want to call it here. */ return rec_get_info_bits(btr_pcur_get_rec(pcur), dict_table_is_comp(index->table)) diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index c6a463c584b..1531fb38b7f 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -1489,7 +1489,7 @@ row_sel_try_search_shortcut( const rec_t* rec = btr_pcur_get_rec(&(plan->pcur)); - if (!page_rec_is_user_rec(rec) || rec_is_default_row(rec, index)) { + if (!page_rec_is_user_rec(rec) || rec_is_metadata(rec, index)) { retry: rw_lock_s_unlock(ahi_latch); return(SEL_RETRY); @@ -1789,8 +1789,8 @@ skip_lock: goto next_rec; } - if (rec_is_default_row(rec, index)) { - /* Skip the 'default row' pseudo-record. */ + if (rec_is_metadata(rec, index)) { + /* Skip the metadata pseudo-record. */ cost_counter++; goto next_rec; } @@ -3011,7 +3011,7 @@ row_sel_store_mysql_field_func( } } else { /* The field is stored in the index record, or - in the 'default row' for instant ADD COLUMN. */ + in the metadata for instant ADD COLUMN. */ if (rec_offs_nth_default(offsets, field_no)) { ut_ad(dict_index_is_clust(index)); @@ -3563,8 +3563,8 @@ sel_restore_position_for_mysql( if (!success && moves_up) { next: if (btr_pcur_move_to_next(pcur, mtr) - && rec_is_default_row(btr_pcur_get_rec(pcur), - pcur->btr_cur.index)) { + && rec_is_metadata(btr_pcur_get_rec(pcur), + pcur->btr_cur.index)) { btr_pcur_move_to_next(pcur, mtr); } @@ -3579,8 +3579,8 @@ next: pcur->pos_state = BTR_PCUR_IS_POSITIONED; prev: if (btr_pcur_is_on_user_rec(pcur) && !moves_up - && !rec_is_default_row(btr_pcur_get_rec(pcur), - pcur->btr_cur.index)) { + && !rec_is_metadata(btr_pcur_get_rec(pcur), + pcur->btr_cur.index)) { btr_pcur_move_to_prev(pcur, mtr); } return true; @@ -3857,7 +3857,7 @@ row_sel_try_search_shortcut_for_mysql( BTR_SEARCH_LEAF, pcur, ahi_latch, mtr); rec = btr_pcur_get_rec(pcur); - if (!page_rec_is_user_rec(rec) || rec_is_default_row(rec, index)) { + if (!page_rec_is_user_rec(rec) || rec_is_metadata(rec, index)) { retry: rw_lock_s_unlock(ahi_latch); return(SEL_RETRY); @@ -4758,7 +4758,7 @@ rec_loop: if (comp) { if (rec_get_info_bits(rec, true) & REC_INFO_MIN_REC_FLAG) { - /* Skip the 'default row' pseudo-record. */ + /* Skip the metadata pseudo-record. */ ut_ad(index->is_instant()); goto next_rec; } @@ -4770,7 +4770,7 @@ rec_loop: } } else { if (rec_get_info_bits(rec, false) & REC_INFO_MIN_REC_FLAG) { - /* Skip the 'default row' pseudo-record. */ + /* Skip the metadata pseudo-record. */ ut_ad(index->is_instant()); goto next_rec; } diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 67a11711fe2..a5d7294c9ed 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -142,7 +142,7 @@ row_undo_ins_remove_clust_rec( /* This is rolling back an INSERT into SYS_COLUMNS. If it was part of an instant ADD COLUMN operation, we must modify the table definition. At this point, any - corresponding operation to the 'default row' will have + corresponding operation to the metadata record will have been rolled back. */ ut_ad(!online); ut_ad(node->trx->dict_operation_lock_mode == RW_X_LATCH); diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index b46d3d83bb0..0ab186aac5e 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1211,16 +1211,15 @@ close_table: if (node->update->info_bits & REC_INFO_MIN_REC_FLAG) { /* This must be an undo log record for a subsequent - instant ADD COLUMN on a table, extending the - 'default value' record. */ + instant ALTER TABLE, extending the metadata record. */ ut_ad(clust_index->is_instant()); if (node->update->info_bits != REC_INFO_MIN_REC_FLAG) { ut_ad(!"wrong info_bits in undo log record"); goto close_table; } - node->update->info_bits = REC_INFO_DEFAULT_ROW; + node->update->info_bits = REC_INFO_METADATA; const_cast(node->ref)->info_bits - = REC_INFO_DEFAULT_ROW; + = REC_INFO_METADATA; } if (!row_undo_search_clust_to_pcur(node)) { @@ -1297,7 +1296,7 @@ row_undo_mod( ut_ad(dict_index_is_clust(node->index)); if (node->ref->info_bits) { - ut_ad(node->ref->info_bits == REC_INFO_DEFAULT_ROW); + ut_ad(node->ref->info_bits == REC_INFO_METADATA); goto rollback_clust; } diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 90681f20cab..652154ae4c2 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -42,7 +42,7 @@ Created 3/26/1996 Heikki Tuuri /** The search tuple corresponding to TRX_UNDO_INSERT_DEFAULT */ const dtuple_t trx_undo_default_rec = { - REC_INFO_DEFAULT_ROW, 0, 0, + REC_INFO_METADATA, 0, 0, NULL, 0, NULL, UT_LIST_NODE_T(dtuple_t)() #ifdef UNIV_DEBUG @@ -506,7 +506,7 @@ trx_undo_page_report_insert( /* Store then the fields required to uniquely determine the record to be inserted in the clustered index */ if (UNIV_UNLIKELY(clust_entry->info_bits != 0)) { - ut_ad(clust_entry->info_bits == REC_INFO_DEFAULT_ROW); + ut_ad(clust_entry->info_bits == REC_INFO_METADATA); ut_ad(index->is_instant()); ut_ad(undo_block->frame[first_free + 2] == TRX_UNDO_INSERT_REC); diff --git a/storage/mroonga/mrn_table.hpp b/storage/mroonga/mrn_table.hpp index 422d48d234d..70af3ab512f 100644 --- a/storage/mroonga/mrn_table.hpp +++ b/storage/mroonga/mrn_table.hpp @@ -97,6 +97,7 @@ struct st_mrn_slot_data #define MRN_SET_WRAP_ALTER_KEY(file, ha_alter_info) \ alter_table_operations base_handler_flags = ha_alter_info->handler_flags; \ + ha_table_option_struct* base_option_struct = ha_alter_info->create_info->option_struct; \ KEY *base_key_info_buffer = ha_alter_info->key_info_buffer; \ uint base_key_count = ha_alter_info->key_count; \ uint base_index_drop_count = ha_alter_info->index_drop_count; \ @@ -104,6 +105,7 @@ struct st_mrn_slot_data uint base_index_add_count = ha_alter_info->index_add_count; \ uint *base_index_add_buffer = ha_alter_info->index_add_buffer; \ ha_alter_info->handler_flags = file->alter_handler_flags; \ + ha_alter_info->create_info->option_struct = wrap_altered_table->s->option_struct; \ ha_alter_info->key_info_buffer = file->alter_key_info_buffer; \ ha_alter_info->key_count = file->alter_key_count; \ ha_alter_info->index_drop_count = file->alter_index_drop_count; \ @@ -113,6 +115,7 @@ struct st_mrn_slot_data #define MRN_SET_BASE_ALTER_KEY(share, table_share) \ ha_alter_info->handler_flags = base_handler_flags; \ + ha_alter_info->create_info->option_struct = base_option_struct; \ ha_alter_info->key_info_buffer = base_key_info_buffer; \ ha_alter_info->key_count = base_key_count; \ ha_alter_info->index_drop_count = base_index_drop_count; \