diff options
author | Alice Sherepa <alice.sherepa@gmail.com> | 2017-09-27 11:25:44 +0200 |
---|---|---|
committer | Alice Sherepa <alice.sherepa@gmail.com> | 2017-09-27 11:25:44 +0200 |
commit | dbaa8dda56519891811f331a031e76ed26d36334 (patch) | |
tree | 53ccf6537e708e09d7d0f778218700ff7da19388 | |
parent | 19d21b9366c1eb5c1c1e822a09969e9a23bfe2c3 (diff) | |
download | mariadb-git-bb-10.0-alice13625.tar.gz |
tests merged 10.0 with mysql 5.6.37bb-10.0-alice13625
116 files changed, 18889 insertions, 3 deletions
diff --git a/mysql-test/suite/innodb/t/add_foreign_key.test b/mysql-test/suite/innodb/t/add_foreign_key.test new file mode 100644 index 00000000000..d0febfd62f0 --- /dev/null +++ b/mysql-test/suite/innodb/t/add_foreign_key.test @@ -0,0 +1,38 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE ADD +--echo # FOREIGN KEY +--echo # + +CREATE TABLE `parent` (`parent_id` INT, PRIMARY KEY (`parent_id`)); +CREATE TABLE `child1` (`id` INT ,`child1_fk1` INT, `child1_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child2` (`id` INT, `child2_fk1` INT, `child2_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child3` (`id` INT , `child3_fk1` INT, PRIMARY KEY (`id`)); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES +`parent` (`parent_id`); + +drop table child3, child2, child1, parent; diff --git a/mysql-test/suite/innodb/t/analyze_table.test b/mysql-test/suite/innodb/t/analyze_table.test new file mode 100644 index 00000000000..e9db3668f02 --- /dev/null +++ b/mysql-test/suite/innodb/t/analyze_table.test @@ -0,0 +1,42 @@ +# +# BUG#22385442 - INNODB: DIFFICULT TO FIND FREE BLOCKS IN THE BUFFER POOL +# + +--source include/have_innodb.inc +--source include/big_test.inc + +DELIMITER |; +CREATE PROCEDURE populate_t1() +BEGIN + DECLARE i int DEFAULT 1; + + START TRANSACTION; + WHILE (i <= 1000000) DO + INSERT INTO t1 VALUES (i, i, CONCAT('a', i)); + SET i = i + 1; + END WHILE; + COMMIT; +END| +DELIMITER ;| + +CREATE TABLE t1( + class INT, + id INT, + title VARCHAR(100) +) ENGINE=InnoDB; + +-- disable_query_log +CALL populate_t1(); +-- enable_query_log + +SELECT COUNT(*) FROM t1; + +SET GLOBAL innodb_stats_persistent_sample_pages=2000; + +ANALYZE TABLE t1; + +DROP TABLE t1; + +DROP PROCEDURE populate_t1; + +SET GLOBAL innodb_stats_persistent_sample_pages=default; diff --git a/mysql-test/suite/innodb/t/blob_redo-master.opt b/mysql-test/suite/innodb/t/blob_redo-master.opt new file mode 100644 index 00000000000..36994abfb5f --- /dev/null +++ b/mysql-test/suite/innodb/t/blob_redo-master.opt @@ -0,0 +1 @@ +--innodb-log-files-in-group=12 --innodb-log-file-size=5M diff --git a/mysql-test/suite/innodb/t/blob_redo.test b/mysql-test/suite/innodb/t/blob_redo.test new file mode 100644 index 00000000000..d292a729d34 --- /dev/null +++ b/mysql-test/suite/innodb/t/blob_redo.test @@ -0,0 +1,92 @@ +--source include/not_embedded.inc +--source include/not_crashrep.inc +--source include/have_innodb.inc +--source include/have_innodb_16k.inc + +--echo # +--echo # Bug #19498877 LIMITATION ON BLOB SIZE IS TOO STRICT, BLOB CAN +--echo # BE 10% OF TOTAL REDO LOG SIZE +--echo # + +# Save the initial number of concurrent sessions. +--source include/count_sessions.inc + +call mtr.add_suppression("InnoDB: Resizing redo log from"); +call mtr.add_suppression("InnoDB: Starting to delete and rewrite log files."); +call mtr.add_suppression("InnoDB: New log files created, LSN="); + +SET GLOBAL max_allowed_packet = 100*1024*1024; + +--echo # Connection big_packets: +connect(big_packets,localhost,root,,); +connection big_packets; + +CREATE TABLE t1 (a BIGINT PRIMARY KEY, b LONGBLOB) ENGINE=InnoDB; + +# Insert a few rows (it doesn't really matter how many). These transactions +# are committed once they are acked, so they should not be lost. +INSERT INTO t1 (a, b) VALUES (1, '1'); +INSERT INTO t1 (a, b) VALUES (2, '2'); +INSERT INTO t1 (a, b) VALUES (3, '3'); +INSERT INTO t1 (a, b) VALUES (4, '4'); +INSERT INTO t1 (a, b) VALUES (5, '5'); + +start transaction; +INSERT INTO t1 (a, b) VALUES (6, REPEAT('a', 6*1024*1024)); + +--echo # Connection default: +connection default; + +# We expect a restart. +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--echo # Quick shutdown and restart server +--shutdown_server 0 + +# Wait for the server to come back up, and reconnect. +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +--echo # Connection default: +connection default; + +--disconnect big_packets + +# We should see (1,2,3,4,5) here. +SELECT a, b FROM t1; + +SET GLOBAL max_allowed_packet = 100*1024*1024; + +--echo # Connection big_packets: +connect(big_packets,localhost,root,,); + +start transaction; +UPDATE t1 SET b = REPEAT('a', 6*1024*1024) WHERE a = 1; + +--echo # Connection default: +connection default; + +# We expect a restart. +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--echo # Quick shutdown and restart server +--shutdown_server 0 + +# Wait for the server to come back up, and reconnect. +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +--echo # Connection default: +connection default; + +--disconnect big_packets + +# We should see (1,2,3,4,5) here. +SELECT a, b FROM t1; + +# Clean up. +DROP TABLE t1; + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/checksum.test b/mysql-test/suite/innodb/t/checksum.test new file mode 100644 index 00000000000..4b371aa1a1b --- /dev/null +++ b/mysql-test/suite/innodb/t/checksum.test @@ -0,0 +1,15 @@ +--source include/not_embedded.inc +--source include/have_innodb.inc +--source suite/innodb/include/checksum_not_strict.inc +--echo # +--echo # Bug#19500258 ZERO CAN BE A VALID INNODB CHECKSUM, +--echo # BUT VALIDATION WILL FAIL LATER +--echo # +--let $old_checksum_algorithm= `SELECT @@GLOBAL.innodb_checksum_algorithm` +SET GLOBAL innodb_checksum_algorithm = 'CRC32'; +CREATE TABLE t1 (a INT PRIMARY KEY, b VARBINARY(512)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, X'666F72636520637263333220a0be0639'); +--source include/restart_mysqld.inc +SELECT count(*) FROM t1; +--eval SET GLOBAL innodb_checksum_algorithm = '$old_checksum_algorithm'; +drop table t1; diff --git a/mysql-test/suite/innodb/t/create_isl_with_direct-master.opt b/mysql-test/suite/innodb/t/create_isl_with_direct-master.opt new file mode 100644 index 00000000000..8f80f02e359 --- /dev/null +++ b/mysql-test/suite/innodb/t/create_isl_with_direct-master.opt @@ -0,0 +1 @@ +--innodb_flush_method=O_DIRECT diff --git a/mysql-test/suite/innodb/t/create_isl_with_direct.test b/mysql-test/suite/innodb/t/create_isl_with_direct.test new file mode 100644 index 00000000000..6ad0cbc878c --- /dev/null +++ b/mysql-test/suite/innodb/t/create_isl_with_direct.test @@ -0,0 +1,27 @@ +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/not_windows.inc + +--disable_query_log +CALL mtr.add_suppression("\\[Warning\\] InnoDB: Failed to set O_DIRECT on file ./ibdata1: OPEN: Invalid argument, continuing anyway. O_DIRECT is known to result in 'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662."); + +# The below mtr suppression to avoid failure in solaris platform. +CALL mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to set DIRECTIO_ON on file.*"); +--enable_query_log + +SHOW VARIABLES LIKE 'innodb_flush_method'; + +let MYSQLD_DATADIR=`SELECT @@datadir`; + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR + +# Create a table with explicit data directory option. +EVAL CREATE TABLE t1 (x INT) ENGINE=INNODB, DATA DIRECTORY='$MYSQL_TMP_DIR'; + +--echo # Contents of tmp/test directory containing .ibd file +--list_files $MYSQL_TMP_DIR/test + +--echo # Contents of the 'test' database directory containing .isl and .frm files +--list_files $MYSQLD_DATADIR/test + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/disabled.def b/mysql-test/suite/innodb/t/disabled.def new file mode 100644 index 00000000000..888298bbb09 --- /dev/null +++ b/mysql-test/suite/innodb/t/disabled.def @@ -0,0 +1,11 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment> +# +# Do not use any TAB characters for whitespace. +# +############################################################################## diff --git a/mysql-test/suite/innodb/t/end_range_check.test b/mysql-test/suite/innodb/t/end_range_check.test new file mode 100644 index 00000000000..a5502946724 --- /dev/null +++ b/mysql-test/suite/innodb/t/end_range_check.test @@ -0,0 +1,77 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/big_test.inc + +--echo # Bug #23481444 OPTIMISER CALL ROW_SEARCH_MVCC() AND READ +--echo # THE INDEX APPLIED BY UNCOMMITTED ROWS. + +CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + f2 INT NOT NULL, f3 INT NOT NULL, + KEY(f2, f3))ENGINE=INNODB; + +DELIMITER |; +CREATE PROCEDURE populate_t1(IN BASE INT, IN SIZE INT) +BEGIN + DECLARE i INT DEFAULT BASE; + WHILE (i <= SIZE) DO + INSERT INTO t1(f2, f3) values (i, i); + SET i = i + 1; + END WHILE; +END| +DELIMITER ;| +CALL populate_t1(1, 10000); +INSERT INTO t1(f2, f3) VALUES(10000, 10000); + +BEGIN; +CALL populate_t1(10001, 20000); + +connect (con1,localhost,root,,); +connection con1; +SELECT SQL_NO_CACHE f2, f3 FROM t1 WHERE f2=10000 and f3 between 9999 and 10000; +connection default; +DROP TABLE t1; + +CREATE TABLE t1(f2 INT NOT NULL, f3 INT NOT NULL, + PRIMARY KEY(f2, f3))ENGINE=INNODB; + +CALL populate_t1(1, 10000); + +BEGIN; +CALL populate_t1(10001, 20000); + +connection con1; +SELECT SQL_NO_CACHE f2, f3 FROM t1 WHERE f2=10000 and f3 between 9999 and 10000; +connection default; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + f2 INT NOT NULL, f3 INT NOT NULL, + KEY(f2), KEY(f3))ENGINE=INNODB; +CALL populate_t1(1, 10000); + +BEGIN; +CALL populate_t1(10001, 20000); + +connection con1; +SELECT count(*) FROM t1 FORCE INDEX(f2, f3) WHERE f2 < 10000 or f3 < 10000; +connection default; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + f2 INT NOT NULL, f3 INT NOT NULL, + KEY(f2, f3))ENGINE=INNODB; + +CALL populate_t1(1, 10000); +CALL populate_t1(100000, 100200); + +BEGIN; +CALL populate_t1(10001, 20000); + +connection con1; +SELECT SQL_NO_CACHE COUNT(*) FROM t1 +WHERE f2 BETWEEN 9999 AND 10000 OR f2 >= 100000; +disconnect con1; +connection default; + +DROP TABLE t1; +DROP PROCEDURE populate_t1; diff --git a/mysql-test/suite/innodb/t/flush-hang.test b/mysql-test/suite/innodb/t/flush-hang.test new file mode 100644 index 00000000000..7de9abdcb6d --- /dev/null +++ b/mysql-test/suite/innodb/t/flush-hang.test @@ -0,0 +1,50 @@ + +--echo # +--echo #Bug #21133329 HANGING "SYSTEM LOCK" WHEN EXECUTING "FLUSH TABLE ... FOR EXPORT" +--echo # + +--source include/not_embedded.inc +--source include/have_debug.inc +--source include/have_innodb.inc + +CREATE TABLE t1 ( + c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 BIGINT, + c3 VARCHAR(2048), + c4 VARCHAR(2048), + INDEX idx1(c2), + INDEX idx2(c3(512)), + INDEX idx3(c4(512))) Engine=InnoDB; + +CREATE TABLE t2 ( f1 int PRIMARY KEY) engine=innodb; + +# Stop purge so that it doesn't remove the delete marked entries. +SET GLOBAL INNODB_PURGE_STOP_NOW=ON; + +# Disable change buffer merge from the master thread, additionally +# enable aggressive flushing so that more changes are buffered. +SET GLOBAL innodb_disable_background_merge=ON; +SET GLOBAL innodb_stats_persistent=OFF; +show variables like '%innodb_stats_persistent%'; + +INSERT INTO t1(c2, c3, c4) VALUES + (1, REPEAT('a', 2048), REPEAT('a', 2048)), + (2, REPEAT('b', 2048), REPEAT('b', 2048)), + (3, REPEAT('c', 2048), REPEAT('c', 2048)), + (4, REPEAT('d', 2048), REPEAT('d', 2048)); + +INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1; +INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1; +INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1; +INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1; +INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1; +INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1; + +FLUSH TABLES t2 FOR EXPORT; +UNLOCK TABLES; + +SET GLOBAL innodb_disable_background_merge=OFF; +SET GLOBAL INNODB_PURGE_RUN_NOW=ON; +SET GLOBAL innodb_stats_persistent=ON; + +DROP TABLE t1,t2; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test new file mode 100644 index 00000000000..6cba3c2ba12 --- /dev/null +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -0,0 +1,87 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #19027905 ASSERT RET.SECOND DICT_CREATE_FOREIGN_CONSTRAINTS_LOW +--echo # DICT_CREATE_FOREIGN_CONSTR +--echo # + +create table t1 (f1 int primary key) engine=InnoDB; +--error ER_CANNOT_ADD_FOREIGN +create table t2 (f1 int primary key, +constraint c1 foreign key (f1) references t1(f1), +constraint c1 foreign key (f1) references t1(f1)) engine=InnoDB; +create table t2 (f1 int primary key, + constraint c1 foreign key (f1) references t1(f1)) engine=innodb; + +--replace_regex /#sql-[0-9a-f_]*'/#sql-temporary'/ +--error ER_DUP_KEY +alter table t2 add constraint c1 foreign key (f1) references t1(f1); + +set foreign_key_checks = 0; +--error ER_FK_DUP_NAME +alter table t2 add constraint c1 foreign key (f1) references t1(f1); + +drop table t2, t1; + +--echo # +--echo # Bug #20031243 CREATE TABLE FAILS TO CHECK IF FOREIGN KEY COLUMN +--echo # NULL/NOT NULL MISMATCH +--echo # + +set foreign_key_checks = 1; +show variables like 'foreign_key_checks'; + +CREATE TABLE t1 +(a INT NOT NULL, + b INT NOT NULL, + INDEX idx(a)) ENGINE=InnoDB; + +CREATE TABLE t2 +(a INT KEY, + b INT, + INDEX ind(b), + FOREIGN KEY (b) REFERENCES t1(a) ON DELETE CASCADE ON UPDATE CASCADE) + ENGINE=InnoDB; + +show create table t1; +show create table t2; + +INSERT INTO t1 VALUES (1, 80); +INSERT INTO t1 VALUES (2, 81); +INSERT INTO t1 VALUES (3, 82); +INSERT INTO t1 VALUES (4, 83); +INSERT INTO t1 VALUES (5, 84); + +INSERT INTO t2 VALUES (51, 1); +INSERT INTO t2 VALUES (52, 2); +INSERT INTO t2 VALUES (53, 3); +INSERT INTO t2 VALUES (54, 4); +INSERT INTO t2 VALUES (55, 5); + +SELECT a, b FROM t1 ORDER BY a; +SELECT a, b FROM t2 ORDER BY a; + +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES (56, 6); + +ALTER TABLE t1 CHANGE a id INT; + +SELECT id, b FROM t1 ORDER BY id; +SELECT a, b FROM t2 ORDER BY a; + +--echo # Operations on child table +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES (56, 6); +--error ER_NO_REFERENCED_ROW_2 +UPDATE t2 SET b = 99 WHERE a = 51; +DELETE FROM t2 WHERE a = 53; +SELECT id, b FROM t1 ORDER BY id; +SELECT a, b FROM t2 ORDER BY a; + +--echo # Operations on parent table +DELETE FROM t1 WHERE id = 1; +UPDATE t1 SET id = 50 WHERE id = 5; +SELECT id, b FROM t1 ORDER BY id; +SELECT a, b FROM t2 ORDER BY a; + +DROP TABLE t2, t1; diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty-master.opt b/mysql-test/suite/innodb/t/ibuf_not_empty-master.opt new file mode 100644 index 00000000000..e5d7090c883 --- /dev/null +++ b/mysql-test/suite/innodb/t/ibuf_not_empty-master.opt @@ -0,0 +1 @@ +--innodb_buffer_pool_size=24M diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test new file mode 100644 index 00000000000..1d3f8788eb4 --- /dev/null +++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test @@ -0,0 +1,102 @@ +--source include/have_innodb.inc +# innodb_change_buffering_debug option is debug only +--source include/have_debug.inc +# Embedded server does not support crashing +--source include/not_embedded.inc + + +call mtr.add_suppression('InnoDB: Failed to find tablespace for table \'".*".".*"\' in the cache'); +call mtr.add_suppression('InnoDB: Allocated tablespace [0-9]+, old maximum was [0-9]+'); + +CREATE TABLE t1( + a INT AUTO_INCREMENT PRIMARY KEY, + b CHAR(1), + c INT, + INDEX(b)) +ENGINE=InnoDB STATS_PERSISTENT=0; + +# The flag innodb_change_buffering_debug is only available in debug builds. +# It instructs InnoDB to try to evict pages from the buffer pool when +# change buffering is possible, so that the change buffer will be used +# whenever possible. +SET GLOBAL innodb_change_buffering_debug = 1; + +# Create enough rows for the table, so that the change buffer will be +# used for modifying the secondary index page. There must be multiple +# index pages, because changes to the root page are never buffered. +INSERT INTO t1 VALUES(0,'x',1); +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; +INSERT INTO t1 SELECT 0,b,c FROM t1; + +# Restart the server in force recovery mode +--echo # Stop server + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Request shutdown +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart:--innodb-force-recovery=6" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +--error ER_CANT_LOCK +insert into t1 values(0,'y',1); + +# Restart the server in force recovery mode +--echo # Stop server + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Request shutdown +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +# Cleanup +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/import.test b/mysql-test/suite/innodb/t/import.test new file mode 100644 index 00000000000..2f682db2abc --- /dev/null +++ b/mysql-test/suite/innodb/t/import.test @@ -0,0 +1,25 @@ +# Test "ALTER TABLE ... IMPORT TABLESPACE" in InnoDB +--source include/have_innodb.inc + +--echo # +--echo # Bug#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES +--echo # + +CREATE TABLE t1 (c1 VARCHAR(32), c2 VARCHAR(32), c3 VARCHAR(32), +PRIMARY KEY (c1, c2, c3)) +ENGINE=InnoDB; + +ALTER TABLE t1 ADD INDEX ind1(c1(5), c2, c3); +ALTER TABLE t1 ADD INDEX ind2(c3, c1(10), c2); +ALTER TABLE t1 ADD INDEX ind3(c2, c3, c1(20)); + +INSERT INTO t1 VALUES ('Test Data -1', 'Test Data -2', 'Test Data -3'); + +--echo # Test with 2ndary index having prefix +--source suite/innodb/include/import.inc + +--echo # Test with PK & 2ndary index with prefix +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1(5), c2(10), c3(20)); +--source suite/innodb/include/import.inc + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/import_update_stats.test b/mysql-test/suite/innodb/t/import_update_stats.test new file mode 100644 index 00000000000..e12e2954e5a --- /dev/null +++ b/mysql-test/suite/innodb/t/import_update_stats.test @@ -0,0 +1,78 @@ +# +# BUG#20125349 - PERSISTANT STATS IS NOT UPDATED WHEN TTS IS IMPORTED. +# + +--source include/not_embedded.inc +--source include/have_innodb.inc + +let MYSQLD_DATADIR =`SELECT @@datadir`; +SET @old_innodb_file_per_table = @@innodb_file_per_table; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +CREATE TABLE t1 ( + col_1 CHAR (255), + col_2 VARCHAR (255) +) ENGINE = InnoDB; + +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); + +SHOW INDEXES FROM t1; + +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"), ("col1_00002", "col2_00002"); + +SHOW INDEXES FROM t1; + +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +FLUSH TABLES t1 FOR EXPORT; +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; + +DROP TABLE t1; + +CREATE TABLE t1 ( + col_1 CHAR (255), + col_2 VARCHAR (255) +) ENGINE = InnoDB; + +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); + +SHOW INDEXES FROM t1; + +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"); + +SHOW INDEXES FROM t1; + +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +ALTER TABLE t1 DISCARD TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; + +SHOW INDEXES FROM t1; + +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +DROP TABLE t1; + +SET GLOBAL innodb_file_per_table = @old_innodb_file_per_table; + +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1*.ibd +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1*.cfg diff --git a/mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt b/mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt new file mode 100644 index 00000000000..a2532d4cfd9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt @@ -0,0 +1,2 @@ +--character-sets-dir=$MYSQL_TEST_DIR/std_data/ + diff --git a/mysql-test/suite/innodb/t/innodb-2byte-collation.test b/mysql-test/suite/innodb/t/innodb-2byte-collation.test new file mode 100644 index 00000000000..b943b0eddf3 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-2byte-collation.test @@ -0,0 +1,88 @@ +# Test for InnoDB support of 2 bytes (15 bits) collation ID +# Some of the example and test setup are adopted from ctype_ldml.test + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_ucs2.inc +--source include/have_utf8mb4.inc +--source include/have_utf16.inc +--source include/have_utf32.inc + +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +show variables like 'character_sets_dir%'; + +set names utf8; + +# Test that the "ID" column in I_S and SHOW queries can handle two bytes +select * from information_schema.collations where id>256 order by id; +show collation like '%test%'; + +# Test that two-byte collation ID is correctly transfered to the client side. +show collation like 'ucs2_vn_ci'; +create table 2byte_collation (c1 char(1) character set ucs2 collate ucs2_vn_ci) +engine = InnoDB; + +insert into 2byte_collation values (0x0061); +--enable_metadata +set @@character_set_results=NULL; +select * from 2byte_collation; +--disable_metadata +drop table 2byte_collation; + +# +# Check maximum collation ID (2047 as of MySQL-6.0.9) +# +CREATE TABLE 2byte_collation (s1 char(10) character set utf8 collate utf8_maxuserid_ci) engine = innodb; +INSERT INTO 2byte_collation VALUES ('a'),('b'); +SELECT * FROM 2byte_collation WHERE s1='a' ORDER BY BINARY s1; +DROP TABLE 2byte_collation; + +# Excercise some change buffer code with the help of +# "innodb_change_buffering_debug" +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; +-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = 1; + +-- enable_query_log + +set names utf8; + +show collation like 'utf8_maxuserid_ci'; + +CREATE TABLE 2byte_collation( + a INT AUTO_INCREMENT PRIMARY KEY, + b CHAR(100) character set utf8 collate utf8_maxuserid_ci, + c INT, + z INT, + INDEX(b)) +ENGINE=InnoDB STATS_PERSISTENT=0; + +INSERT INTO 2byte_collation VALUES(0,'x',1, 1); + +CREATE UNIQUE INDEX idx3 ON 2byte_collation(c, b); + +INSERT INTO 2byte_collation SELECT 0,b,c+1,z+1 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+10,z+10 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+20,z+20 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+50,z+50 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+100,z+100 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+200,z+200 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+400,z+400 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+800,z+800 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+1600,z+1600 FROM 2byte_collation; +INSERT INTO 2byte_collation SELECT 0,b,c+4000,z+4000 FROM 2byte_collation; + +CREATE INDEX idx5 ON 2byte_collation(b, c); + +SELECT b FROM 2byte_collation LIMIT 10; + +INSERT INTO 2byte_collation VALUES (10001, "a", 20001, 20001); + +UPDATE 2byte_collation set b = "aaa" where c = 20001; + +DROP TABLE 2byte_collation; + +-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_change_buffering_debug = 0; + diff --git a/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test b/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test new file mode 100644 index 00000000000..64f9be95c08 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test @@ -0,0 +1,123 @@ +# DEBUG_SYNC must be compiled in. +--source include/have_debug_sync.inc + +--source include/have_innodb.inc + +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) +--connect (con3,localhost,root,,) +--connect (con4,localhost,root,,) +--connect (con5,localhost,root,,) +--connect (con6,localhost,root,,) + +connection default; +# Disable query log to avoid non-deterministic output conflicts +SET AUTOCOMMIT=0; +BEGIN; +# Lock all the records +SELECT * FROM t1 FOR UPDATE; +--disable_query_log + +connection con1; +SET AUTOCOMMIT=1; +# Test if locking autocommit selects end up in the trx_sys_t::trx_list. +# We check this via the INFORMATION_SCHEMA.INNODB_TRX. +# This should block and show up in the I_S. +SET DEBUG_SYNC='lock_wait_suspend_thread_enter SIGNAL waiting1'; +--send +SELECT COUNT(*) FROM t1 LOCK IN SHARE MODE; + +connection con2; +SET AUTOCOMMIT=1; +# Test if non-locking autocommit selects end up in the trx_sys_t::trx_list. +# We check this via the INFORMATION_SCHEMA.INNODB_TRX. +# This should not block and should not show up in the I_S. +--send +SELECT COUNT(*) FROM t1; + +connection con3; +SET AUTOCOMMIT=1; +# Note: autocommit non-locking selects are not converted to locking selects +# Therefore this should not block; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +--send +SELECT COUNT(*) FROM t1; + +connection con4; +SET AUTOCOMMIT=0; +# Note: Non-locking selects are converted to locking selects +# therefore this should block; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +SET DEBUG_SYNC='now WAIT_FOR waiting1'; +SET DEBUG_SYNC='lock_wait_suspend_thread_enter SIGNAL waiting4'; +--send +SELECT COUNT(*) FROM t1 WHERE c1 >= 0; + +connection con5; +SET AUTOCOMMIT=1; +# This should not block +BEGIN; +--send +SELECT COUNT(*) FROM t1; + +connection con6; +SET AUTOCOMMIT=1; +# This will ignore the auto-commit setting but wont block because it is +# a non-locking select. +XA START '1'; +--enable_query_log +SELECT * FROM t1 WHERE c1 <= 3; + +connection default; +# Wait for SELECTs to get into the lock wait queue +SET DEBUG_SYNC='now WAIT_FOR waiting4'; + +# Check the number of non-locking transactions +let $wait_condition = + SELECT COUNT(*) = 5 + FROM INFORMATION_SCHEMA.INNODB_TRX + WHERE trx_autocommit_non_locking = 0; +--source include/wait_condition.inc + +# Check the waiting transactions +SELECT trx_state, trx_query, trx_autocommit_non_locking +FROM INFORMATION_SCHEMA.INNODB_TRX +WHERE trx_state = 'LOCK WAIT' +ORDER BY trx_query; + +INSERT INTO t1 VALUES(4, '4'); +COMMIT; + +connection con6; +SELECT * FROM t1 WHERE c1 <= 4; +XA END '1'; +XA PREPARE '1'; +XA ROLLBACK '1'; + +connection default; +disconnect con2; +disconnect con3; +disconnect con5; +disconnect con6; + +connection con1; +reap; +disconnect con1; + +connection con4; +reap; +disconnect con4; + +connection default; +DROP TABLE t1; + +# Clean up resources used in this test case. +--disable_warnings +SET DEBUG_SYNC= 'RESET'; +--enable_warnings diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-master.opt b/mysql-test/suite/innodb/t/innodb-autoinc-master.opt new file mode 100644 index 00000000000..303ec1be1d0 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-autoinc-master.opt @@ -0,0 +1,3 @@ +--default-storage-engine=MyISAM +--innodb-strict-mode=0 +--innodb-file-per-table=0 diff --git a/mysql-test/suite/innodb/t/innodb-bug12552164.test b/mysql-test/suite/innodb/t/innodb-bug12552164.test new file mode 100644 index 00000000000..7fe9903dcfe --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-bug12552164.test @@ -0,0 +1,50 @@ +CREATE TABLE worklog5743 (col_1_CHAR CHAR(255) , col_2_CHAR CHAR(255) , +PRIMARY KEY (col_1_CHAR)) engine = innodb; +INSERT INTO worklog5743 VALUES(repeat("a", 200) , repeat("o", 200)); +SELECT col_1_CHAR = repeat("a", 200) , col_2_CHAR = repeat("o", 200) FROM +worklog5743; + +--echo "In connection 1" +--connect (con1,localhost,root,,) +SELECT col_1_CHAR = repeat("a", 200) , col_2_CHAR = repeat("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; + + +--echo "In connection 2" +--connect (con2,localhost,root,,) +START TRANSACTION; +INSERT INTO worklog5743 VALUES(repeat("b", 200) , repeat("o", 200)); +UPDATE worklog5743 SET col_1_CHAR = repeat("d", 200) WHERE col_1_CHAR = +repeat("a", 200) AND col_2_CHAR = repeat("o", 200); +SELECT col_1_CHAR = repeat("a", 200) , col_2_CHAR = repeat("o", 200) FROM +worklog5743; + + +--echo "In connection 1" +--connection con1 +SELECT col_1_CHAR = repeat("b", 200) , col_2_CHAR = repeat("o", 200) FROM +worklog5743; + +START TRANSACTION; + +SELECT col_1_CHAR = repeat("a", 200) , col_2_CHAR = repeat("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; + +--echo "In connection 2" +--connection con2 +COMMIT; +SELECT sleep(5); + +--echo "In connection 1" +--connection con1 +SELECT col_1_CHAR = repeat("b", 200) , col_2_CHAR = repeat("o", 200) FROM +worklog5743; +SELECT col_1_CHAR = repeat("a", 200) , col_2_CHAR = repeat("o", 200) FROM +worklog5743; +SELECT COUNT(*) FROM worklog5743; +COMMIT; + +--connection default +DROP TABLE worklog5743; diff --git a/mysql-test/suite/innodb/t/innodb-bug14219515.test b/mysql-test/suite/innodb/t/innodb-bug14219515.test new file mode 100644 index 00000000000..6adc18adc9f --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-bug14219515.test @@ -0,0 +1,19 @@ +# ==== Purpose ==== +# +# Verify that ADD PRIMARY KEY can report duplicate key value +# +# ==== References ==== +# +# Bug #14219515 DUPLICATE VALUE NOT REPORTED FOR ADD PRIMARY KEY +# +--source include/have_innodb.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT NOT NULL, b INT) ENGINE = INNODB; +INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4); +--ERROR ER_DUP_ENTRY +ALTER TABLE t1 ADD PRIMARY KEY(b), ADD UNIQUE INDEX(a); +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-double-write.test b/mysql-test/suite/innodb/t/innodb-double-write.test new file mode 100644 index 00000000000..39738ed6030 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-double-write.test @@ -0,0 +1,388 @@ +--echo # +--echo # Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY +--echo # Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST +--echo # PAGE OF SYSTEM TABLESPACE +--echo # + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/not_embedded.inc +--source include/not_valgrind.inc + +# Slow shutdown and restart to make sure ibuf merge is finished +SET GLOBAL innodb_fast_shutdown = 0; +--source include/restart_mysqld.inc + +--disable_query_log +call mtr.add_suppression("InnoDB: Database page .* contained only zeroes."); +call mtr.add_suppression("Header page consists of zero bytes"); +call mtr.add_suppression("Checksum mismatch in tablespace"); +call mtr.add_suppression("but the innodb_page_size start-up parameter is"); +call mtr.add_suppression("Database page corruption"); +call mtr.add_suppression("innodb-page-size mismatch in tablespace"); +--enable_query_log + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +show variables like 'innodb_doublewrite'; +show variables like 'innodb_fil_make_page_dirty_debug'; +show variables like 'innodb_saved_page_number_debug'; + +create table t1 (f1 int primary key, f2 blob) engine=innodb; + +start transaction; +insert into t1 values(1, repeat('#',12)); +insert into t1 values(2, repeat('+',12)); +insert into t1 values(3, repeat('/',12)); +insert into t1 values(4, repeat('-',12)); +insert into t1 values(5, repeat('.',12)); +commit work; + +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if first page of user +--echo # tablespace is full of zeroes. + +select space from information_schema.innodb_sys_tables +where name = 'test/t1' into @space_id; + +--echo # Wait for purge to complete +--source include/wait_innodb_all_purged.inc + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--echo # Make the first page dirty for table t1 +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = @space_id; + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 12)); +--source include/wait_until_disconnected.inc + +--echo # Make the first page (page_no=0) of the user tablespace +--echo # full of zeroes. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; +open(FILE, "+<", $fname) or die; +binmode FILE; +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if first page of user +--echo # tablespace is corrupted. + +select space from information_schema.innodb_sys_tables +where name = 'test/t1' into @space_id; + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--echo # Make the first page dirty for table t1 +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = @space_id; + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 12)); +--source include/wait_until_disconnected.inc + +--echo # Corrupt the first page (page_no=0) of the user tablespace. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; +open(FILE, "+<", $fname) or die; +binmode FILE; +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if 2nd page of user +--echo # tablespace is full of zeroes. + +select space from information_schema.innodb_sys_tables +where name = 'test/t1' into @space_id; + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--echo # Make the 2nd page dirty for table t1 +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = @space_id; + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 400)); +--source include/wait_until_disconnected.inc + +--echo # Make the 2nd page (page_no=1) of the tablespace all zeroes. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; +open(FILE, "+<", $fname) or die; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if 2nd page of user +--echo # tablespace is corrupted. + +select space from information_schema.innodb_sys_tables +where name = 'test/t1' into @space_id; + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--echo # Make the 2nd page dirty for table t1 +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = @space_id; + +--echo # Ensure that dirty pages of table t1 is flushed. +flush tables t1 for export; +unlock tables; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 400)); +--source include/wait_until_disconnected.inc + +--echo # Corrupt the 2nd page (page_no=1) of the user tablespace. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; +open(FILE, "+<", $fname) or die; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if first page of +--echo # system tablespace is full of zeroes. + +--echo # Ensure that the dirty page of system tablespace is flushed. +set global innodb_buf_flush_list_now = 1; + +--echo # Make the first page dirty for system tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; + +--echo # Ensure that the dirty page of system tablespace is also flushed. +set global innodb_buf_flush_list_now = 1; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 400)); +--source include/wait_until_disconnected.inc + +--echo # Make the first page (page_no=0) of the system tablespace +--echo # all zeroes. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; +open(FILE, "+<", $fname) or die; +binmode FILE; +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if first page of +--echo # system tablespace is corrupted. + +--echo # Ensure that the dirty page of system tablespace is flushed. +set global innodb_buf_flush_list_now = 1; + +--echo # Make the first page dirty for system tablespace +set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; + +--echo # Ensure that the dirty page of system tablespace is also flushed. +set global innodb_buf_flush_list_now = 1; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 400)); +--source include/wait_until_disconnected.inc + +--echo # Corrupt the first page (page_no=0) of the system tablespace. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; +open(FILE, "+<", $fname) or die; +binmode FILE; +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if 2nd page of +--echo # system tablespace is full of zeroes. + +--echo # Ensure that the dirty page of system tablespace is flushed. +set global innodb_buf_flush_list_now = 1; + +--echo # Make the second page dirty for system tablespace +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = 0; + +--echo # Ensure that the dirty page of system tablespace is flushed. +set global innodb_buf_flush_list_now = 1; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 400)); +--source include/wait_until_disconnected.inc + +--echo # Make the 2nd page (page_no=1) of the system tablespace +--echo # all zeroes. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; +open(FILE, "+<", $fname) or die; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- +--echo # Test Begin: Test if recovery works if 2nd page of +--echo # system tablespace is corrupted. + +--echo # Ensure that the dirty page of system tablespace is flushed. +set global innodb_buf_flush_list_now = 1; + +--echo # Make the second page dirty for system tablespace +set global innodb_saved_page_number_debug = 1; +set global innodb_fil_make_page_dirty_debug = 0; + +--echo # Ensure that the dirty page of system tablespace is flushed. +set global innodb_buf_flush_list_now = 1; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +set debug='+d,crash_commit_before'; +--error 2013 +insert into t1 values (6, repeat('%', 400)); +--source include/wait_until_disconnected.inc + +--echo # Make the 2nd page (page_no=1) of the system tablespace +--echo # all zeroes. +perl; +my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1"; +open(FILE, "+<", $fname) or die; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET); +print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--echo # Server must be started successfully, and table t1 must be fine... +check table t1; +select f1, f2 from t1; + +--echo # Test End +--echo # --------------------------------------------------------------- + +drop table t1; + diff --git a/mysql-test/suite/innodb/t/innodb-index-debug-master.opt b/mysql-test/suite/innodb/t/innodb-index-debug-master.opt new file mode 100644 index 00000000000..778b4443d4f --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-index-debug-master.opt @@ -0,0 +1 @@ +--innodb-sort-buffer-size=64k diff --git a/mysql-test/suite/innodb/t/innodb-index-online-master.opt b/mysql-test/suite/innodb/t/innodb-index-online-master.opt new file mode 100644 index 00000000000..9ac01ffb5ad --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-index-online-master.opt @@ -0,0 +1 @@ +--innodb-sort-buffer-size=64k --innodb-online-alter-log-max-size=64k --innodb-buffer-pool-size=5M --innodb-log-buffer-size=256k diff --git a/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test b/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test new file mode 100644 index 00000000000..c0bc3895875 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test @@ -0,0 +1,115 @@ +--echo # +--echo # Bug #21025880 DUPLICATE UK VALUES IN READ-COMMITTED(AGAIN) +--echo # + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +let i=0; + +while ($i <=1 ) +{ + +CREATE TABLE t1 ( + a INT NOT NULL, + b INT NOT NULL, + PRIMARY KEY(b), + UNIQUE KEY(a)) +ENGINE=INNODB; + +SET @old_innodb_stats_auto_recalc = @@innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc = OFF; + +# Block purge +SET GLOBAL innodb_purge_stop_now = ON; + +SET @old_tx_isolation = @@tx_isolation; +SET GLOBAL tx_isolation = 'READ-COMMITTED'; + +SET @old_innodb_lock_wait_timeout = @@innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout = 1; + +--connect(con1,localhost,root,,) +--connect(con2,localhost,root,,) + +--connection con1 + +# Create and delete-mark an index record + +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1; + +SET debug_sync = 'row_ins_sec_index_entry_dup_locks_created SIGNAL +con1_locks_done WAIT_FOR con1_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con1_insert_done WAIT_FOR con1_finish'; +--send + +if ($i == 0) +{ +REPLACE INTO t1 VALUES (1,2); +} + +if ( $i == 1) +{ +INSERT INTO t1 values (1,2) ON DUPLICATE KEY UPDATE a=2; +} +--connection con2 + +SET debug_sync = 'now WAIT_FOR con1_locks_done'; + +SET debug_sync = 'lock_wait_suspend_thread_enter SIGNAL con2_blocked +WAIT_FOR con2_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con2_insert_done WAIT_FOR con2_finish'; +SET debug_sync = 'ib_after_row_insert SIGNAL con2_insert_done'; + +--send +REPLACE INTO t1 VALUES (1,3); + +--connection default +SET debug_sync = 'now WAIT_FOR con2_blocked'; + +SET GLOBAL innodb_purge_run_now=ON; + +# Wait for purge to delete the delete-marked record +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS + WHERE VARIABLE_NAME='INNODB_PURGE_TRX_ID_AGE' AND VARIABLE_VALUE=2; +--source include/wait_condition.inc + +SET debug_sync = 'now SIGNAL con2_go WAIT_FOR con2_insert_done'; +SET debug_sync = 'now SIGNAL con1_go WAIT_FOR con1_insert_done'; + +SET debug_sync = 'now SIGNAL con1_finish'; +SET debug_sync = 'now SIGNAL con2_finish'; + +--connection con1 +--reap + +--connection con2 +--error 0,ER_LOCK_WAIT_TIMEOUT +--reap + +--connection default + +--disconnect con1 +--disconnect con2 + +SELECT * FROM t1; +CHECK TABLE t1; + +DROP TABLE t1; + +SET GLOBAL innodb_stats_auto_recalc = @old_innodb_stats_auto_recalc; +SET GLOBAL tx_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; + +# Clean up resources used in this test case. +--disable_warnings +SET DEBUG_SYNC= 'RESET'; +--enable_warnings + +--inc $i +} diff --git a/mysql-test/suite/innodb/t/innodb-log-file-size-1.test b/mysql-test/suite/innodb/t/innodb-log-file-size-1.test new file mode 100644 index 00000000000..91c2a141300 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-log-file-size-1.test @@ -0,0 +1,300 @@ +######## suite/innodb/t/innodb-wl6445-1 ########## +# # +# Testcase for worklog WL#6494: InnoDB should be able to work if # +# redo log file size mismatch +# Test resizing the InnoDB redo log. +# # +# # +# Creation: # +# 2011-09-26 Implemented this test as part of WL#6494 # +# # +###################################################################### + + +# Not supported in embedded +--source include/not_embedded.inc + +-- source include/have_innodb.inc +# Valgrind would complain about memory leaks when we crash on purpose. +--source include/not_valgrind.inc + +if (`SELECT @@innodb_log_file_size = 2097152`) { + --skip Test requires innodb_log_file_size!=2M. +} + +# restart with innodb-fast-shutdown=2 to on stopping it , behave as crash +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-fast-shutdown=2 --innodb-log-file-size=1M" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + + +call mtr.add_suppression("InnoDB: Resizing redo log"); +call mtr.add_suppression("InnoDB: Starting to delete and rewrite log files"); +call mtr.add_suppression("InnoDB: New log files created"); +call mtr.add_suppression("InnoDB: The log sequence numbers [0-9]+ and [0-9]+ in ibdata files do not match the log sequence number [0-9]+ in the ib_logfiles"); + +let MYSQLD_DATADIR =`SELECT @@datadir`; +let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; +let $innodb_file_format = `SELECT @@innodb_file_format`; +let $innodb_log_file_size = `SELECT @@innodb_log_file_size`; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +SET GLOBAL innodb_file_format = `Barracuda`; +SELECT @@innodb_file_format; + +SELECT @@innodb_log_file_size; +SELECT @@innodb_log_files_in_group; + + +# Testcase 1 - set log file size > existing size and innodb_log_files_in_group > old value +--disable_warnings +DROP DATABASE IF EXISTS db_wl6494; +--enable_warnings +CREATE DATABASE db_wl6494; +USE db_wl6494; + +CREATE TABLE t1(id INT PRIMARY KEY,bfield blob) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,repeat('a',2000)),(2,repeat('b',2000)), +(3,repeat('c',2000)); +START TRANSACTION; +INSERT INTO t1 VALUES (11,repeat('a',2000)),(12,repeat('b',2000)), +(13,repeat('c',2000)); +SAVEPOINT A; +INSERT INTO t1 VALUES (21,repeat('a',2000)),(22,repeat('b',2000)), +(23,repeat('c',2000)); +SAVEPOINT B; +SELECT id,LEFT(bfield,20) FROM t1; +ROLLBACK TO A; +COMMIT; +SELECT id,LEFT(bfield,20) FROM t1; + +# restart with different redo log size +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +# set log size from 2*1M to 5*2M +--exec echo "restart: --innodb-log-file-size=2M --innodb_log_files_in_group=5 --log-error=$MYSQLTEST_VARDIR/log/case1.err" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/case1.err; +let SEARCH_PATTERN= InnoDB: Starting crash recovery; +--source include/search_pattern_in_file.inc + +# Check size of ib_logfile* when innodb_log_files_in_group is set +perl; + my $dir = $ENV{'MYSQLD_DATADIR'}; + $file = "ib_logfile0"; + $size_in_MB = (-s "$dir/$file") / (1024 * 1024);; + print "The size of the $file file: $size_in_MB \n"; + $file = "ib_logfile1"; + $size_in_MB = (-s "$dir/$file") / (1024 * 1024);; + print "The size of the $file file: $size_in_MB \n"; + $file = "ib_logfile2"; + $size_in_MB = (-s "$dir/$file") / (1024 * 1024);; + print "The size of the $file file: $size_in_MB \n"; + $file = "ib_logfile3"; + $size_in_MB = (-s "$dir/$file") / (1024 * 1024);; + print "The size of the $file file: $size_in_MB \n"; + $file = "ib_logfile4"; + $size_in_MB = (-s "$dir/$file") / (1024 * 1024);; + print "The size of the $file file: $size_in_MB \n"; +EOF + + +USE db_wl6494; +SELECT id,LEFT(bfield,20) FROM t1; +--ERROR ER_DUP_ENTRY +INSERT INTO t1 VALUES (1,repeat('a',2000)),(2,repeat('b',2000)), +(3,repeat('c',2000)); +INSERT INTO t1 VALUES (21,repeat('a',2000)),(22,repeat('b',2000)), +(23,repeat('c',2000)); +SELECT id,LEFT(bfield,20) FROM t1; + +# clenaup of test +# restart with different redo log size +DROP TABLE t1; +DROP DATABASE db_wl6494; +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc +# Do something while server is down +--error 0,1 +--move_file $SEARCH_FILE $MYSQLTEST_VARDIR/log/mysqld.1.err.old1 +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +# set log size to 3*3M +--exec echo "restart: --innodb-fast-shutdown=2 --innodb-log-file-size=3M --innodb_log_files_in_group=3" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +SELECT @@innodb_log_file_size; +SELECT @@innodb_log_files_in_group; + +# Testcase 2 - set log file size < existing size and innodb_log_files_in_group < old value +--disable_warnings +DROP DATABASE IF EXISTS db_wl6494; +--enable_warnings +CREATE DATABASE db_wl6494; +USE db_wl6494; + +CREATE TABLE t1(id INT PRIMARY KEY,bfield blob) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,repeat('a',2000)),(2,repeat('b',2000)), +(3,repeat('c',2000)); +START TRANSACTION; +INSERT INTO t1 VALUES (11,repeat('a',2000)),(12,repeat('b',2000)), +(13,repeat('c',2000)); +SAVEPOINT A; +INSERT INTO t1 VALUES (21,repeat('a',2000)),(22,repeat('b',2000)), +(23,repeat('c',2000)); +SAVEPOINT B; +SELECT id,LEFT(bfield,20) FROM t1; +ROLLBACK TO A; +COMMIT; +SELECT id,LEFT(bfield,20) FROM t1; + +# restart with different redo log size +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +# set log size from 3*3M to 2*2M +--exec echo "restart: --innodb-log-file-size=2M --innodb_log_files_in_group=2 --log-error=$MYSQLTEST_VARDIR/log/case2.err" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +SELECT @@innodb_log_file_size; +SELECT @@innodb_log_files_in_group; + + +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/case2.err; +let SEARCH_PATTERN= InnoDB: Starting crash recovery; +--source include/search_pattern_in_file.inc + + +USE db_wl6494; +SELECT id,LEFT(bfield,20) FROM t1; +--ERROR ER_DUP_ENTRY +INSERT INTO t1 VALUES (1,repeat('a',2000)),(2,repeat('b',2000)), +(3,repeat('c',2000)); +INSERT INTO t1 VALUES (21,repeat('a',2000)),(22,repeat('b',2000)), +(23,repeat('c',2000)); +SELECT id,LEFT(bfield,20) FROM t1; + +# end of testcase 2. Do not drop table/database as it is used in foloowing case + +# testcase misc +let MYSQLD_DATADIR= `select @@datadir`; +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err; +let $args=--loose-console > $SEARCH_FILE 2>&1; + +# Stop the server +SET GLOBAL innodb_fast_shutdown=0; +let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; +--exec echo "wait" > $restart_file +--shutdown_server +--source include/wait_until_disconnected.inc + +--echo "test misc 1" +--error 1 +--exec $MYSQLD_CMD $args --innodb-log-group-home-dir=foo\;bar +let SEARCH_PATTERN= syntax error in innodb_log_group_home_dir; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo "test misc 2" +--error 1 +--exec $MYSQLD_CMD $args --innodb-mirrored-log-groups=2 +let SEARCH_PATTERN= innodb_mirrored_log_groups is an unimplemented feature and the variable will be completely removed in a future version. Using values other than 1 is not supported.; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo "test misc 3" +--error 1 +--exec $MYSQLD_CMD $args --innodb-read-only +let SEARCH_PATTERN= InnoDB: Cannot resize log files in read-only mode; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo "test misc 4" +# We should have perfectly synced files here. +# Rename the log files, and trigger an error in recovery. +#--move_file $MYSQLD_DATADIR/ib_logfile101 $MYSQLD_DATADIR/ib_logfile0 +--move_file $MYSQLD_DATADIR/ib_logfile1 $MYSQLD_DATADIR/ib_logfile1_hidden +--error 1 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: Only one log file found; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +#--move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile101 +--move_file $MYSQLD_DATADIR/ib_logfile1_hidden $MYSQLD_DATADIR/ib_logfile1 + +--echo "test misc 5" +# make copy of ib_logfile0 before editing +--move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile0_hidden +perl; +die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/ib_logfile0"); +print FILE "garbage"; +close(FILE); +EOF +--error 1 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: .*ib_logfile0 size 7 is not a multiple of innodb_page_size; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--remove_file $MYSQLD_DATADIR/ib_logfile0 +--move_file $MYSQLD_DATADIR/ib_logfile0_hidden $MYSQLD_DATADIR/ib_logfile0 + + +--echo "test misc 6" +--move_file $MYSQLD_DATADIR/ib_logfile1 $MYSQLD_DATADIR/ib_logfile1_hidden +perl; +die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/ib_logfile1"); +print FILE "junkfill" x 131072; +close(FILE); +EOF + +--error 1 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: .*ib_logfile1 is of different size; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--remove_file $MYSQLD_DATADIR/ib_logfile1 +--move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile0_hidden + +# restart server +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect +USE db_wl6494; +SELECT id,LEFT(bfield,20) FROM t1; +--ERROR ER_DUP_ENTRY +INSERT INTO t1 VALUES (1,repeat('a',2000)),(2,repeat('b',2000)), +(3,repeat('c',2000)); + +# cleanup and set original values +DROP TABLE t1; +DROP DATABASE db_wl6494; +--error 0,1 +--remove_file $MYSQLTEST_VARDIR/log/mysqld.1.err.old1 +--error 0,1 +--remove_file $MYSQLTEST_VARDIR/log/case1.err +--error 0,1 +--remove_file $MYSQLTEST_VARDIR/log/case2.err +--remove_file $MYSQLD_DATADIR/ib_logfile0_hidden +--remove_file $MYSQLD_DATADIR/ib_logfile1_hidden +--disable_query_log +eval SET GLOBAL INNODB_FILE_FORMAT=$innodb_file_format; +eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; +--enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb-log-file-size.test b/mysql-test/suite/innodb/t/innodb-log-file-size.test new file mode 100644 index 00000000000..43dcd09e8b6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-log-file-size.test @@ -0,0 +1,213 @@ +# Test resizing the InnoDB redo log. + +--source include/have_innodb.inc +--source include/have_debug.inc + +# Valgrind would complain about memory leaks when we crash on purpose. +--source include/not_valgrind.inc +# Embedded server does not support crashing +--source include/not_embedded.inc +# Avoid CrashReporter popup on Mac +--source include/not_crashrep.inc + +if (`SELECT @@innodb_log_file_size = 1048576`) { + --skip Test requires innodb_log_file_size>1M. +} + +call mtr.add_suppression("InnoDB: Resizing redo log"); +call mtr.add_suppression("InnoDB: Starting to delete and rewrite log files"); +call mtr.add_suppression("InnoDB: New log files created"); +call mtr.add_suppression("InnoDB: The log sequence numbers [0-9]+ and [0-9]+ in ibdata files do not match the log sequence number [0-9]+ in the ib_logfiles"); + +CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB; + +SET DEBUG='+d,crash_commit_before'; +# Write file to make mysql-test-run.pl restart the server +--exec echo "restart: --innodb-log-file-size=6M" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--error 2013 +INSERT INTO t1 VALUES (42); + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT * FROM t1; + +INSERT INTO t1 VALUES (42); + +SET DEBUG='+d,crash_commit_before'; +# Write file to make mysql-test-run.pl restart the server +--exec echo "restart: --innodb-log-files-in-group=3 --innodb-log-file-size=5M" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--error 2013 +DELETE FROM t1; + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT * FROM t1; + +INSERT INTO t1 VALUES (123); + +let MYSQLD_DATADIR= `select @@datadir`; +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err; +let $args=--loose-console > $SEARCH_FILE 2>&1; +let crash=$args --innodb-force-recovery-crash; + +SET DEBUG='+d,crash_commit_before'; +# Write file to make mysql-test-run.pl restart the server +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--error 2013 +DELETE FROM t1; + +--error 1 +--exec $MYSQLD_CMD $args --innodb-log-group-home-dir=foo\;bar +let SEARCH_PATTERN= syntax error in innodb_log_group_home_dir; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--error 1 +--exec $MYSQLD_CMD $args --innodb-mirrored-log-groups=2 +let SEARCH_PATTERN= innodb_mirrored_log_groups is an unimplemented feature and the variable will be completely removed in a future version. Using values other than 1 is not supported.; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +# On Windows, DBUG_SUICIDE() does exit(3) instead of SIGKILL (128+9). +--echo --innodb-force-recovery-crash=1 +--error 3 +--exec $MYSQLD_CMD $crash=1 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=2 +--error 3 +--exec $MYSQLD_CMD $crash=2 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +--echo --innodb-force-recovery-crash=3 +--error 3 +--exec $MYSQLD_CMD $crash=3 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--error 1 +--exec $MYSQLD_CMD $args --innodb-read-only +let SEARCH_PATTERN= InnoDB: Recovery skipped, --innodb-read-only set!; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Can.t initiate database recovery, running in read-only-mode; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo --innodb-force-recovery-crash=4 +--error 3 +--exec $MYSQLD_CMD $crash=4 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=5 +--error 3 +--exec $MYSQLD_CMD $crash=5 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--error 1 +--exec $MYSQLD_CMD $args --innodb-read-only +let SEARCH_PATTERN= InnoDB: Can.t initiate database recovery, running in read-only-mode; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo --innodb-force-recovery-crash=6 +--error 3 +--exec $MYSQLD_CMD $crash=6 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=7 +--error 3 +--exec $MYSQLD_CMD $crash=7 +# this crashes right after deleting all log files +--remove_file $SEARCH_FILE + +--error 1 +--exec $MYSQLD_CMD $args --innodb-read-only +let SEARCH_PATTERN= InnoDB: Cannot create log files in read-only mode; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo --innodb-force-recovery-crash=8 +--error 3 +--exec $MYSQLD_CMD $crash=8 +let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=9 +--error 3 +--exec $MYSQLD_CMD $crash=9 +let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +# We should have perfectly synced files here. +# Rename the log files, and trigger an error in recovery. +--move_file $MYSQLD_DATADIR/ib_logfile101 $MYSQLD_DATADIR/ib_logfile0 +--move_file $MYSQLD_DATADIR/ib_logfile1 $MYSQLD_DATADIR/ib_logfile1_hidden +--error 1 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: Only one log file found; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile101 + +perl; +die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/ib_logfile0"); +print FILE "garbage"; +close(FILE); +EOF +--error 1 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: Log file .*ib_logfile0 size 7 is not a multiple of innodb_page_size; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--remove_file $MYSQLD_DATADIR/ib_logfile0 +--move_file $MYSQLD_DATADIR/ib_logfile101 $MYSQLD_DATADIR/ib_logfile0 + +perl; +die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/ib_logfile1"); +print FILE "junkfill" x 131072; +close(FILE); +EOF + +--error 1 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: Log file .*ib_logfile1 is of different size 1048576 bytes than other log files; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--remove_file $MYSQLD_DATADIR/ib_logfile1 +--move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile101 +--move_file $MYSQLD_DATADIR/ib_logfile1_hidden $MYSQLD_DATADIR/ib_logfile1 + +--echo --innodb-force-recovery-crash=10 +--error 3 +--exec $MYSQLD_CMD $crash=10 +let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Renaming log file .*ib_logfile101 to .*ib_logfile0; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-multiple-tablespaces.test b/mysql-test/suite/innodb/t/innodb-multiple-tablespaces.test new file mode 100644 index 00000000000..0b9d401475d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-multiple-tablespaces.test @@ -0,0 +1,538 @@ +# +# These test make sure that tables are visible after rebooting +# + +--source include/have_innodb.inc + +# Must have debug code to use SET SESSION debug +--source include/have_debug.inc + +# Valgrind would complain about memory leaks when we crash on purpose. +--source include/not_valgrind.inc + +# Embedded server does not support crashing +--source include/not_embedded.inc + +# Avoid CrashReporter popup on Mac +#--source include/not_crashrep.inc + +SET default_storage_engine=InnoDB; + +--disable_query_log +let $MYSQLD_DATADIR= `select @@datadir`; +let $data_directory = DATA DIRECTORY='$MYSQL_TMP_DIR/alt_dir'; + +let $innodb_file_per_table=`select @@innodb_file_per_table`; +let $innodb_file_format=`select @@innodb_file_format`; +--enable_query_log + +--mkdir $MYSQL_TMP_DIR/alt_dir +--mkdir $MYSQL_TMP_DIR/alt_dir/test +--mkdir $MYSQL_TMP_DIR/new_dir +--mkdir $MYSQL_TMP_DIR/new_dir/test + +--disable_query_log +# These errors are expected in the error log for this test. +call mtr.add_suppression("Could not find a valid tablespace file for"); +call mtr.add_suppression("Tablespace open failed for"); +call mtr.add_suppression("tablespace id and flags are"); +call mtr.add_suppression("but in the InnoDB data dictionary they are"); +call mtr.add_suppression("has been found in multiple places"); +call mtr.add_suppression("have been found in two places;"); +call mtr.add_suppression("Will not open the tablespace for"); +call mtr.add_suppression("Default location;"); +call mtr.add_suppression("Remote location;"); +call mtr.add_suppression("Dictionary location;"); +call mtr.add_suppression("Failed to find tablespace for table"); +call mtr.add_suppression("Attempt to open a tablespace previously opened"); +call mtr.add_suppression("A link file was found named"); +call mtr.add_suppression("but tablespace with that id or name does not exist."); +--enable_query_log + +--echo # +--echo # Test when tablespaces can be found at multiple places +--echo # SYS_DATAFILES will refer to the file at alt_dir. +--echo # Link File will refer to the file at new_dir. +--echo # Tablename Default SYS_DATAFILES Link_File +--echo # yyy Yes Yes Yes +--echo # nyy No Yes Yes +--echo # yny Yes No Yes +--echo # yyn Yes Yes No +--echo # nyw No Yes WrongFile +--echo # nwy No WrongFile Yes +--echo # wny WrongFile No Yes +--echo # ynw Yes No WrongFile +--echo # wyn WrongFile Yes No +--echo # ywn Yes WrongFile No +--echo # nnn No No No +--echo # www WrongFile WrongFile WrongFile +--echo # nolink No Yes, No ISL No +--echo # + +set global innodb_file_per_table=on; +set global innodb_file_format='Barracuda'; + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE yyy (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO yyy VALUES (1, 'yyy'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE nyy (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO nyy VALUES (1, 'nyy'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE yny (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO yny VALUES (1, 'yny'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE yyn (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO yyn VALUES (1, 'yyn'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE nyw (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO nyw VALUES (1, 'nyw'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE nwy (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO nwy VALUES (1, 'nwy'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE wny (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO wny VALUES (1, 'wny'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE ynw (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO ynw VALUES (1, 'ynw'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE wyn (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO wyn VALUES (1, 'wyn'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE ywn (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO ywn VALUES (1, 'ywn'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE nnn (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO nnn VALUES (1, 'nnn'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE www (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO www VALUES (1, 'www'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE nolink (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO nolink VALUES (1, 'no link file'); + +--echo # +--echo # Shutdown the server, copy and remove files. +--echo # +--source include/shutdown_mysqld.inc +--sleep 2 + +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # YYY; Tablespace found in 3 places +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQLD_DATADIR/test/yyy.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQL_TMP_DIR/new_dir/test/yyy.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/yyy.ibd > $MYSQLD_DATADIR/test/yyy.isl + +--echo # NYY; Tablespace found in alt_dir and new_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/nyy.ibd $MYSQL_TMP_DIR/new_dir/test/nyy.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/nyy.ibd > $MYSQLD_DATADIR/test/nyy.isl + +--echo # YNY; Tablespace found in default and new_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yny.ibd $MYSQLD_DATADIR/test/yny.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yny.ibd $MYSQL_TMP_DIR/new_dir/test/yny.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/yny.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/yny.ibd > $MYSQLD_DATADIR/test/yny.isl + +--echo # YYN; Tablespace found in default and alt_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyn.ibd $MYSQLD_DATADIR/test/yyn.ibd + +--echo # NYW; Copy the wrong file to new_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQL_TMP_DIR/new_dir/test/nyw.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/nyw.ibd > $MYSQLD_DATADIR/test/nyw.isl + +--echo # NWY; Copy the wrong file to alt_dir, good one to new_dir. +--copy_file $MYSQL_TMP_DIR/alt_dir/test/nwy.ibd $MYSQL_TMP_DIR/new_dir/test/nwy.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/nwy.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/nwy.ibd > $MYSQLD_DATADIR/test/nwy.isl +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQL_TMP_DIR/alt_dir/test/nwy.ibd + +--echo # WNY; Copy the wrong file to default, good one to new_dir, delete it form alt_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQLD_DATADIR/test/wny.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/wny.ibd $MYSQL_TMP_DIR/new_dir/test/wny.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/wny.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/wny.ibd > $MYSQLD_DATADIR/test/wny.isl + +--echo # YNW; Copy the file to default, wrong one to new_dir, delete it form alt_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/ynw.ibd $MYSQLD_DATADIR/test/ynw.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/ynw.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQL_TMP_DIR/new_dir/test/ynw.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/ynw.ibd > $MYSQLD_DATADIR/test/ynw.isl + +--echo # WYN; Copy the wrong file to default +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQLD_DATADIR/test/wyn.ibd + +--echo # YWN; Copy the file to default, wrong one to alt_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/ywn.ibd $MYSQLD_DATADIR/test/ywn.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/ywn.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQL_TMP_DIR/alt_dir/test/ywn.ibd + +--echo # NNN; Delete the tablespace and ISL +--remove_file $MYSQLD_DATADIR/test/nnn.isl +--remove_file $MYSQL_TMP_DIR/alt_dir/test/nnn.ibd + +--echo # WWW; Put the wrong file in all three locations +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQLD_DATADIR/test/www.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/www.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQL_TMP_DIR/alt_dir/test/www.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd $MYSQL_TMP_DIR/new_dir/test/www.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/www.ibd > $MYSQLD_DATADIR/test/www.isl + +--echo # NOLINK; Delete the ISL file Since remote location is still in SYS_DATAFILES, +--echo # it should still be found. And the ISL file should be re-created. +--remove_file $MYSQLD_DATADIR/test/nolink.isl + +--echo # Make a backup of this tablespace to use later. +--copy_file $MYSQL_TMP_DIR/alt_dir/test/nolink.ibd $MYSQL_TMP_DIR/alt_dir/test/nolink.ibd.bak + +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # +--echo # Start the server and show the tablespaces. +--echo # +--source include/start_mysqld.inc + +--replace_result ./ MYSQLD_DATADIR/ $MYSQLD_DATADIR MYSQLD_DATADIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--error ER_NO_SUCH_TABLE +SELECT * FROM yyy; +--error ER_NO_SUCH_TABLE +SELECT * FROM nyy; +--error ER_NO_SUCH_TABLE +SELECT * FROM yny; +--error ER_NO_SUCH_TABLE +SELECT * FROM yyn; +SELECT * FROM nyw; +SELECT * FROM nwy; +SELECT * FROM wny; +SELECT * FROM ynw; +SELECT * FROM wyn; +SELECT * FROM ywn; +--error ER_NO_SUCH_TABLE +SELECT * FROM nnn; +--error ER_NO_SUCH_TABLE +SELECT * FROM www; +SELECT * FROM nolink; + +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE yyy; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE nyy; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE yny; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE yyn; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE nyw; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE nwy; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE wny; +SHOW CREATE TABLE ynw; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE wyn; +SHOW CREATE TABLE ywn; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE nnn; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE www; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE nolink; + +--echo # +--echo # List of files before DROP TABLES +--echo # +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # +--echo # Cleanup after restart +--echo # + +DROP TABLE yyy; +DROP TABLE nyy; +DROP TABLE yny; +DROP TABLE yyn; +DROP TABLE nyw; +DROP TABLE nwy; +DROP TABLE wny; +DROP TABLE ynw; +DROP TABLE wyn; +DROP TABLE ywn; +DROP TABLE nnn; +DROP TABLE www; +DROP TABLE nolink; + +--echo # +--echo # List of files not deleted by the DROP TABLES +--echo # +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--list_files $MYSQL_TMP_DIR/new_dir/test + +--remove_file $MYSQLD_DATADIR/test/www.ibd +--remove_file $MYSQLD_DATADIR/test/wny.ibd +--remove_file $MYSQLD_DATADIR/test/wyn.ibd +--remove_file $MYSQLD_DATADIR/test/yny.ibd +--remove_file $MYSQLD_DATADIR/test/yyn.ibd +--remove_file $MYSQLD_DATADIR/test/yyy.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/nwy.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/nyy.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/www.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/ywn.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/yyn.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/yyy.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/nyw.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/nyy.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/www.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/ynw.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/yny.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/yyy.ibd + +--echo # +--echo # List of files after removing leftover files +--echo # +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # +--echo # Create some tables again and this time, crash instead of shutdown +--echo # InnoDB recovery does not have the ability at this time to query +--echo # the data dictionary in order to determine if the table it is +--echo # openeing is the correct one, or to finde the previous location +--echo # of a tablespace from SYS_DATAFILES. It must rely on the ISL file +--echo # to tell the truth. But it can compare the current linked location +--echo # with a tablespace found in the default location and use the most +--echo # recent. +--echo # +--echo # Test recovery when tablespaces can be found at multiple places. +--echo # SYS_DATAFILES is unavailable during recovery. +--echo # Link File will refer to the file at alt_dir. +--echo # In each case except the control tablespace, the Link file will +--echo # exist with a file name in alt_dir. 'fnolink.ibd.bak' is the +--echo # source of the 'wrong' tablespaces. +--echo # +--echo # Tablename Default_Tablespace Remote_Tablespace +--echo # ny Yes Yes +--echo # wy Wrong Yes +--echo # yn Yes No +--echo # yw Yes Wrong +--echo # yy Yes Yes (both the same file) +--echo # + +set global innodb_file_per_table=on; +set global innodb_file_format='Barracuda'; + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE ny (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO ny VALUES (1, 'ny'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE wy (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO wy VALUES (1, 'wy'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE yn (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO yn VALUES (1, 'yn'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE yw (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO yw VALUES (1, 'yw'); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE yy (c1 INT KEY, c2 TEXT) ENGINE=InnoDB $data_directory; +INSERT INTO yy VALUES (1, 'yy'); + +--echo # +--echo # Crash the server, copy and remove files. +--echo # +BEGIN; +INSERT INTO ny VALUES (2, 'ny'); +INSERT INTO wy VALUES (2, 'wy'); +INSERT INTO yn VALUES (2, 'yn'); +INSERT INTO yw VALUES (2, 'yw'); +INSERT INTO yy VALUES (2, 'yy'); + +SELECT * FROM ny; +SELECT * FROM wy; +SELECT * FROM yn; +SELECT * FROM yw; +SELECT * FROM yy; + +# Request a crash on next execution of commit. +SET SESSION debug="+d,crash_commit_before"; +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Execute the statement that causes the crash. +--error 2013 +COMMIT; +--source include/wait_until_disconnected.inc +--sleep 2 + +--echo # +--echo # Now that the engine is not running, move files around to test various scenarios. +--echo # + +--echo # NY; Tablespace found in alt_dir but not the default directory. + +--echo # WY; The wrong tablespace is found in the default directory +--echo # and the correct one in alt_dir. +--copy_file $MYSQL_TMP_DIR/alt_dir/test/nolink.ibd.bak $MYSQLD_DATADIR/test/wy.ibd + +--echo # YW; Tablespace is found in the default directory but the wrong file in alt_dir. +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yw.ibd $MYSQLD_DATADIR/test/yw.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/yw.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/nolink.ibd.bak $MYSQL_TMP_DIR/alt_dir/test/yw.ibd + +--echo # YN; Tablespace found the default directory but not in alt_dir. +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yn.ibd $MYSQLD_DATADIR/test/yn.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/yn.ibd + +--echo # YY; Found in both default directory and alt-dir. +--copy_file $MYSQL_TMP_DIR/alt_dir/test/yy.ibd $MYSQLD_DATADIR/test/yy.ibd + +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Start the server with innodb-force-recovery=1 so that it does not quit +--echo # when it finds multiple possible locations for yy, wy and yw. +--echo # +--enable_reconnect +--exec echo "restart:--innodb-force-recovery=1" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT * FROM ny; +--error ER_NO_SUCH_TABLE +SELECT * FROM wy; +SELECT * FROM yn; +--error ER_NO_SUCH_TABLE +SELECT * FROM yw; +--error ER_NO_SUCH_TABLE +SELECT * FROM yy; + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE ny; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE wy; +SHOW CREATE TABLE yn; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE yw; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE yy; + +--replace_result ./ MYSQLD_DATADIR/ $MYSQLD_DATADIR MYSQLD_DATADIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo # +--echo # Shutdown the server and remove extra tablespace files. +--echo # +--source include/shutdown_mysqld.inc +--sleep 2 + +--echo # +--echo # List of files before removing unused files +--echo # + +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--remove_file $MYSQLD_DATADIR/test/ny.isl +--remove_file $MYSQLD_DATADIR/test/wy.ibd +--remove_file $MYSQLD_DATADIR/test/wy.isl +--remove_file $MYSQLD_DATADIR/test/yn.ibd +--remove_file $MYSQLD_DATADIR/test/yn.isl +--remove_file $MYSQLD_DATADIR/test/yw.ibd +--remove_file $MYSQLD_DATADIR/test/yw.isl +--remove_file $MYSQLD_DATADIR/test/yy.ibd +--remove_file $MYSQLD_DATADIR/test/yy.isl + +--remove_file $MYSQL_TMP_DIR/alt_dir/test/nolink.ibd.bak +--remove_file $MYSQL_TMP_DIR/alt_dir/test/ny.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/wy.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/yw.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/yy.ibd + +--echo # +--echo # List of files before restart and DROP TABLES +--echo # + +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Start the server without using force_recover. +--echo # +--source include/start_mysqld.inc + +DROP TABLE ny; +DROP TABLE wy; +DROP TABLE yn; +DROP TABLE yw; +DROP TABLE yy; + +--echo # +--echo # List of files after DROP TABLES +--echo # +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Cleanup +--echo # + +--rmdir $MYSQL_TMP_DIR/alt_dir/test +--rmdir $MYSQL_TMP_DIR/alt_dir +--rmdir $MYSQL_TMP_DIR/new_dir/test +--rmdir $MYSQL_TMP_DIR/new_dir + +-- disable_query_log +eval set global innodb_file_format=$innodb_file_format; +eval set global innodb_file_per_table=$innodb_file_per_table; + diff --git a/mysql-test/suite/innodb/t/innodb-read-view.test b/mysql-test/suite/innodb/t/innodb-read-view.test new file mode 100644 index 00000000000..729d40be236 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-read-view.test @@ -0,0 +1,176 @@ +# DEBUG_SYNC must be compiled in. +--source include/have_debug_sync.inc + +# We need to test the use case: +# a. Create a transaction T1 that will be promoted to RW. +# b. Create a transaction T2 that will be promoted to RW. +# a. Create a RO transaction T3 +# d. T3 does a select - creates a read view that doesn't include T1 and T2 +# e. T1 & T2 do some updates - this promotes T1 & T2 to RW transactions +# f. T1 & T2 Commit +# g. T3 Does a select - it should not see the changes of T1 & T2 + +--source include/have_innodb.inc + +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); + +CREATE TABLE t2 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t2 VALUES(0, "a"); +INSERT INTO t2 VALUES(1, "b"); +INSERT INTO t2 VALUES(2, "c"); +INSERT INTO t2 VALUES(3, "d"); + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) + +connection con1; +--echo 'T1' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t2; + +connection default; +--echo 'T2' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1; + +connection con2; +--echo 'T3' +SET AUTOCOMMIT=0; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +SELECT * FROM t1; +SELECT * FROM t2; + +connection default; +--echo 'T1' +UPDATE t2 SET c1 = c1 + 100; +SELECT * FROM t2; +COMMIT; + +connection default; +--echo 'T2' +UPDATE t1 SET c1 = c1 + 100; +SELECT * FROM t1; +COMMIT; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +--send SELECT * FROM t1; + +connection default; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +--send SELECT * FROM t2; + +connection default; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection default; +disconnect con1; +disconnect con2; + +# We need to test the use case: +# a. Create a transaction T1 that will be promoted to RW. +# b. Create a transaction T2 that will be promoted to RW. +# c. T2 does some updates - this promotes T2 to RW transactions +# d. T2 Commits +# e. Create a RO transaction T3 +# f. T3 does a select - creates a read view that doesn't include T1 +# g. T1 does some updates - this promotes T1 to RW transactions +# h. T1 Commits +# i. T3 Does a select - it should not see the changes made by T1 but should +# see the changes by T2 + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) + +connection con1; +--echo 'T1' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1; + +connection default; +--echo 'T2' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t2; +UPDATE t2 SET c1 = c1 + 100; +SELECT * FROM t2; +COMMIT; + +connection con2; +--echo 'T3' +SET AUTOCOMMIT=0; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +SELECT * FROM t1; +SELECT * FROM t2; + +connection con1; +--echo 'T1' +UPDATE t1 SET c1 = c1 + 100; +SELECT * FROM t1; +COMMIT; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +--send SELECT * FROM t1; + +connection con1; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +--send SELECT * FROM t2; + +connection default; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t1; +DROP TABLE t2; + +# Clean up resources used in this test case. +--disable_warnings +SET DEBUG_SYNC= 'RESET'; +--enable_warnings diff --git a/mysql-test/suite/innodb/t/innodb-status-output.test b/mysql-test/suite/innodb/t/innodb-status-output.test new file mode 100644 index 00000000000..cf18c18deee --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-status-output.test @@ -0,0 +1,108 @@ +--source include/have_innodb.inc +# This restarts the server and waits a long time for output. +--source include/big_test.inc +# Embedded server does not support restarting. +--source include/not_embedded.inc + +# Test the deprecation messages and connection to the flags. +CREATE TABLE innodb_monitor(a SERIAL) ENGINE=InnoDB; +SHOW VARIABLES LIKE 'innodb_status_output%'; +DROP TABLE innodb_monitor; +SHOW VARIABLES LIKE 'innodb_status_output%'; +CREATE TABLE innodb_lock_monitor(a SERIAL) ENGINE=InnoDB; +SHOW VARIABLES LIKE 'innodb_status_output%'; +DROP TABLE innodb_lock_monitor; +SHOW VARIABLES LIKE 'innodb_status_output%'; +CREATE TABLE innodb_tablespace_monitor(a SERIAL) ENGINE=InnoDB; +DROP TABLE innodb_tablespace_monitor; +CREATE TABLE innodb_table_monitor(a SERIAL) ENGINE=InnoDB; +DROP TABLE innodb_table_monitor; + +CREATE TABLE t(a SERIAL) ENGINE=InnoDB; +INSERT INTO t VALUES(42); + +# Restart, writing the error log to a different file. +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server + +let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/innodb-status-output.err; + +--error 0,1 +--remove_file $SEARCH_FILE + +# Test that the output appears. +--exec echo "restart: --log-error=$SEARCH_FILE" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +BEGIN; +SELECT * FROM t FOR UPDATE; +# Enable full output. +SET GLOBAL innodb_status_output_locks=ON; +SET GLOBAL innodb_status_output=ON; +SELECT SLEEP(30); +COMMIT; + +# Restart, check the log output +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server + +let SEARCH_PATTERN= INNODB MONITOR OUTPUT; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= SELECT SLEEP.*\nTABLE LOCK.*\nRECORD LOCKS space id; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--exec echo "restart: --log-error=$SEARCH_FILE" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +BEGIN; +SELECT * FROM t FOR UPDATE; +# This alone should not enable any output. +SET GLOBAL innodb_status_output_locks=ON; +SELECT SLEEP(30); +COMMIT; + +# Restart, check the log output +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server + +# We should not see any extra output. +let SEARCH_PATTERN= ready for connections.*\nVersion:.*\n.*Normal shutdown; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--exec echo "restart: --log-error=$SEARCH_FILE" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +BEGIN; +SELECT * FROM t FOR UPDATE; +# Enable some output. +SET GLOBAL innodb_status_output=ON; +SELECT SLEEP(30); +COMMIT; + +# Restart, check the log output +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server + +# We should have some extra output. +let SEARCH_PATTERN= INNODB MONITOR OUTPUT; +--source include/search_pattern_in_file.inc +# No RECORD LOCKS output expected +let SEARCH_PATTERN= SELECT SLEEP.*\n------; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +# Clean up. +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb-system-table-view.test b/mysql-test/suite/innodb/t/innodb-system-table-view.test new file mode 100644 index 00000000000..3ed5bc6e47a --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-system-table-view.test @@ -0,0 +1,171 @@ +# This is the test for Information Schema System Table View +# that displays the InnoDB system table content through +# information schema tables. + +--source include/have_innodb.inc + +--disable_query_log +SET default_storage_engine=InnoDB; +let $MYSQLD_DATADIR= `select @@datadir`; +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +--enable_query_log + +# The IDs of mysql.innodb_table_stats and mysql.innodb_index_stats are +# unpredictable, probably they depend on whether mtr has created the +# database for this test from scratch or is using a previously created +# database where those tables have been dropped and recreated. If we can +# force mtr to use a freshly created database for this test then the following +# complications can be removed and the test be reverted to the version +# it was before the patch that adds this comment. +--let $table_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_table_stats'` +--let $index_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_index_stats'` +--let $rep_table_1 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_master_info'` +--let $rep_table_2 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_relay_log_info'` +--let $rep_table_3 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_worker_info'` + +--disable_query_log +--eval SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE table_id NOT IN ($table_stats_id, $index_stats_id, $rep_table_1, $rep_table_2, $rep_table_3) ORDER BY table_id; + +--eval SELECT table_id,pos,mtype,prtype,len,name FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE table_id NOT IN ($table_stats_id, $index_stats_id, $rep_table_1, $rep_table_2, $rep_table_3) ORDER BY table_id, pos; + +# The SELECT * version of the query below has been moved to innodb_4k, +# innodb_8k & innodb_16k since the root page number changes with page size. +--eval SELECT index_id,table_id,type,n_fields,space,name FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE table_id NOT IN ($table_stats_id, $index_stats_id, $rep_table_1, $rep_table_2, $rep_table_3) ORDER BY index_id; +--enable_query_log + +SELECT index_id,pos,name FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS + WHERE name NOT IN ('database_name', 'table_name', 'index_name', 'stat_name', 'id', 'host', 'port') + ORDER BY index_id, pos; + +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; + +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; + +SET GLOBAL innodb_file_format=`Barracuda`; +SET GLOBAL innodb_file_per_table=ON; + +--disable_warnings +DROP TABLE IF EXISTS t_redundant, t_compact, t_compressed, t_dynamic; +--enable_warnings + +CREATE TABLE t_redundant (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; +CREATE TABLE t_compact (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; +CREATE TABLE t_compressed (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb; +CREATE TABLE t_dynamic (a INT KEY, b TEXT) ROW_FORMAT=DYNAMIC ENGINE=innodb; + +--sorted_result +SELECT name, n_cols, file_format, row_format + FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES + WHERE space > 0; +--sorted_result +SELECT name, file_format, row_format + FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES + WHERE name LIKE 'test%'; +--replace_result ./ MYSQLD_DATADIR/ $MYSQLD_DATADIR MYSQLD_DATADIR +--sorted_result +SELECT path FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES + WHERE path LIKE '%test%'; + +DROP TABLE t_redundant, t_compact, t_compressed, t_dynamic; +--disable_query_log +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +--enable_query_log + +SELECT count(*) FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS; + +# Create a foreign key constraint, and verify the information +# in INFORMATION_SCHEMA.INNODB_SYS_FOREIGN and +# INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS +CREATE TABLE parent (id INT NOT NULL, + PRIMARY KEY (id)) ENGINE=INNODB; + +CREATE TABLE child (id INT, parent_id INT, + INDEX par_ind (parent_id), + CONSTRAINT constraint_test + FOREIGN KEY (parent_id) REFERENCES parent(id) + ON DELETE CASCADE) ENGINE=INNODB; + +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; + +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; + +# Insert a row in the table "parent", and see whether that reflected in +# INNODB_SYS_TABLESTATS +INSERT INTO parent VALUES(1); + +--sorted_result +SELECT name, num_rows, ref_count +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name LIKE "%parent"; + +--sorted_result +SELECT NAME, FLAG, N_COLS FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES; + +--sorted_result +SELECT name, n_fields +from INFORMATION_SCHEMA.INNODB_SYS_INDEXES +WHERE table_id In (SELECT table_id from + INFORMATION_SCHEMA.INNODB_SYS_TABLES + WHERE name LIKE "%parent%"); + +--sorted_result +SELECT name, n_fields +from INFORMATION_SCHEMA.INNODB_SYS_INDEXES +WHERE table_id In (SELECT table_id from + INFORMATION_SCHEMA.INNODB_SYS_TABLES + WHERE name LIKE "%child%"); + +--sorted_result +SELECT name, pos, mtype, len +from INFORMATION_SCHEMA.INNODB_SYS_COLUMNS +WHERE table_id In (SELECT table_id from + INFORMATION_SCHEMA.INNODB_SYS_TABLES + WHERE name LIKE "%child%"); + +DROP TABLE child; + +DROP TABLE parent; + +# Create table with 2 columns in the foreign key constraint +CREATE TABLE parent (id INT NOT NULL, newid INT NOT NULL, + PRIMARY KEY (id, newid)) ENGINE=INNODB; + +CREATE TABLE child (id INT, parent_id INT, + INDEX par_ind (parent_id), + CONSTRAINT constraint_test + FOREIGN KEY (id, parent_id) REFERENCES parent(id, newid) + ON DELETE CASCADE) ENGINE=INNODB; + +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; + +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; + +INSERT INTO parent VALUES(1, 9); + +# Nested query will open the table handle twice +--sorted_result +SELECT * FROM parent WHERE id IN (SELECT id FROM parent); + +--sorted_result +SELECT name, num_rows, ref_count +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS +WHERE name LIKE "%parent"; + +DROP TABLE child; + +DROP TABLE parent; + +--disable_query_log +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +--enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb-tablespace.test b/mysql-test/suite/innodb/t/innodb-tablespace.test new file mode 100644 index 00000000000..ae14eaa0177 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-tablespace.test @@ -0,0 +1,473 @@ +# +# A series of tests to show the correct tablespace behavior. +# See also; parts.partition_basic_symlink_innodb.test for +# partition related tests with remote tablespaces. +# See innodb.innodb-restart for tablespace migration tests. +# +--source include/have_innodb.inc +--source include/have_partition.inc +SET default_storage_engine=InnoDB; + +--echo # +--echo # TABLESPACE related tests. +--echo # + +# Set up some variables +LET $MYSQLD_DATADIR = `select @@datadir`; +LET $data_directory_clause = DATA DIRECTORY='$MYSQL_TMP_DIR/alt_dir'; +LET $index_directory_clause = INDEX DIRECTORY='$MYSQL_TMP_DIR/alt_dir'; + +# These values can change during the test +LET $innodb_file_format_orig=`select @@innodb_file_format`; +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +LET $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; + +--echo # +--echo # CREATE TABLE ... DATA DIRECTORY +--echo # Innodb does not support INDEX DIRECTORY. +--echo # +SET SESSION innodb_strict_mode = ON; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error ER_ILLEGAL_HA +eval CREATE TABLE t1 (a int KEY, b text) $index_directory_clause; +SHOW WARNINGS; + +--echo # +--echo # Without strict mode, INDEX DIRECTORY is just ignored +--echo # +SET SESSION innodb_strict_mode = OFF; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t1 (a int KEY, b text) $index_directory_clause; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # Innodb does not support DATA DIRECTORY without innodb_file_per_table=ON. +--echo # +SET SESSION innodb_strict_mode = ON; +SET GLOBAL innodb_file_per_table=OFF; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error ER_ILLEGAL_HA +eval CREATE TABLE t1 (a int KEY, b text) $data_directory_clause; +SHOW WARNINGS; + +--echo # +--echo # Without strict mode, DATA DIRECTORY without innodb_file_per_table=ON is just ignored. +--echo # +SET SESSION innodb_strict_mode = OFF; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t1 (a int KEY, b text) $data_directory_clause; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # Now set innodb_file_per_table so that DATA DIRECTORY can be tested. +SET GLOBAL innodb_file_per_table=ON; + +--echo # +--echo # Create the tablespace in MYSQL_TMP_DIR/alt_dir +--echo # InnoDB will create the sub-directories if needed. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t1 (a int KEY, b text) $data_directory_clause; +SHOW WARNINGS; +INSERT INTO t1 VALUES (1, "Create the tablespace"); +SELECT * FROM t1; + +--echo # +--echo # Check if link file exists in MYSQLD_DATADIR +--echo # +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo # Check if tablespace file exists where we specified in DATA DIRECTORY +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Check that DATA DIRECTORY shows up in the SHOW CREATE TABLE results. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t1; + +--echo # Show that the new system tables have this table in them correctly +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables WHERE name LIKE 'test%'; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo # +--echo # Show that the system tables are updated on drop table +--echo # +DROP TABLE t1; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables WHERE name LIKE 'test%' + ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo # +--echo # Create the same table a second time in the same place +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t1 (a int KEY, b text) $data_directory_clause; + +INSERT INTO t1 VALUES (2, "Create the same table a second time in the same place"); +SELECT * FROM t1; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t1; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables WHERE name LIKE 'test%' + ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Truncate the table, then insert and verify +--echo # +TRUNCATE TABLE t1; +INSERT INTO t1 VALUES (3, "Truncate the table, then insert"); +SELECT * FROM t1; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables WHERE name LIKE 'test%' + ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Rename the table, then insert and verify +--echo # +RENAME TABLE t1 TO t2; +INSERT INTO t2 VALUES (4, "Rename the table, then insert"); +SELECT * FROM t2; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables WHERE name LIKE 'test%' + ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # CREATE TABLE LIKE does not retain DATA DIRECTORY automatically. +--echo # +CREATE TABLE t3 LIKE t2; +INSERT INTO t3 VALUES (5, "CREATE TABLE LIKE"); +SELECT * FROM t3; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables WHERE name LIKE 'test%' + ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_result ./ MYSQLD_DATADIR/ $MYSQLD_DATADIR MYSQLD_DATADIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test + +--echo # +--echo # Now make sure the tables can be fully dropped. +--echo # +DROP TABLE t2, t3; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables WHERE name LIKE 'test%' + ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Be sure SQL MODE "NO_DIR_IN_CREATE" prevents the use of DATA DIRECTORY +--echo # +SET @org_mode=@@sql_mode; +SET @@sql_mode='NO_DIR_IN_CREATE'; +SELECT @@sql_mode; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t1 (a int, b text) $data_directory_clause; +SHOW WARNINGS; +INSERT INTO t1 VALUES (6, "SQL MODE NO_DIR_IN_CREATE prevents DATA DIRECTORY"); +# Checking if tablespace exists in --datadir since DATA DIRECTORY was ignored. +--file_exists $MYSQLD_DATADIR/test/t1.ibd +DROP TABLE t1; +set @@sql_mode=@org_mode; + +--echo # +--echo # MySQL engine does not allow DATA DIRECTORY to be +--echo # within --datadir for any engine, including InnoDB +--echo # +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +--error ER_WRONG_ARGUMENTS +eval CREATE TABLE t1 (a int KEY, b text) DATA DIRECTORY '$MYSQLD_DATADIR/test'; + +--echo # TEMPORARY tables are incompatible with DATA DIRECTORY +SET SESSION innodb_strict_mode = ON; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error ER_ILLEGAL_HA +eval CREATE TEMPORARY TABLE t1 (a int KEY, b text) engine=InnoDB $data_directory_clause; +SHOW WARNINGS; +SET SESSION innodb_strict_mode = OFF; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TEMPORARY TABLE t1 (a int KEY, b text) engine=InnoDB $data_directory_clause; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +DROP TABLE t1; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Create the remote table via static DDL statements in a stored procedure +--echo # +DELIMITER |; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE PROCEDURE static_proc() BEGIN CREATE TABLE t1 (a int KEY, b text) $data_directory_clause; END | +DELIMITER ;| +CALL static_proc; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +INSERT INTO t1 VALUES (7, "Create the remote table via static DDL statements"); +SELECT * FROM t1; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t1; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +DROP PROCEDURE static_proc; +DROP TABLE t1; + +--echo # +--echo # Create the remote table via dynamic DDL statements in a stored procedure +--echo # +DELIMITER |; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE PROCEDURE dynamic_proc() BEGIN PREPARE stmt1 FROM "CREATE TABLE t1 (a int KEY, b text) $data_directory_clause"; EXECUTE stmt1; END | +DELIMITER ;| +CALL dynamic_proc; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +INSERT INTO t1 VALUES (8, "Create the remote table via dynamic DDL statements"); +SELECT * FROM t1; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t1; +--echo ---- MYSQLD_DATADIR/test +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +DROP PROCEDURE dynamic_proc; +DROP TABLE t1; + +--echo # +--echo # CREATE, DROP, ADD and TRUNCATE PARTITION with DATA DIRECTORY +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE emp ( + id INT NOT NULL, + store_name VARCHAR(30), + parts VARCHAR(30), + store_id INT +) +PARTITION BY LIST(store_id) ( + PARTITION east VALUES IN (10,20,30) + DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir_east', + PARTITION north VALUES IN (40,50,60) + DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir_north', + PARTITION west VALUES IN (70,80,100) + DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir_west' +); + +INSERT INTO emp values(1,'Oracle','NUTT',10); +INSERT INTO emp values(2,'HUAWEI','BOLT',40); +INSERT INTO emp values(3,'IBM','NAIL',70); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp; +# InnoDB always converts table names to lower case on Windows +--replace_regex /emp#P#/emp#p#/ +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +SELECT * FROM emp; +--echo ---- MYSQLD_DATADIR/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir_east/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_east/test +--echo ---- MYSQL_TMP_DIR/alt_dir_north/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_north/test +--echo ---- MYSQL_TMP_DIR/alt_dir_west/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_west/test + +--echo # +--echo # DROP one PARTITION. +--echo # +ALTER TABLE emp DROP PARTITION west; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp; +--replace_regex /emp#P#/emp#p#/ +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +SELECT * FROM emp; +--echo ---- MYSQLD_DATADIR/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir_east/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_east/test +--echo ---- MYSQL_TMP_DIR/alt_dir_north/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_north/test +--echo ---- MYSQL_TMP_DIR/alt_dir_west/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_west/test + +--echo # +--echo # ADD the PARTITION back. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval ALTER TABLE emp ADD PARTITION ( + PARTITION west VALUES IN (70,80,100) + DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir_west'); +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp; +--replace_regex /emp#P#/emp#p#/ +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +INSERT INTO emp VALUES(3,'IBM','NAIL',70); +SELECT * FROM emp; +--echo ---- MYSQLD_DATADIR/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir_east/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_east/test +--echo ---- MYSQL_TMP_DIR/alt_dir_north/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_north/test +--echo ---- MYSQL_TMP_DIR/alt_dir_west/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_west/test + +--echo # +--echo # TRUNCATE one PARTITION. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +ALTER TABLE emp TRUNCATE PARTITION west; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp; +--replace_regex /emp#P#/emp#p#/ +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +--replace_regex /emp#P#/emp#p#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +SELECT * FROM emp; +INSERT INTO emp VALUES(3,'IBM','NAIL',70); +SELECT * FROM emp; +--echo ---- MYSQLD_DATADIR/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQLD_DATADIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir_east/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_east/test +--echo ---- MYSQL_TMP_DIR/alt_dir_north/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_north/test +--echo ---- MYSQL_TMP_DIR/alt_dir_west/test +--replace_regex /emp#P#/emp#p#/ +--list_files $MYSQL_TMP_DIR/alt_dir_west/test + +DROP TABLE emp; + +--echo # +--echo # Cleanup +--echo # + +--rmdir $MYSQL_TMP_DIR/alt_dir/test +--rmdir $MYSQL_TMP_DIR/alt_dir + +--disable_query_log +EVAL SET GLOBAL innodb_file_format=$innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +EVAL SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; +--enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt b/mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt new file mode 100644 index 00000000000..8071b4f7282 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt @@ -0,0 +1,2 @@ +--innodb-use-sys-malloc=true +--innodb-large-prefix=true diff --git a/mysql-test/suite/innodb/t/innodb-use-sys-malloc.test b/mysql-test/suite/innodb/t/innodb-use-sys-malloc.test new file mode 100644 index 00000000000..7acd3f5fe81 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-use-sys-malloc.test @@ -0,0 +1,45 @@ +-- source include/have_innodb.inc + +#display current value of innodb_use_sys_malloc +SELECT @@GLOBAL.innodb_use_sys_malloc; +--echo 1 Expected + +#try changing it. Should fail. +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@GLOBAL.innodb_use_sys_malloc=0; +--echo Expected error 'Read only variable' + +SELECT @@GLOBAL.innodb_use_sys_malloc; +--echo 1 Expected + + +# Do some stuff to see if it works. +# Also, test the code paths of +# Bug #12699505 MEMORY LEAK IN ROW_CREATE_INDEX_FOR_MYSQL() +# (the leak would only be triggered if +# ha_innobase::max_supported_key_part_length() were set +# higher than the limit used in row_create_index_for_mysql()) + +--error ER_DUP_FIELDNAME +create table t1(a int not null,key(a,a)) engine=innodb DEFAULT CHARSET=latin1; +# thanks to --innodb-large-prefix=1 this will not be truncated to b(767) +-- error ER_INDEX_COLUMN_TOO_LONG +create table t1(a int,b text,key(b(768))) engine=innodb DEFAULT CHARSET=latin1; +create table t1(a int not null,b text) engine=innodb DEFAULT CHARSET=latin1; +insert into t1 values (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,''); +--error ER_DUP_FIELDNAME +create index t1aa on t1(a,a); +-- error ER_INDEX_COLUMN_TOO_LONG +create index t1b on t1(b(768)); +SHOW CREATE TABLE t1; +select * from t1; + +drop table t1; +CREATE TABLE t2(a int primary key, b text) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (1,''),(2,''),(3,''),(4,''),(5,''),(6,''),(7,''); +--error ER_DUP_FIELDNAME +CREATE INDEX t2aa on t2(a,a); +-- error ER_INDEX_COLUMN_TOO_LONG +CREATE INDEX t2b on t2(b(768)); +SELECT * FROM t2; +DROP TABLE t2; diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-debug.test b/mysql-test/suite/innodb/t/innodb-wl5980-debug.test new file mode 100644 index 00000000000..d44e17a8739 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-wl5980-debug.test @@ -0,0 +1,91 @@ +# +# This testcase is to check the various debug injection points +# to make sure error conditions react corectly and acheive +# better code coverage. +# + +# Not supported in embedded +--source include/not_embedded.inc + +# the DBUG_EXECUTE_IF() macro needs a debug server. +--source include/have_debug.inc + +-- source include/have_innodb.inc + +--disable_query_log +# These values can change during the test +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; + +# These messages are expected in the log +call mtr.add_suppression("Cannot find space id [0-9]+ in the tablespace memory cache"); +call mtr.add_suppression("Cannot rename table 'test/t1' to 'test/t2' since the dictionary cache already contains 'test/t2'."); + +# Set up some variables +LET $MYSQL_DATA_DIR = `select @@datadir`; +LET $data_directory_clause = DATA DIRECTORY='$MYSQL_TMP_DIR/alt_dir'; +--enable_query_log + +SET GLOBAL innodb_file_per_table=ON; + +--echo # +--echo # WL5980 Remote tablespace debug error injection tests. +--echo # + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t1 (a int KEY, b text) ENGINE=Innodb $data_directory_clause ; +INSERT INTO t1 VALUES (1, "tablespace"); +SELECT * FROM t1; + + +--echo # +--echo # Test the first injection point in fil_rename_tablespace(). +--echo # Make sure the table is useable after this failure. +--echo # +SET SESSION debug="+d,fil_rename_tablespace_failure_1"; +--disable_result_log +--error ER_ERROR_ON_RENAME +RENAME TABLE t1 TO t2; +--enable_result_log +SET SESSION debug="-d,fil_rename_tablespace_failure_1"; +INSERT INTO t1 VALUES (2, "tablespace"); +SELECT * FROM t1; + +--echo # +--echo # Test the second injection point in fil_rename_tablespace(). +--echo # Make sure the table is useable after this failure. +--echo # +SET SESSION debug="+d,fil_rename_tablespace_failure_2"; +--disable_result_log +--error ER_ERROR_ON_RENAME +RENAME TABLE t1 TO t2; +--enable_result_log +SET SESSION debug="-d,fil_rename_tablespace_failure_2"; +INSERT INTO t1 VALUES (3, "tablespace"); +SELECT * FROM t1; + +--echo # +--echo # Test the injection point in dict_table_rename_in_cache(). +--echo # Make sure the table is useable after this failure. +--echo # +SET SESSION debug="+d,dict_table_rename_in_cache_failure"; +--disable_result_log +--error ER_ERROR_ON_RENAME +RENAME TABLE t1 TO t2; +--enable_result_log +SET SESSION debug="-d,dict_table_rename_in_cache_failure"; +INSERT INTO t1 VALUES (4, "tablespace"); +SELECT * FROM t1; + +--echo # +--echo # Cleanup +--echo # + +DROP TABLE t1; + +--rmdir $MYSQL_TMP_DIR/alt_dir/test +--rmdir $MYSQL_TMP_DIR/alt_dir + +-- disable_query_log +eval set global innodb_file_per_table=$innodb_file_per_table_orig; +-- enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-discard.test b/mysql-test/suite/innodb/t/innodb-wl5980-discard.test new file mode 100644 index 00000000000..c785862a7e3 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-wl5980-discard.test @@ -0,0 +1,750 @@ +--echo # +--echo # This test shows DISCARD/IMPORT of a remote tablespace. +--echo # + +# Not supported in embedded +--source include/not_embedded.inc + +-- source include/have_innodb.inc + +--disable_query_log +# These values can change during the test +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; + +# This warning is expected in the log +call mtr.add_suppression("tablespace is set as discarded"); + +# Set up some variables +LET $MYSQL_DATA_DIR = `select @@datadir`; +LET $data_directory_clause = DATA DIRECTORY='$MYSQL_TMP_DIR/alt_dir'; +--enable_query_log + +SET default_storage_engine=InnoDB; + +SET GLOBAL innodb_file_per_table=ON; + +--disable_warnings +DROP TABLE IF EXISTS t5980; +--enable_warnings + +--echo # +--echo # CREATE TABLE ... DATA DIRECTORY +--echo # combined with WL#5522 - Transportable Tablespace +--echo # Create the tablespace in MYSQL_TMP_DIR/alt_dir +--echo # InnoDB will create the sub-directories if needed. +--echo # Test that DISCARD and IMPORT work correctly. +--echo # + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t5980 (a int KEY, b text) $data_directory_clause; +INSERT INTO t5980 VALUES (1, "Create the tablespace"); +SELECT * FROM t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Check that DATA DIRECTORY shows up in the SHOW CREATE TABLE results. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980; + + +--echo # +--echo # Backup the cfg and ibd files. +--echo # +FLUSH TABLES t5980 FOR EXPORT; +SELECT * FROM t5980; +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak +UNLOCK TABLES; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Do some DDL and DML. +--echo # +INSERT INTO t5980 VALUES (2,'Remote table has been FLUSHed and UNLOCKed'); +START TRANSACTION; +INSERT INTO t5980 VALUES (12,'Transactional record inserted'); +COMMIT; +START TRANSACTION; +INSERT INTO t5980 VALUES (13,'Rollback this transactional record'); +ROLLBACK; +SELECT COUNT(*) FROM t5980; +SELECT * FROM t5980; +ALTER TABLE t5980 DROP PRIMARY KEY; +ALTER TABLE t5980 ADD COLUMN c VARCHAR(50) DEFAULT NULL; +INSERT INTO t5980(a,b,c) VALUES (2,'Duplicate value since primary key has been dropped','third column added'); +SELECT * FROM t5980; + +--echo # +--echo # Make a second backup of the cfg and ibd files. +--echo # +FLUSH TABLES t5980 FOR EXPORT; +SELECT * FROM t5980; +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak2 +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak2 +UNLOCK TABLES; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # DROP the table and make sure all files except the backups are gone. +--echo # +DROP TABLE t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # CREATE the table again. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t5980 (a int KEY, b text) $data_directory_clause; +INSERT INTO t5980 VALUES (1, "Create the tablespace a second time"); +SELECT * FROM t5980; + +--echo # +--echo # DISCARD existing tablespace so backed-up .ibd which can be imported/restored +--echo # +ALTER TABLE t5980 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Restore the second backup of cfg and ibd files. +--echo # +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak2 $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak2 $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd +--echo "### files in MYSQL_TMP_DIR/alt_dir/test" +--list_files $MYSQL_TMP_DIR/alt_dir/test/ + +--echo # +--echo # Try to Import the second backup. These backups have extra DDL and +--echo # do not match the current frm file. +--echo # +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t5980 IMPORT TABLESPACE; +CHECK TABLE t5980; +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Restore the first backup of cfg and ibd files. +--echo # +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Import the tablespace and do some DDL and DML. +--echo # +ALTER TABLE t5980 IMPORT TABLESPACE; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +CHECK TABLE t5980; +SELECT COUNT(*) FROM t5980; +SELECT * FROM t5980; +INSERT INTO t5980 VALUES (2,'Inserted record after IMPORT'); +SELECT * FROM t5980; +START TRANSACTION; +INSERT INTO t5980 VALUES (12,'Transactional record inserted'); +COMMIT; +START TRANSACTION; +INSERT INTO t5980 VALUES (13,'Rollback this transactional record'); +ROLLBACK; +SELECT * FROM t5980; +ALTER TABLE t5980 DROP PRIMARY KEY; +ALTER TABLE t5980 ADD COLUMN c VARCHAR(50) DEFAULT NULL; +INSERT INTO t5980(a,b,c) VALUES (2,'Duplicate value since primary key has been dropped','third column added'); +SELECT * FROM t5980; + +--echo # +--echo # Show that the system tables have this table in them correctly. +--echo # +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo # +--echo # Drop the imported table and show that the system tables are updated. +--echo # +DROP TABLE t5980; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # CREATE the table a third time. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t5980 (a int KEY, b text) $data_directory_clause; +INSERT INTO t5980 VALUES (1, "Create the tablespace a third time"); +SELECT * FROM t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Restart the server +--echo # This test makes sure that you can still execute the FLUSH TABLES command +--echo # after restarting the server and the tablespace can still be found. +--echo # +--source include/restart_mysqld.inc +SET GLOBAL innodb_file_per_table=ON; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +SELECT * FROM t5980; +FLUSH TABLES t5980 FOR EXPORT; +SELECT * FROM t5980; +UNLOCK TABLES; + +--echo # +--echo # Restart the server again. This test makes sure that you can +--echo # still DISCARD a remote table after restarting the server. +--echo # +--source include/restart_mysqld.inc +SET GLOBAL innodb_file_per_table=ON; +SELECT * FROM t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +ALTER TABLE t5980 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Restore the backup of *.ibd and *.cfg files +--echo # +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Import the tablespace and check it out. +--echo # +ALTER TABLE t5980 IMPORT TABLESPACE; +SELECT * FROM t5980; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # DISCARD the tablespace again +--echo # +ALTER TABLE t5980 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Restart the engine while the tablespace is in the discarded state +--echo # +--source include/restart_mysqld.inc +SET GLOBAL innodb_file_per_table=ON; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980; +CHECK TABLE t5980; + +--echo # +--echo # Relocate this discarded file to the default directory +--echo # instead of the remote directory it was discarded from. +--echo # Put cfg and idb files into the default directory. +--echo # Delete the isl file and the remote cfg file. +--echo # Restart the engine again. +--echo # The tablespace is still in the discarded state. +--echo # +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak $MYSQL_DATA_DIR/test/t5980.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak $MYSQL_DATA_DIR/test/t5980.cfg +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo # Restarting ... +--source include/restart_mysqld.inc +SET GLOBAL innodb_file_per_table=ON; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980; +CHECK TABLE t5980; + +--echo # +--echo # Try to import the tablespace. It can only be imported from +--echo # the location it was discarded from. +--echo # The error message for 1810 (IO_READ_ERROR) refers to a local path +--echo # so do not display it. +--echo # +--disable_result_log +--error ER_NO_SUCH_TABLE +ALTER TABLE t5980 IMPORT TABLESPACE; +--enable_result_log +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980; +CHECK TABLE t5980; + +--echo # +--echo # Restore the ibd and cfg files to the remote directory. +--echo # Delete the ibd and cfg files from the default directory. +--echo # The isl file is missing, but is no longer needed since the +--echo # remote location is in the data dictionary. +--echo # Import the tablespace and check it out. +--echo # +--copy_file $MYSQL_DATA_DIR/test/t5980.ibd $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd +--copy_file $MYSQL_DATA_DIR/test/t5980.cfg $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg +--remove_file $MYSQL_DATA_DIR/test/t5980.ibd +--remove_file $MYSQL_DATA_DIR/test/t5980.cfg +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test +ALTER TABLE t5980 IMPORT TABLESPACE; +INSERT INTO t5980 VALUES (2, "Insert this record after IMPORT"); +SELECT * FROM t5980; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980; + +--echo # +--echo # Show that the system tables have this table in them correctly. +--echo # +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +DROP TABLE t5980; +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5980.cfg.bak2 +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5980.ibd.bak2 + +--echo # +--echo # Create a local and remote tablespaces, discard two and make +--echo # the other two missing upon restart, and try some DDL and DML +--echo # on these discarded and missing tablespaces. +--echo # + +SET GLOBAL innodb_file_per_table=ON; +CREATE TABLE t5980a (a int, b text) engine=InnoDB; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t5980b (a int, b text) engine=InnoDB $data_directory_clause; +CREATE TABLE t5980c (a int, b text) engine=InnoDB; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t5980d (a int, b text) engine=InnoDB $data_directory_clause; + +INSERT INTO t5980a VALUES (1, "Default location, discarded."); +INSERT INTO t5980b VALUES (1, "Remote location, discarded"); +INSERT INTO t5980c VALUES (1, "Default location, missing"); +INSERT INTO t5980d VALUES (1, "Remote location, missing"); + +SELECT * FROM t5980a; +SELECT * FROM t5980b; +SELECT * FROM t5980c; +SELECT * FROM t5980d; + +SHOW CREATE TABLE t5980a; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980b; +SHOW CREATE TABLE t5980c; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980d; + +SELECT name,n_cols,file_format,row_format FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Shutdown the server, remove two tablespaces, restart server. +--echo # +--source include/shutdown_mysqld.inc +--remove_file $MYSQL_DATA_DIR/test/t5980c.ibd +--remove_file $MYSQL_DATA_DIR/test/t5980d.isl +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5980d.ibd +--source include/start_mysqld.inc + +FLUSH TABLES t5980a, t5980b FOR EXPORT; +UNLOCK TABLES; + +ALTER TABLE t5980a DISCARD TABLESPACE; +ALTER TABLE t5980b DISCARD TABLESPACE; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980a; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980b; +--error ER_NO_SUCH_TABLE +SELECT * FROM t5980c; +--error ER_NO_SUCH_TABLE +SELECT * FROM t5980d; + +SHOW CREATE TABLE t5980a; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980b; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t5980c; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t5980d; + +SELECT name,n_cols,file_format,row_format FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Discarded and missing tablespaces cannot be TRUNCATED +--echo # + +--error ER_TABLESPACE_DISCARDED +TRUNCATE TABLE t5980a; +--error ER_TABLESPACE_DISCARDED +TRUNCATE TABLE t5980b; +--error ER_NO_SUCH_TABLE +TRUNCATE TABLE t5980c; +--error ER_NO_SUCH_TABLE +TRUNCATE TABLE t5980d; + +--echo # +--echo # Discarded tablespaces can be RENAMED but they remain discarded +--echo # + +RENAME TABLE t5980a TO t5980aa; +RENAME TABLE t5980b TO t5980bb; + +--echo # +--echo # Missing tablespaces cannot be RENAMED +--echo # + +--error ER_ERROR_ON_RENAME +RENAME TABLE t5980c TO t5980cc; +--error ER_ERROR_ON_RENAME +RENAME TABLE t5980d TO t5980dd; + +--error ER_NO_SUCH_TABLE +SELECT * FROM t5980a; +--error ER_NO_SUCH_TABLE +SELECT * FROM t5980b; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980aa; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980bb; +--error ER_NO_SUCH_TABLE +SELECT * FROM t5980c; +--error ER_NO_SUCH_TABLE +SELECT * FROM t5980d; + +SHOW CREATE TABLE t5980aa; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980bb; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t5980c; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t5980d; + +SELECT name,n_cols,file_format,row_format FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo # +--echo # Discarded tablespaces cannot be ALTERED with ALGORITHM=COPY. +--echo # + +--error ER_TABLESPACE_DISCARDED +ALTER TABLE t5980aa ADD PRIMARY KEY(a), ALGORITHM=COPY; +--error ER_TABLESPACE_DISCARDED +ALTER TABLE t5980bb ADD PRIMARY KEY(a), ALGORITHM=COPY; + +--echo # +--echo # Discarded tablespaces can be ALTERED with ALGORITHM=INPLACE. +--echo # + +# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on. +# And adding a PRIMARY KEY will also add NOT NULL implicitly! +SET @old_sql_mode = @@sql_mode; +SET @@sql_mode = 'STRICT_TRANS_TABLES'; +ALTER TABLE t5980aa ADD PRIMARY KEY(a), ALGORITHM=INPLACE; +ALTER TABLE t5980bb ADD PRIMARY KEY(a), ALGORITHM=INPLACE; +SET @@sql_mode = @old_sql_mode; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Missing tablespaces cannot be ALTERED. +--echo # + +--error ER_NO_SUCH_TABLE +ALTER TABLE t5980c ADD PRIMARY KEY(a); +--error ER_NO_SUCH_TABLE +ALTER TABLE t5980d ADD PRIMARY KEY(a); + +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980aa; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980bb; + +SHOW CREATE TABLE t5980aa; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980bb; + +SELECT name,n_cols,file_format,row_format FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Restart the server to check if the discarded flag is persistent +--echo # +--source include/shutdown_mysqld.inc +--source include/start_mysqld.inc + +--echo # +--echo # Discarded tablespaces that were ALTERED IN_PLACE are still discarded. +--echo # + +--error ER_TABLESPACE_DISCARDED +INSERT INTO t5980aa VALUES (1, "Inserted into Discarded Local tablespace after ALTER ADD PRIMARY KEY, ALGORITHM=INPLACE"); +--error ER_TABLESPACE_DISCARDED +INSERT INTO t5980bb VALUES (1, "Inserted into Discarded Local tablespace after ALTER ADD PRIMARY KEY, ALGORITHM=INPLACE"); + +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980aa; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980bb; + +RENAME TABLE t5980aa TO t5980a; +RENAME TABLE t5980bb TO t5980b; + +SHOW CREATE TABLE t5980a; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5980b; + +SELECT name,n_cols,file_format,row_format FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Discard tablespaces again and try another ALTER TABLE ROW_FORMAT. +--echo # + +ALTER TABLE t5980a DISCARD TABLESPACE; +ALTER TABLE t5980b DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980a; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980b; + +--echo # +--echo # ALTER TABLE ALGORITHM=COPY cannot use a discarded tablespace. +--echo # + +--error ER_TABLESPACE_DISCARDED +ALTER TABLE t5980a ROW_FORMAT=REDUNDANT, ALGORITHM=COPY; +--error ER_TABLESPACE_DISCARDED +ALTER TABLE t5980b ROW_FORMAT=REDUNDANT, ALGORITHM=COPY; + +--echo # +--echo # ALTER TABLE ALGORITHM=INPLACE can use a discarded tablespace. +--echo # + +ALTER TABLE t5980a ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; +ALTER TABLE t5980b ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; + +--echo # +--echo # Discarded tablespaces that were ALTERED IN_PLACE are still discarded. +--echo # + +--error ER_TABLESPACE_DISCARDED +INSERT INTO t5980a VALUES (1, "Inserted into discarded local tablespace after ALTER ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE"); +--error ER_TABLESPACE_DISCARDED +INSERT INTO t5980b VALUES (1, "Inserted into discarded local tablespace after ALTER ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE"); +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980a; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980b; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Discard tablespaces again and try ALTER TABLE ADD COLUMN. +--echo # + +ALTER TABLE t5980a DISCARD TABLESPACE; +ALTER TABLE t5980b DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980a; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980b; + +--echo # +--echo # ALTER TABLE ALGORITHM=COPY cannot use a discarded tablespace. +--echo # + +--error ER_TABLESPACE_DISCARDED +ALTER TABLE t5980a ADD COLUMN c CHAR(20), ALGORITHM=COPY; +--error ER_TABLESPACE_DISCARDED +ALTER TABLE t5980b ADD COLUMN c CHAR(20), ALGORITHM=COPY; + +--echo # +--echo # ALTER TABLE ALGORITHM=INPLACE can use a discarded tablespace. +--echo # + +ALTER TABLE t5980a ADD COLUMN c CHAR(20), ALGORITHM=INPLACE; +ALTER TABLE t5980b ADD COLUMN c CHAR(20), ALGORITHM=INPLACE; + +--echo # +--echo # Discarded tablespaces that were ALTERED IN_PLACE are still discarded. +--echo # + +--error ER_TABLESPACE_DISCARDED +DELETE FROM t5980a; +--error ER_TABLESPACE_DISCARDED +UPDATE t5980a SET c="Tablespace is DISCARDED"; +--error ER_TABLESPACE_DISCARDED +INSERT INTO t5980a VALUES (1, "Inserted into discarded local tablespace after ALTER ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE", "new column"); +--error ER_TABLESPACE_DISCARDED +INSERT INTO t5980b VALUES (1, "Inserted into discarded local tablespace after ALTER ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE", "new column"); +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980a; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t5980b; +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +DROP TABLE t5980a; +DROP TABLE t5980b; +DROP TABLE t5980c; +DROP TABLE t5980d; + +SELECT name,n_cols,file_format,row_format FROM information_schema.innodb_sys_tables + WHERE name LIKE 'test%' ORDER BY name; +SELECT name,file_format,row_format FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY space; +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo ### files in MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### files in MYSQL_TMP_DIR/alt_dir/test +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Cleanup +--echo # + +--rmdir $MYSQL_TMP_DIR/alt_dir/test +--rmdir $MYSQL_TMP_DIR/alt_dir + +-- disable_query_log +eval set global innodb_file_per_table=$innodb_file_per_table_orig; +call mtr.add_suppression("InnoDB: Could not find a valid tablespace file for"); +call mtr.add_suppression("InnoDB: Tablespace open failed for"); +call mtr.add_suppression("InnoDB: Failed to find tablespace for table "); +call mtr.add_suppression("InnoDB: Table test/t5980.* does not have an .ibd file in the database directory."); +call mtr.add_suppression("Trying to import a tablespace, but could not open the tablespace file"); +call mtr.add_suppression("Cannot delete tablespace .+ because it is not found in the tablespace memory cache"); +call mtr.add_suppression("Cannot delete tablespace .+ in DISCARD TABLESPACE. Tablespace not found"); +call mtr.add_suppression("doesn't have a corresponding tablespace, it was discarded."); +-- enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-linux.test b/mysql-test/suite/innodb/t/innodb-wl5980-linux.test new file mode 100644 index 00000000000..fbe6ddf6b21 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-wl5980-linux.test @@ -0,0 +1,191 @@ +# +# This testcase is related to WL5980, to test the portability feature. +# Create a DB & tables with all kinds Non-Partition & partition on +# Windows platform. Zip the entire DB and tablespaces on Windows. +# Bring the zip file to Linux. Unzip the DB and modify the *.isl files +# with the proper path of the *.ibd files. Restart the DB & check the +# DB with a few DML operations. Test and validate the Windows DB on +# Linux platform. +# Prerequisite : portability_wl5980_linux.zip +# should exist in "suite/innodb/t" + +--source include/have_innodb_16k.inc +--source include/not_embedded.inc + +--echo # Skip this test other platfoms and run only on Linux. +if (`select convert(@@version_compile_os using latin1) IN ("Linux") = 0`) +{ + skip Need Linux; +} + +--echo # Set the environmental variables +let MYSQL_BASEDIR= `select @@basedir`; + +--echo # Stop server +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 30 +-- source include/wait_until_disconnected.inc + +--echo # Copy the remote tablespace & DB zip files from suite location to working location. +#--copy_file $MYSQLTEST_VARDIR/../mysql-test/suite/innodb/t/portability_wl5980_linux.zip $MYSQL_TMP_DIR/portability_wl5980_linux.zip + +perl; +use File::Find; +use File::Copy; +sub find_zip () { + if (/portability_wl5980_linux\.zip/) { + my $dest_dir = $ENV{'MYSQL_TMP_DIR'}; + my $src_file = $File::Find::name; + my $srcfile = File::Spec->catfile("$src_file") ; + my $destfile = File::Spec->catfile("$dest_dir", "portability_wl5980_linux.zip"); + if (! -e $destfile) { + copy($srcfile,$destfile) or die "copy @args failed: $!"; + } + } +} +my $search_dir = $ENV{'MYSQL_BASEDIR'}; +find(\&find_zip,"$search_dir"); +EOF + +--echo # Check that the file exists in the working folder. +--file_exists $MYSQL_TMP_DIR/portability_wl5980_linux.zip + +--echo # Unzip the zip file. +--exec unzip -qo $MYSQL_TMP_DIR/portability_wl5980_linux.zip -d $MYSQL_TMP_DIR + +--echo # Remove the DOS based *.isl files from the MySql Data directory. +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p1.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p2.isl + +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp3.isl + +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p1.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p2.isl + +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s0.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s1.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s2.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s3.isl + +--echo # Check that the *.ibd files are in the required location. +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab1/test/emp2#p#p1.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab2/test/emp2#p#p2.ibd + +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab3/test/emp3.ibd + +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab4/test/emp4#p#p1.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab5/test/emp4#p#p2.ibd + +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part0/test/purchase#p#p0#sp#s0.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part1/test/purchase#p#p0#sp#s1.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part2/test/purchase#p#p1#sp#s2.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part3/test/purchase#p#p1#sp#s3.ibd + + +--echo # Create new *.isl files with the correct path to the *.ibd files, +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab1/test/emp2#p#p1.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p1.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab2/test/emp2#p#p2.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p2.isl + +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab3/test/emp3.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp3.isl + +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab4/test/emp4#p#p1.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p1.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab5/test/emp4#p#p2.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p2.isl + +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part0/test/purchase#p#p0#sp#s0.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s0.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part1/test/purchase#p#p0#sp#s1.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s1.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part2/test/purchase#p#p1#sp#s2.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s2.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part3/test/purchase#p#p1#sp#s3.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s3.isl + +--echo # Restart the DB server from unzip location Data Dir. +--echo # Note that lower case option is required because the +--echo # partition tables will be stored in mixed (Upper & Lower) format on Linux, +--echo # but on Windows the partition table names are stored in lower case only. + +-- exec echo "restart:--lower_case_table_names=1 --datadir=$MYSQL_TMP_DIR/mysqld.5980/data/ " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc + +--echo # Check the DB & tables with DML statements. +use test; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp1; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp2; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp3; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp4; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE purchase; + +SELECT COUNT(*) FROM emp1; +SELECT COUNT(*) FROM emp2; +SELECT COUNT(*) FROM emp3; +SELECT COUNT(*) FROM emp4; +SELECT COUNT(*) FROM purchase; + +DELETE FROM emp1; +DELETE FROM emp2; +DELETE FROM emp3; +DELETE FROM emp4; +DELETE FROM purchase; + +SELECT COUNT(*) FROM emp1; +SELECT COUNT(*) FROM emp2; +SELECT COUNT(*) FROM emp3; +SELECT COUNT(*) FROM emp4; +SELECT COUNT(*) FROM purchase; + +--echo # Check the system tables have the proper entry of the tables. +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE '%emp%' ORDER BY name; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE '%purchase%' ORDER BY name; + +--echo # +--echo # Cleanup +--echo # + +DROP TABLE emp1; +DROP TABLE emp2; +DROP TABLE emp3; +DROP TABLE emp4; +DROP TABLE purchase; + +# The following lines of code just to dupe the MTR frame work nothing to do with WL, +# As MTR thinks that it was a failure, When the server logs contains error/warnings +# even though there are no result mismatch.It is an expected behavior of the server. + +CREATE DATABASE mtr; +DELIMITER |; +CREATE PROCEDURE mtr.check_warnings(OUT result INT) +BEGIN +SELECT 0 INTO RESULT; +END| + +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab1/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab2/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab3/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab4/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab5/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part0/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part1/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part2/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part3/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab1 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab2 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab3 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab4 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab5 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part0 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part1 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part2 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part3 diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-windows.test b/mysql-test/suite/innodb/t/innodb-wl5980-windows.test new file mode 100644 index 00000000000..2cc140c8d44 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-wl5980-windows.test @@ -0,0 +1,237 @@ +# +# This testcase is related to WL5980, to test the portability feature. +# Create a DB & tables with all kinds Non-Partition & partition on +# Linux platform. Zip the entire DB and tablespaces on Windows. +# Bring the zip file to Windows. Unzip the DB and modify the *.isl files +# with the proper path of the *.ibd files. Restart the DB & check the +# DB with a few DML operations. Test and validate the Linux DB on +# Windows platform. +# Prerequisite : portability_wl5980_windows.zip +# should exist in "suite/innodb/t" + +# Windows-specific tests +--source include/windows.inc +--source include/have_innodb_16k.inc +--source include/not_embedded.inc + +--echo #Check whether unzip is installed on the system +--echo #Store the command output into a temp file. +perl; + my $dir = $ENV{'MYSQLTEST_VARDIR'}; + my $cmd = system('unzip --help > NUL 2>&1'); + open ( OUTPUT, ">$dir/tmp/tar.inc") ; + print OUTPUT "let \$stat = $cmd;\n"; + close (OUTPUT); +EOF + +--echo #Get the value of the $stat variable from perl, to MTR +--source $MYSQLTEST_VARDIR/tmp/tar.inc + +--echo #Check the status is non-zero +if ($stat != 0) +{ + --skip Test requires Unzip on Windows +} + +--echo #Remove the temp file tar.inc +--remove_file $MYSQLTEST_VARDIR/tmp/tar.inc + +--echo # Set the environmental variables +let $MYSQL_BASEDIR= `select @@basedir`; + +--echo # Stop server +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 30 +-- source include/wait_until_disconnected.inc + +--echo # Copy the remote tablespace & DB zip files from suite location to working location. +--copy_file $MYSQL_BASEDIR/mysql-test/suite/innodb/t/portability_wl5980_windows.zip $MYSQL_TMP_DIR/portability_wl5980_windows.zip + +--echo # Check that the file exists in the working folder. +--file_exists $MYSQL_TMP_DIR/portability_wl5980_windows.zip + +--echo # Unzip the zip file. +--exec unzip -q $MYSQL_TMP_DIR/portability_wl5980_windows.zip -d $MYSQL_TMP_DIR + +--echo # Remove the DOS based *.isl files from the MySql Data directory. +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p1.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p2.isl + +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp3.isl + +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p1.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p2.isl + +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s0.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s1.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s2.isl +--remove_file $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s3.isl + +--echo # Check that the *.ibd files are in the required location. +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab1/test/emp2#p#p1.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab2/test/emp2#p#p2.ibd + +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab3/test/emp3.ibd + +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab4/test/emp4#p#p1.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/tab5/test/emp4#p#p2.ibd + +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part0/test/purchase#p#p0#sp#s0.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part1/test/purchase#p#p0#sp#s1.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part2/test/purchase#p#p1#sp#s2.ibd +--file_exists $MYSQL_TMP_DIR/mysqld.5980/part3/test/purchase#p#p1#sp#s3.ibd + + +--echo # Create new *.isl files with the correct path to the *.ibd files, +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab1/test/emp2#p#p1.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p1.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab2/test/emp2#p#p2.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp2#p#p2.isl + +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab3/test/emp3.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp3.isl + +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab4/test/emp4#p#p1.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p1.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/tab5/test/emp4#p#p2.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/emp4#p#p2.isl + +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part0/test/purchase#p#p0#sp#s0.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s0.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part1/test/purchase#p#p0#sp#s1.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p0#sp#s1.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part2/test/purchase#p#p1#sp#s2.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s2.isl +--exec echo $MYSQL_TMP_DIR/mysqld.5980/part3/test/purchase#p#p1#sp#s3.ibd > $MYSQL_TMP_DIR/mysqld.5980/data/test/purchase#p#p1#sp#s3.isl + +--exec echo #change path separator Linux "/" format to windows "\" format by Perl script, +--exec echo #in the *.ISL files , in the Mysql data directory +--perl EOF +use File::Copy; +#use strict; +#use warnings; +my $dir= $ENV{'MYSQL_TMP_DIR'}."/mysqld.5980/data/test"; +opendir(DIR, $dir) or die $!; + while (my $file = readdir(DIR)) { + # Read files only in the Directory + next unless (-f "$dir/$file"); + # Use a regular expression to find files ending in .isl + next unless ($file =~ m/\.isl$/); + # open file in write mode + open IN_FILE,"<", "$dir/$file" or die $!; + open OUT_FILE, ">", "$dir/tmp" or die $!; + while(<IN_FILE>) { + #change the path separator "/" to "\" in the file + $_=~ s/"$//g; + $_=~ s/\//\\/g; + print OUT_FILE $_; + } + + close(IN_FILE); + close(OUT_FILE); + #move the new content from tmp file to the orginal file. + move("$dir/tmp", "$dir/$file"); + print "$file\n"; + } +closedir(DIR); + +exit 0; +EOF + +--echo # Restarting the server with skip-grant-tables option and updating +--echo # mysql.user table. This is to deal with the restriction imposed on +--echo # plugin field for users in WL6982. + +--echo # Restart the DB server from unzip location of MySQL Data Dir +-- exec echo "restart: --datadir=$MYSQL_TMP_DIR/mysqld.5980/data/ --skip-grant-tables" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc + +-- exec $MYSQL -e "UPDATE mysql.user SET plugin = 'mysql_native_password'" + +-- echo # Stop server +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 30 +-- source include/wait_until_disconnected.inc + +--echo # Restart the DB server from unzip location of MySQL Data Dir +-- exec echo "restart: --datadir=$MYSQL_TMP_DIR/mysqld.5980/data/ " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc + +--echo # Check the DB & tables with DML statements. +use test; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp1; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp2; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp3; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE emp4; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE purchase; + +SELECT COUNT(*) FROM emp1; +SELECT COUNT(*) FROM emp2; +SELECT COUNT(*) FROM emp3; +SELECT COUNT(*) FROM emp4; +SELECT COUNT(*) FROM purchase; + +DELETE FROM emp1; +DELETE FROM emp2; +DELETE FROM emp3; +DELETE FROM emp4; +DELETE FROM purchase; + +SELECT COUNT(*) FROM emp1; +SELECT COUNT(*) FROM emp2; +SELECT COUNT(*) FROM emp3; +SELECT COUNT(*) FROM emp4; +SELECT COUNT(*) FROM purchase; + +--echo # Check the system tables have the proper entry of the tables. +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + ORDER BY name; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE '%emp%' ORDER BY name; +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name LIKE '%purchase%' ORDER BY name; + +--echo # +--echo # Cleanup +--echo # + +DROP TABLE emp1; +DROP TABLE emp2; +DROP TABLE emp3; +DROP TABLE emp4; +DROP TABLE purchase; + +# The following lines of code just to dupe the MTR frame work nothing to do with WL, +# As MTR thinks that it was a failure, When the server logs contains error/warnings +# even though there are no result mismatch.It is an expected behavior of the server. + +CREATE DATABASE mtr; +DELIMITER |; +CREATE PROCEDURE mtr.check_warnings(OUT result INT) +BEGIN +SELECT 0 INTO RESULT; +END| + +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab1/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab2/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab3/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab4/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab5/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part0/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part1/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part2/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part3/test +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab1 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab2 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab3 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab4 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/tab5 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part0 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part1 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part2 +--rmdir $MYSQL_TMP_DIR/mysqld.5980/part3 diff --git a/mysql-test/suite/innodb/t/innodb-wl6445-1.test b/mysql-test/suite/innodb/t/innodb-wl6445-1.test new file mode 100644 index 00000000000..5fd75a98022 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-wl6445-1.test @@ -0,0 +1,758 @@ +######## suite/innodb/t/innodb-wl6445-1 ########## +# # +# Testcase for worklog WL#6445: InnoDB should be able to work with # +# read-only tables +# All sub-test in this file focus on restarting server in read only # +# and verify necessary operations blocked # +# operations # +# # +# # +# Creation: # +# 2011-09-06 Implemented this test as part of WL#6445 # +# # +###################################################################### + +# Don't test this under valgrind, memory leaks will occur due restart +--source include/not_valgrind.inc +# Not supported in embedded +--source include/not_embedded.inc + +-- source include/have_innodb.inc + + +let MYSQLD_DATADIR =`SELECT @@datadir`; +let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; +let $innodb_file_format = `SELECT @@innodb_file_format`; +let $innodb_large_prefix_orig = `select @@innodb_large_prefix`; +let $innodb_flush_log_at_trx_commit_orig =`select @@innodb_flush_log_at_trx_commit`; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +SET GLOBAL innodb_file_format = `Barracuda`; +SELECT @@innodb_file_format; + +set global innodb_large_prefix=1; +SELECT @@innodb_large_prefix; + +let $MYSQLD_DATADIR = `SELECT @@datadir`; +let $data_index_directory = DATA DIRECTORY='$MYSQL_TMP_DIR/alt_dir'; + +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; + + +#------------------------------------------------------------------------------ +# Testcase 1 covers +# a) Create table/data , restart server in readonly mode +# b) verfiy DDL/DML/DCL in read only mode +# c) statements blocked for non root and root user from differet sessions. +#------------------------------------------------------------------------------ +--echo case # 1 +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY , j blob) ENGINE = InnoDB; + +INSERT INTO t1 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +# Create user with minimun access +CREATE USER 'test1'@'localhost' IDENTIFIED BY '123'; +GRANT ALL ON testdb_wl6445.* TO 'test1'@'localhost'; +# Create user with root access +CREATE USER 'test2'@'localhost' IDENTIFIED BY '123'; +GRANT ALL ON *.* TO 'test2'@'localhost'; + +# check when datadir and index dir are specified +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +EVAL CREATE TABLE otherlocation (id int PRIMARY KEY) +ENGINE=InnoDB , $data_index_directory; +INSERT INTO otherlocation VALUES (1),(2),(3); +SELECT * FROM otherlocation ORDER BY id; + +#SHOW ENGINE INNODB STATUS; + +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +SET GLOBAL innodb_file_per_table = 1; +SET GLOBAL innodb_file_format = `Barracuda`; + +# Nothing to do with wl64645.non-InnoDB issue. But need to document in QA note. +CREATE USER 'test3'@'localhost' IDENTIFIED BY '123'; +GRANT ALL ON testdb_wl6445.* TO 'test3'@'localhost'; + +USE testdb_wl6445; +SELECT i FROM t1 ORDER BY i; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +--echo # connection con_test1_user try to modify +--connect (con_test1_user,'localhost','test1','123',) +SELECT user(); +USE testdb_wl6445; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +--ERROR ER_INNODB_READ_ONLY +CREATE TABLE t2 ( i int ,j blob) ENGINE = Innodb; +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i+1; + +--echo # disconnect con_test1_user +--disconnect con_test1_user + + +--echo # connection con_test2_user +--connect (con_test2_user,'localhost','test2','123',) +SELECT user(); +USE testdb_wl6445; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +--ERROR ER_INNODB_READ_ONLY +CREATE TABLE t2 ( i int , j blob) ENGINE = Innodb; +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i+1; +# Fix in next revision - known ( no data returned) +#SHOW ENGINE INNODB STATUS; +FLUSH STATUS; +FLUSH LOGS; +FLUSH TABLES t1; +FLUSH TABLES WITH READ LOCK; +UNLOCK TABLES; + + +--echo # disconnect con_test2_user +--disconnect con_test2_user + + +--echo # connection default +--connection default +USE testdb_wl6445; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +--ERROR ER_INNODB_READ_ONLY +CREATE TABLE t2 ( i int , j blob) ENGINE = Innodb; +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i+1; + +# check with table having data and index directory specified +--ERROR ER_CANT_LOCK +INSERT INTO otherlocation VALUES (1),(2),(3); +SELECT * FROM otherlocation ORDER BY id; + +# Fix in next revision - known ( no data returned) +# SHOW ENGINE INNODB STATUS; +FLUSH STATUS; +FLUSH LOGS; +FLUSH TABLES t1; +FLUSH TABLES WITH READ LOCK; +UNLOCK TABLES; + + +#------------------------------------------------------------------------------ +#clenaup +#------------------------------------------------------------------------------ +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +DROP USER 'test1'@'localhost'; +DROP USER 'test2'@'localhost'; +DROP USER 'test3'@'localhost'; +DROP TABLE otherlocation; +DROP DATABASE testdb_wl6445; + + +#------------------------------------------------------------------------------ +# Testcase 2 covers +# a) Create table/data , perform transaction , restart server in readonly mode +# b) verfiy DDL/DML/DCL in read only mode +#------------------------------------------------------------------------------ +--echo case # 2 +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; + +SET GLOBAL innodb_file_per_table = 1; +SET GLOBAL innodb_file_format = `Barracuda`; +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY , j blob) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,repeat('a',4000)),(2,repeat('b',4000)),(3,repeat('c',4000)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + + +START TRANSACTION; +let $counter= 50; +--disable_query_log +while ($counter>3) { + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --dec $counter +} +--enable_query_log +SAVEPOINT A; +let $counter= 100; +--disable_query_log +while ($counter>50) { + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --dec $counter +} +--enable_query_log +SAVEPOINT B; +ROLLBACK TO A; +--echo "---commit first 50 records " +COMMIT; + + +SELECT COUNT(*) FROM testdb_wl6445.t1; +#SHOW ENGINE INNODB STATUS; + +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +USE testdb_wl6445; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (211,repeat('a',200)),(212,repeat('b',200)),(213,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 WHERE i%10=0 ORDER BY i; +--ERROR ER_INNODB_READ_ONLY +CREATE TABLE t2 ( i int , j blob) ENGINE = Innodb; +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i+1; + +SELECT i,LEFT(j,20) FROM t1 WHERE i%10=0 ORDER BY i; + +# Check with transaction in read-only mode with innodb_flush_log_at_trx_commit=0 +START TRANSACTION; +SET GLOBAL innodb_flush_log_at_trx_commit = 0; +let $counter= 200; +--disable_query_log +while ($counter>150) { + --ERROR ER_CANT_LOCK + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --ERROR ER_CANT_LOCK + UPDATE testdb_wl6445.t1 SET i = i + 1; + --ERROR ER_CANT_LOCK + DELETE FROM testdb_wl6445.t1; + --dec $counter +} +--enable_query_log +SAVEPOINT A; +let $counter= 250; +--disable_query_log +while ($counter>200) { + --ERROR ER_CANT_LOCK + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --ERROR ER_CANT_LOCK + UPDATE testdb_wl6445.t1 SET i = i + 1; + --ERROR ER_CANT_LOCK + DELETE FROM testdb_wl6445.t1; + --dec $counter +} +--enable_query_log +SAVEPOINT B; +ROLLBACK TO A; +--echo "---commit first 50 records with innodb_flush_log_at_trx_commit = 0 --" +COMMIT; + +SELECT i,LEFT(j,20) FROM t1 WHERE i%10=0 ORDER BY i; + +# Check with transaction in read-only mode with innodb_flush_log_at_trx_commit=1 +START TRANSACTION; +SET GLOBAL innodb_flush_log_at_trx_commit = 1; +let $counter= 200; +--disable_query_log +while ($counter>150) { + --ERROR ER_CANT_LOCK + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --ERROR ER_CANT_LOCK + UPDATE testdb_wl6445.t1 SET i = i + 1; + --ERROR ER_CANT_LOCK + DELETE FROM testdb_wl6445.t1; + --dec $counter +} +--enable_query_log +SAVEPOINT A; +let $counter= 250; +--disable_query_log +while ($counter>200) { + --ERROR ER_CANT_LOCK + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --ERROR ER_CANT_LOCK + UPDATE testdb_wl6445.t1 SET i = i + 1; + --ERROR ER_CANT_LOCK + DELETE FROM testdb_wl6445.t1; + --dec $counter +} +--enable_query_log +SAVEPOINT B; +ROLLBACK TO A; +--echo "---commit first 50 records with innodb_flush_log_at_trx_commit = 1 --" +COMMIT; + +SELECT i,LEFT(j,20) FROM t1 WHERE i%10=0 ORDER BY i; + +# Check with transaction in read-only mode with innodb_flush_log_at_trx_commit=2 +START TRANSACTION; +SET GLOBAL innodb_flush_log_at_trx_commit = 2; +let $counter= 200; +--disable_query_log +while ($counter>150) { + --ERROR ER_CANT_LOCK + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --ERROR ER_CANT_LOCK + UPDATE testdb_wl6445.t1 SET i = i + 1; + --ERROR ER_CANT_LOCK + DELETE FROM testdb_wl6445.t1; + --dec $counter +} +--enable_query_log +SAVEPOINT A; +let $counter= 250; +--disable_query_log +while ($counter>200) { + --ERROR ER_CANT_LOCK + EVAL INSERT INTO testdb_wl6445.t1 VALUES ($counter,repeat(CONCAT('a',$counter),2000)); + --ERROR ER_CANT_LOCK + UPDATE testdb_wl6445.t1 SET i = i + 1; + --ERROR ER_CANT_LOCK + DELETE FROM testdb_wl6445.t1; + --dec $counter +} +--enable_query_log +SAVEPOINT B; +ROLLBACK TO A; +--echo "---commit first 50 records with innodb_flush_log_at_trx_commit = 2 --" +COMMIT; + + +# Fix in next revision - known ( no data returned) +# SHOW ENGINE INNODB STATUS; +FLUSH STATUS; +FLUSH LOGS; +FLUSH TABLES t1; +FLUSH TABLES WITH READ LOCK; +UNLOCK TABLES; + +#------------------------------------------------------------------------------ +#clenaup +#------------------------------------------------------------------------------ +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +DROP DATABASE testdb_wl6445; + + + +#------------------------------------------------------------------------------ +# Testcase 3 covers +# a) Create table/data with trigger & procedure, partitioned table +# b) restart server in readonly mode +# c) verfiy behavior with trigger,procedure,partitioned and temp table +#------------------------------------------------------------------------------ +--echo case # 3 +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY , j blob) ENGINE = InnoDB; +CREATE TABLE t2 ( t2_i int PRIMARY KEY , t2_j blob) ENGINE = InnoDB; +CREATE TABLE t3 ( i int PRIMARY KEY , j VARCHAR(20)) ENGINE = InnoDB; + +# create partitioned table +CREATE TABLE t4 (val INT) +PARTITION BY LIST(val)( + PARTITION mypart_odd VALUES IN (1,3,5), + PARTITION MyPart_even VALUES IN (2,4,6)); +INSERT INTO testdb_wl6445.t4 VALUES (1),(2),(3),(4),(5),(6); +SELECT * FROM testdb_wl6445.t4 ORDER BY val; + +DELIMITER //; +CREATE TRIGGER TRIGGER_1 BEFORE INSERT ON testdb_wl6445.t1 FOR EACH ROW BEGIN +INSERT INTO testdb_wl6445.t2 SET t2_i = NEW.i , t2_j = NEW.j; +END;// +CREATE PROCEDURE proc1 (OUT param1 INT) +BEGIN +SELECT COUNT(*) INTO param1 FROM testdb_wl6445.t1; +END;// +CREATE PROCEDURE proc2 (IN param1 INT,IN param2 VARCHAR(20)) +BEGIN +INSERT INTO testdb_wl6445.t3 VALUES (param1,param2); +END;// +DELIMITER ;// + +INSERT INTO t1 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +SELECT t2_i,LEFT(t2_j,20) FROM t2 ORDER BY t2_i; +CALL proc1(@a); +SELECT @a; +CALL proc2(1,'test1'); +SELECT * FROM t3; + +#SHOW ENGINE INNODB STATUS; + +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +SET GLOBAL innodb_file_per_table = 1; +SET GLOBAL innodb_file_format = `Barracuda`; +USE testdb_wl6445; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +SELECT t2_i,LEFT(t2_j,20) FROM t2 ORDER BY t2_i; +CALL proc1(@a); +SELECT @a; +--ERROR ER_CANT_LOCK +CALL proc2(2,'test2'); +SELECT * FROM t3; + +# try to CREATE temp table +--ERROR ER_INNODB_READ_ONLY +CREATE TEMPORARY TABLE temp_1 ( i INT ) ENGINE = Innodb; + +# Try to insert with partitioned table +--ERROR ER_CANT_LOCK +INSERT INTO testdb_wl6445.t4 VALUES (1),(2),(3),(4),(5),(6); +SELECT * FROM testdb_wl6445.t4 ORDER BY val; + +FLUSH STATUS; +FLUSH LOGS; +FLUSH TABLES t1,t2,t3; +FLUSH TABLES WITH READ LOCK; +UNLOCK TABLES; + + +#------------------------------------------------------------------------------ +#clenaup +#------------------------------------------------------------------------------ +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +DROP DATABASE testdb_wl6445; + + +#------------------------------------------------------------------------------ +# Testcase 4 covers +# a) Create table/data restart server in readonly mode +# b) check the effect of server variables impacting change of RO +# ( they will be ignored) +#------------------------------------------------------------------------------ +--echo case # 4 +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY , j VARCHAR(300), FULLTEXT KEY (j)) ENGINE = InnoDB; +CREATE INDEX idx1 ON testdb_wl6445.t1(i); +INSERT INTO t1 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +INSERT INTO t1 VALUES (4,'mysql database'),(5,'mysql database innodb support'),(6,'innodb engine'); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +#FTS Query +SELECT * FROM t1 WHERE MATCH (j) AGAINST ('mysql (+database -innodb)' IN BOOLEAN MODE) ; + +# store initial values +let $innodb_max_purge_lag_orig = `SELECT @@innodb_max_purge_lag`; +let $innodb_max_purge_lag_delay_orig = `SELECT @@innodb_max_purge_lag_delay`; +let $innodb_purge_batch_size_orig = `select @@innodb_purge_batch_size`; +let $innodb_purge_threads_orig = `SELECT @@innodb_purge_threads`; +let $relay_log_purge_orig = `select @@relay_log_purge`; +let $innodb_buffer_pool_size_orig = `select @@innodb_buffer_pool_size`; +let $innodb_change_buffer_max_size_orig = `select @@innodb_change_buffer_max_size`; +let $innodb_change_buffering_orig = `select @@innodb_change_buffering`; +let $innodb_print_all_deadlocks_orig = `select @@innodb_print_all_deadlocks`; + + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only --innodb_purge_threads=5 --innodb_buffer_pool_size=16M" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + + +SET GLOBAL innodb_max_purge_lag = 10; +SET GLOBAL innodb_max_purge_lag_delay = 10; +SET GLOBAL innodb_purge_batch_size = 600; +# purge thread is read only variable +#SET GLOBAL innodb_purge_threads = 5; +SET GLOBAL relay_log_purge = 0; +SET GLOBAL innodb_change_buffer_max_size = 30; +SET GLOBAL innodb_change_buffering = 'changes'; +SET GLOBAL innodb_print_all_deadlocks = 'ON'; + + +USE testdb_wl6445; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i + 1; +--ERROR ER_CANT_LOCK +DELETE FROM t1 ; + + +SELECT @@innodb_max_purge_lag,@@innodb_max_purge_lag_delay,@@innodb_purge_batch_size, +@@innodb_purge_threads,@@relay_log_purge,@@innodb_buffer_pool_size, +@@innodb_change_buffer_max_size,@@innodb_change_buffering,@@innodb_print_all_deadlocks; + +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +#FTS Query +SELECT * FROM t1 WHERE MATCH (j) AGAINST ('mysql (+database -innodb)' IN BOOLEAN MODE) ; +SELECT * FROM t1 WHERE MATCH (j) AGAINST ('innodb') ; + +# restore initial values +--disable_query_log +eval SET GLOBAL innodb_max_purge_lag=$innodb_max_purge_lag_orig; +eval SET GLOBAL innodb_max_purge_lag_delay=$innodb_max_purge_lag_delay_orig; +eval SET GLOBAL innodb_purge_batch_size = $innodb_purge_batch_size_orig; +#eval SET GLOBAL innodb_purge_threads = $innodb_purge_threads_orig; +eval SET GLOBAL relay_log_purge = $relay_log_purge_orig; +eval SET GLOBAL innodb_change_buffer_max_size = $innodb_change_buffer_max_size_orig; +eval SET GLOBAL innodb_change_buffering = $innodb_change_buffering_orig; +eval SET GLOBAL innodb_print_all_deadlocks = $innodb_print_all_deadlocks_orig; +--enable_query_log + + +#------------------------------------------------------------------------------ +#clenaup +#------------------------------------------------------------------------------ +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +DROP DATABASE testdb_wl6445; + +#------------------------------------------------------------------------------ +# Testcase 5 covers +# a) Create table/data restart server in readonly mode +# b) check starting with both --read-only and --innodb-read-only +# c) check starting with only --read-only +#------------------------------------------------------------------------------ +--echo case # 5 +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY , j VARCHAR(300), FULLTEXT KEY (j)) ENGINE = InnoDB; +CREATE INDEX idx1 ON testdb_wl6445.t1(i); +INSERT INTO t1 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +INSERT INTO t1 VALUES (4,'mysql database'),(5,'mysql database innodb support'),(6,'innodb engine'); +#FTS Query +SELECT * FROM t1 WHERE MATCH (j) AGAINST ('mysql (+database -innodb)' IN BOOLEAN MODE) ; +SELECT * FROM t1 WHERE MATCH (j) AGAINST ('innodb') ; + + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only --read-only" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +# check if root user able to modify +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i + 20; +--ERROR ER_CANT_LOCK +DELETE FROM t1; +--ERROR ER_INNODB_READ_ONLY +CREATE TABLE t2 ( i INT ) ENGINE = Innodb; +CREATE USER 'test5'@'localhost' IDENTIFIED BY '123'; +GRANT ALL ON testdb_wl6445.* TO 'test5'@'localhost'; + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make server can be start with --read-only +--exec echo "restart: --read-only" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +# check if root user able to do DML/DDL +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +UPDATE t1 SET i = i + 20; +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +DELETE FROM t1; +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +CREATE TABLE t2 ( i INT ) ENGINE = Innodb; +CREATE USER 'test5_2'@'localhost' IDENTIFIED BY '123'; +GRANT ALL ON testdb_wl6445.* TO 'test5_2'@'localhost'; + + +#------------------------------------------------------------------------------ +#clenaup +#------------------------------------------------------------------------------ +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +DROP USER 'test5_2'@'localhost'; +DROP USER 'test5'@'localhost'; +DROP DATABASE testdb_wl6445; + + + +#------------------------------------------------------------------------------ +# Testcase 6 covers +# a) Create table/data restart server in readonly mode +# b) check mysqldump/mysqlimport work +#------------------------------------------------------------------------------ +--echo case # 6 +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY ) ENGINE = InnoDB; +CREATE INDEX idx1 ON testdb_wl6445.t1(i); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT i FROM t1 ORDER BY i; + +--echo # Creating a temp sql file to be loaded. +--write_file $MYSQLTEST_VARDIR/tmp/t1.sql +11 +12 +13 +EOF + + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +USE testdb_wl6445; +# try mysql import +--replace_regex /.*Error//i +--error 1 +--exec $MYSQL_IMPORT -uroot testdb_wl6445 $MYSQLTEST_VARDIR/tmp/t1.sql 2>&1 +# only 3 records get in select as import shoudl fail due to --innodb-read-only +SELECT i FROM t1 ORDER BY i; + + +# mysqldump works +--exec $MYSQL_DUMP --skip-comments --databases testdb_wl6445 > $MYSQLTEST_VARDIR/tmp/testdb_wl6445_dump.txt + +--error 0,1 +--remove_file $MYSQLTEST_VARDIR/tmp/testdb_wl6445_dump.txt +--error 0,1 +--remove_file $MYSQLTEST_VARDIR/tmp/t1.sql + +#clenaup +#------------------------------------------------------------------------------ +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +DROP DATABASE testdb_wl6445; +--rmdir $MYSQL_TMP_DIR/alt_dir/testdb_wl6445 +--rmdir $MYSQL_TMP_DIR/alt_dir +--disable_query_log +eval SET GLOBAL INNODB_FILE_FORMAT=$innodb_file_format; +eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; +eval SET GLOBAL innodb_large_prefix = $innodb_large_prefix_orig; +eval SET GLOBAL innodb_flush_log_at_trx_commit = $innodb_flush_log_at_trx_commit_orig; +call mtr.add_suppression("deleting orphaned .ibd file"); +--enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb-wl6445-2.test b/mysql-test/suite/innodb/t/innodb-wl6445-2.test new file mode 100644 index 00000000000..3acc0f07229 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-wl6445-2.test @@ -0,0 +1,245 @@ +######## suite/innodb/t/innodb-wl6445-2 ########## +# # +# Testcase for worklog WL#6445: InnoDB should be able to work with # +# read-only tables +# All sub-test in this file focus on changinf file permission and # +# restarting server in read only. It verifies necessary operations # +# are blocked # +# # +# # +# Creation: # +# 2011-09-06 Implemented this test as part of WL#6445 # +# # +###################################################################### + +# Don't test this under valgrind, memory leaks will occur due restart +--source include/not_valgrind.inc + +# Not supported in embedded +--source include/not_embedded.inc + +-- source include/have_innodb.inc +# *nix specific command to remove write permission +# wanted to use perl to save original permission of file and restore back after +# chnage but could not find way to do.(with perl we could run test on windows too) +-- source include/not_windows.inc + +let MYSQLD_DATADIR =`SELECT @@datadir`; +let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; +let $innodb_file_format = `SELECT @@innodb_file_format`; +let $innodb_large_prefix_orig = `select @@innodb_large_prefix`; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +SET GLOBAL innodb_file_format = `Barracuda`; +SELECT @@innodb_file_format; + +set global innodb_large_prefix=1; +SELECT @@innodb_large_prefix; + +let $MYSQLD_DATADIR = `SELECT @@datadir`; + + +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; + + +#------------------------------------------------------------------------------ +# Testcase covers +# a) Create table/data , +# b) remove write permission of ibdata , ib_logfile0 +# c) restart server in --innodb-read-only mode and verfiy DDL/DML/DCL in read only mode +#------------------------------------------------------------------------------ +--echo case # 1 + +SET GLOBAL innodb_file_per_table = 1; +SET GLOBAL innodb_file_format = `Barracuda`; +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY , j blob) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +# remove write permissions +--exec chmod a-w $MYSQLD_DATADIR/ibdata1 +--exec chmod a-w $MYSQLD_DATADIR/testdb_wl6445/t1.ibd +--exec chmod a-w $MYSQLD_DATADIR/ib_logfile0 +# + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +USE testdb_wl6445; +SELECT i FROM t1 ORDER BY i; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +--ERROR ER_INNODB_READ_ONLY +CREATE TABLE t2 ( i int , j blob) ENGINE = Innodb; +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i+1; + +# Fix in next revision - known ( no data returned) +# SHOW ENGINE INNODB STATUS; +FLUSH STATUS; +FLUSH LOGS; +FLUSH TABLES t1; +FLUSH TABLES WITH READ LOCK; +UNLOCK TABLES; + + +#------------------------------------------------------------------------------ +#clenaup +#------------------------------------------------------------------------------ +# +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--exec chmod 0644 $MYSQLD_DATADIR/ibdata1 +--exec chmod 0644 $MYSQLD_DATADIR/ib_logfile0 +--exec chmod 0660 $MYSQLD_DATADIR/testdb_wl6445/t1.ibd +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +DROP DATABASE IF EXISTS testdb_wl6445; + + +#------------------------------------------------------------------------------ +# Testcase covers +# a) Create table/data , +# b) remove write permission of ibdata , ib_logfile0 when server is running +# c) restart server in --innodb-read-only mode and verfiy DDL/DML/DCL in read only mode +#------------------------------------------------------------------------------ +--echo case # 2 +--disable_warnings +DROP DATABASE IF EXISTS testdb_wl6445; +--enable_warnings +CREATE DATABASE testdb_wl6445; + +USE testdb_wl6445; +CREATE TABLE t1 ( i int PRIMARY KEY , j blob) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +# remove write permissions +--exec chmod a-w $MYSQLD_DATADIR/ibdata1 +--exec chmod a-w $MYSQLD_DATADIR/testdb_wl6445/t1.ibd +--exec chmod a-w $MYSQLD_DATADIR/ib_logfile0 +# +# check dml/ddl after removing write permission +CREATE TABLE t2 ( i int PRIMARY KEY , j blob) ENGINE = InnoDB; +INSERT INTO t2 VALUES (1,repeat('a',200)),(2,repeat('b',200)),(3,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t2 ORDER BY i; +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +UPDATE t2 SET i = i + 10; +SELECT i,LEFT(j,20) FROM t2 ORDER BY i; +DELETE FROM t2; +SELECT i,LEFT(j,20) FROM t2 ORDER BY i; + + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +# Do something while server is down +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart: --innodb-read-only " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc + +USE testdb_wl6445; +SELECT i FROM t1 ORDER BY i; +SELECT i FROM t2 ORDER BY i; +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; + +--ERROR ER_CANT_LOCK +INSERT INTO t1 VALUES (11,repeat('a',200)),(12,repeat('b',200)),(13,repeat('c',200)); +SELECT i,LEFT(j,20) FROM t1 ORDER BY i; +--ERROR ER_TABLE_EXISTS_ERROR +CREATE TABLE t2 ( i int , j blob) ENGINE = Innodb; +--ERROR ER_INNODB_READ_ONLY +CREATE TABLE t3 ( i int , j blob) ENGINE = Innodb; +--ERROR ER_CANT_LOCK +UPDATE t1 SET i = i+1; + +# Fix in next revision - known ( no data returned) +# SHOW ENGINE INNODB STATUS; +FLUSH STATUS; +FLUSH LOGS; +FLUSH TABLES t1,t2; +FLUSH TABLES WITH READ LOCK; +UNLOCK TABLES; + + +#------------------------------------------------------------------------------ +# Testcase covers +# a) Create table/data , +# b) remove write permission of ibdata , ib_logfile0 +# c) try to restart server without --innodb-read-only mode +#------------------------------------------------------------------------------ +# Note : write permission is already removed in previous case so we just +# start server without --innodb-read-only option + +--echo case # 3 + +# We let our server restart attempts write to the file $error_log. +let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err; +--error 0,1 +--remove_file $error_log +# $error_log has to be processed by include/search_pattern_in_file.inc which +# contains Perl code requiring that the environment variable SEARCH_FILE points +# to this file. +let SEARCH_FILE= $error_log; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc + +--echo # Try to restart the server without --innodb-read-only after removing +--echo # write permissions of system tablespace. Server should not start. +--echo # This confirms server is not automatically started in read-only mode. +#---------------------------------------------------------------------------------- +# Detailed explanations of what happens are placed nearby the checks. +--error 1 +--exec $MYSQLD_CMD --loose-console > $error_log 2>&1 + +# We get depending on the platform either "./ibdata1" or ".\ibdata1". +let SEARCH_PATTERN=InnoDB: The system tablespace must be writable; +--source include/search_pattern_in_file.inc + + +#------------------------------------------------------------------------------ +#clenaup +#------------------------------------------------------------------------------ +# +# Do something while server is down +--exec chmod 0644 $MYSQLD_DATADIR/ibdata1 +--exec chmod 0644 $MYSQLD_DATADIR/ib_logfile0 +--exec chmod 0660 $MYSQLD_DATADIR/testdb_wl6445/t1.ibd +--error 0,1 +--remove_file $error_log +--enable_reconnect +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +USE testdb_wl6445; +DROP DATABASE testdb_wl6445; +eval SET GLOBAL INNODB_FILE_FORMAT=$innodb_file_format; +eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; +eval SET GLOBAL innodb_large_prefix = $innodb_large_prefix_orig; diff --git a/mysql-test/suite/innodb/t/innodb-wl6445.test b/mysql-test/suite/innodb/t/innodb-wl6445.test new file mode 100644 index 00000000000..1e0e492aee9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-wl6445.test @@ -0,0 +1,103 @@ +--source include/have_innodb.inc + +# Don't test this under valgrind, memory leaks will occur due restart +--source include/not_valgrind.inc + +# Embedded has issues with restarting +--source include/not_embedded.inc + +CREATE DATABASE WL6445; + +CREATE TABLE WL6445.t1(c1 INT, c2 INT, INDEX sec_idx(c2)) ENGINE=InnoDB; +INSERT INTO WL6445.t1 VALUES(0,0),(1,1),(2,2); + +SHOW CREATE TABLE WL6445.t1; + +# Write file to make mysql-test-run.pl wait for the server to stop +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--echo # Request clean shutdown +--send_shutdown + +--echo # Wait for disconect +--source include/wait_until_disconnected.inc + +--echo # Restart server. +--exec echo "restart:--innodb-read-only" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +--echo # Restarted + +## DDL + +SELECT COUNT(*) FROM WL6445.t1; + +--error ER_CANT_LOCK +INSERT INTO WL6445.t1 VALUES(3,3); + +--ERROR ER_OPEN_AS_READONLY +INSERT INTO WL6445.t1 SELECT * FROM WL6445.t1; + +--error ER_CANT_LOCK +REPLACE INTO WL6445.t1 VALUES(1,1); + +--error ER_CANT_LOCK +UPDATE WL6445.t1 SET c1 = c1 + 100; + +--error ER_CANT_LOCK +DELETE FROM WL6445.t1; + +# DDL +--error ER_DUP_FIELDNAME +ALTER TABLE WL6445.t1 ADD COLUMN c2 INT; + +--error ER_CANT_LOCK +ALTER TABLE WL6445.t1 ADD UNIQUE INDEX(c1); + +--error ER_CANT_LOCK +ALTER TABLE WL6445.t1 DROP INDEX sec_idx; + +# FIXME: Should bne +#--error ER_OPEN_AS_READONLY +--replace_regex /wl6445/WL6445/i +--error ER_BAD_TABLE_ERROR +DROP TABLE WL6445.t1; + +--error ER_OPEN_AS_READONLY +TRUNCATE TABLE WL6445.t1; + +--replace_regex /'\..*t1'/'t1'/ /'\..*t2'/'t2'/ +--error ER_ERROR_ON_RENAME +RENAME TABLE WL6445.t1 TO WL6444.t2; + +--replace_regex /wl6445/WL6445/i +--error ER_BAD_TABLE_ERROR +DROP DATABASE WL6445; + +SHOW CREATE TABLE WL6445.t1; + +# Restart in RW mode so that we can drop the test data +# Write file to make mysql-test-run.pl wait for the server to stop +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--echo # Request clean shutdown +--send_shutdown + +--echo # Wait for disconect +--source include/wait_until_disconnected.inc + +--echo # Restart server. +--exec echo "restart:" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +--echo # Restarted + +DROP TABLE WL6445.t1; + +DROP DATABASE WL6445; diff --git a/mysql-test/suite/innodb/t/innodb_autoinc_reset.test b/mysql-test/suite/innodb/t/innodb_autoinc_reset.test new file mode 100644 index 00000000000..b5411e9f2a3 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_autoinc_reset.test @@ -0,0 +1,25 @@ +# +# BUG#21454472 AUTO-INCREMENT SEQUENCE GETS RESET +# + +--source include/have_innodb.inc +--source include/have_debug.inc + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(100) +) ENGINE=InnoDB AUTO_INCREMENT=99; + +SET GLOBAL debug="+d,innodb_evict_autoinc_table"; + +# Evict t1 from dictionary cache +-- error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL innodb_ft_aux_table="test/t1"; + +SET GLOBAL debug="-d,innodb_evict_autoinc_table"; + +INSERT INTO t1(name) VALUES('mysql'); + +SELECT * FROM t1; + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_load-master.opt b/mysql-test/suite/innodb/t/innodb_buffer_pool_load-master.opt new file mode 100644 index 00000000000..252c52fbcb0 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_load-master.opt @@ -0,0 +1 @@ +--innodb-buffer-pool-size=64M diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_load.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_load.test new file mode 100644 index 00000000000..9bd2c830673 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_load.test @@ -0,0 +1,115 @@ +#Want to skip this test from daily Valgrind execution +--source include/no_valgrind_without_big.inc +# +# Test for the functionality of InnoDB Buffer Pool dump/load. +# + +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)` + +-- error 0,1 +-- remove_file $file + +# Create a table and populate it with some data +CREATE TABLE ib_bp_test +(a INT AUTO_INCREMENT, b VARCHAR(64), c TEXT, PRIMARY KEY (a), KEY (b, c(128))) +ENGINE=INNODB; + +let $check_cnt = +SELECT COUNT(*) FROM information_schema.innodb_buffer_page_lru +WHERE table_name LIKE '%ib_bp_test%'; + +# See that we have a small number of pages in the LRU +-- eval $check_cnt + +# Here we end up with 16382 rows in the table +-- disable_query_log +INSERT INTO ib_bp_test (b, c) VALUES (REPEAT('b', 64), REPEAT('c', 256)); +INSERT INTO ib_bp_test (b, c) VALUES (REPEAT('B', 64), REPEAT('C', 256)); +let $i=12; +while ($i) +{ + -- eval INSERT INTO ib_bp_test (b, c) VALUES ($i, $i * $i); + INSERT INTO ib_bp_test (b, c) SELECT b, c FROM ib_bp_test; + dec $i; +} +-- enable_query_log + +# Accept 329 for 16k page size, 662 for 8k page size & 1392 for 4k page size +-- replace_result 329 {checked_valid} 662 {checked_valid} 1392 {checked_valid} +-- eval $check_cnt + +# Dump +SET GLOBAL innodb_buffer_pool_dump_now = ON; + +# Wait for the dump to complete +let $wait_condition = + SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at ' + FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'; +-- source include/wait_condition.inc + +# Confirm the file has been created +-- file_exists $file + +# Add some garbage records to the dump file +-- let IBDUMPFILE = $file +perl; +my $fn = $ENV{'IBDUMPFILE'}; +open(my $fh, '>>', $fn) || die "perl open($fn): $!"; +print $fh "123456,0\n"; +print $fh "0,123456\n"; +print $fh "123456,123456\n"; +close($fh); +EOF + +-- source include/restart_mysqld.inc + +# Load the table so that entries in the I_S table do not appear as NULL +select count(*) from ib_bp_test where a = 1; + +# Load +SET GLOBAL innodb_buffer_pool_load_now = ON; + +# Wait for the load to complete +let $wait_condition = + SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) load completed at ' + FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_status'; +-- source include/wait_condition.inc + +# Show the status, interesting if the above timed out +-- replace_regex /[0-9]{6}[[:space:]]+[0-9]{1,2}:[0-9]{2}:[0-9]{2}/TIMESTAMP_NOW/ +SELECT variable_value +FROM information_schema.global_status +WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_status'; + +# Accept 329 for 16k page size, 662 for 8k page size & 1392 for 4k page size +-- replace_result 329 {checked_valid} 662 {checked_valid} 1392 {checked_valid} +-- eval $check_cnt + +# Add some total garbage to the dump file +-- let IBDUMPFILE = $file +perl; +my $fn = $ENV{'IBDUMPFILE'}; +open(my $fh, '>>', $fn) || die "perl open($fn): $!"; +print $fh "abcdefg\n"; +close($fh); +EOF + +call mtr.add_suppression("InnoDB: Error parsing"); + +# Load +SET GLOBAL innodb_buffer_pool_load_now = ON; + +# Wait for the load to fail +let $wait_condition = + SELECT SUBSTR(variable_value, 1, 13) = 'Error parsing' + FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_status'; +-- source include/wait_condition.inc + +DROP TABLE ib_bp_test; diff --git a/mysql-test/suite/innodb/t/innodb_bug-13628249.test b/mysql-test/suite/innodb/t/innodb_bug-13628249.test new file mode 100644 index 00000000000..5add0fca29e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug-13628249.test @@ -0,0 +1,125 @@ +# This is the test case for bug#13628249. Make sure that InnoDB starts +# up correctly and is able to shutdown with --innodb-force-recovery >= 3 +# after a crash with active user tranactions. + +# +# Not supported in embedded +--source include/not_embedded.inc + +# +# This test case needs to crash the server. Needs a debug server. +--source include/have_debug.inc +# +# Don't test this under valgrind, memory leaks will occur. +--source include/not_valgrind.inc +# +# This test case needs InnoDB. +-- source include/have_innodb.inc + +# Avoid CrashReporter popup on Mac +--source include/not_crashrep.inc + +call mtr.add_suppression('InnoDB: Failed to find tablespace for table \'"mysql"."slave_master_info"\' in the cache'); +call mtr.add_suppression('InnoDB: Failed to find tablespace for table \'"mysql"."slave_relay_log_info"\' in the cache'); +call mtr.add_suppression('InnoDB: Failed to find tablespace for table \'"mysql"."slave_worker_info"\' in the cache'); +call mtr.add_suppression('InnoDB: Failed to find tablespace for table \'"test"."t1"\' in the cache'); +call mtr.add_suppression('InnoDB: Allocated tablespace [0-9]+, old maximum was [0-9]+'); + +##### Restart the server in force recovery mode +--echo # Stop server + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Request shutdown +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart:--innodb-force-recovery=2" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +##### Restart the server in normal mode +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Send a shutdown request to the server +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + + +# +# Create test data. +# +CREATE TABLE t1(c1 INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; +BEGIN; +INSERT INTO t1 VALUES(1), (2), (3), (4); + +# Request a crash on next execution of commit. +SET SESSION debug="+d,crash_commit_before"; + +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart:--innodb-force-recovery=3" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Execute the statement that causes the crash. +--error 2013 +COMMIT; + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT COUNT(*) IN (0,4) yes FROM t1; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--send_shutdown +--source include/wait_until_disconnected.inc + +--exec echo "restart:--innodb-force-recovery=5" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT COUNT(*) IN (0,4) yes FROM t1; + +# Restart the server in normal mode now, otherwise the DROP TABLE t1; +# will cause an assertion failure because essentially it is in read-only +# mode. For -innodb-force-recovery >= 3 a transaction is not assigned a +# rollback segment. +-- source include/restart_mysqld.inc + +SELECT COUNT(*) IN (0,4) yes FROM t1; + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_bug11766634-master.opt b/mysql-test/suite/innodb/t/innodb_bug11766634-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug11766634-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/innodb/t/innodb_bug11766634.test b/mysql-test/suite/innodb/t/innodb_bug11766634.test new file mode 100644 index 00000000000..0cd07464971 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug11766634.test @@ -0,0 +1,76 @@ +# Bug 11766634 59783: InnoDB data grows unexpectedly when inserting, +# truncating, inserting the same set of rows. +# +# Scenario: +# create table t1. Insert $recs records. check size of ibdata1. +# drop table t1. create table t1. Insert the same set of $recs +# records. The size of ibdata1 must not increase. +# + +#Want to skip this test from daily Valgrind execution. +--source include/no_valgrind_without_big.inc +# Adding big test option for this test. +--source include/big_test.inc + +-- source include/not_embedded.inc +-- source include/have_innodb.inc + +--echo # This test case needs the innodb_file_per_table option to be disabled. +set global innodb_file_per_table = 0; +show variables like 'innodb_file_per_table'; + +create table t1 (f1 char(255)) engine innodb; +let $MYSQLD_DATADIR=`select @@datadir`; +let IBDATA1=$MYSQLD_DATADIR/ibdata1; +let $MYSQLD_TMPDIR = `SELECT @@tmpdir`; +let $rnd=`SELECT FLOOR(1 + (RAND() * 100000))`; +let TMPFILE=$MYSQLD_TMPDIR/bug11766634-$rnd.txt; + +let $recs = 36262; + +--disable_query_log +let $c = $recs; +start transaction; +while ($c) +{ + insert into t1 values ('Hello World'); + dec $c; +} +commit work; +--enable_query_log + +perl; +my $filesize = -s $ENV{'IBDATA1'}; +open FILE, ">" . $ENV{'TMPFILE'} or die $!; +print FILE "$filesize\n"; +close(FILE); +EOF + +drop table t1; +create table t1 (f1 char(255)) engine innodb; + +--disable_query_log +let $c = $recs; +start transaction; +while ($c) +{ + insert into t1 values ('Hello World'); + dec $c; +} +commit work; +--enable_query_log + +perl; +my $newfilesize = -s $ENV{'IBDATA1'}; +open FILE, "<" . $ENV{'TMPFILE'} or die $!; +my @lines = <FILE>; +close(FILE); +die "File size read from temp file was 0!\n" if $lines[0] == 0; +my $diff = $newfilesize - $lines[0]; +print "Difference in ibdata1 file size: $diff\n"; +unlink($ENV{'TMPFILE'}) or die $!; +EOF + +drop table t1; +set global innodb_file_per_table = 1; + diff --git a/mysql-test/suite/innodb/t/innodb_bug11789106.test b/mysql-test/suite/innodb/t/innodb_bug11789106.test new file mode 100644 index 00000000000..c9d3fb5e800 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug11789106.test @@ -0,0 +1,17 @@ +# Test for bug #11789106: FAILING ASSERTION: templ->mbmaxlen > templ->mbminlen +# templ->mysql_col_len == len + +-- source include/have_innodb.inc + +create table table_11789106(`a` point,`b` int,`c` char(2), + primary key (`a`(1),`c`(1)), key (`b`)) +character set latin2 engine=innodb; + +insert into table_11789106 values (geomfromtext('point(1 1)'),'',''); + +# This will trigger the assertion failure in +# row_sel_field_store_in_mysql_format_func() +select `a` from table_11789106 where `b` < '1' for update; + +drop table table_11789106; + diff --git a/mysql-test/suite/innodb/t/innodb_bug11933790.test b/mysql-test/suite/innodb/t/innodb_bug11933790.test new file mode 100644 index 00000000000..6627db062f9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug11933790.test @@ -0,0 +1,42 @@ +# +# Bug 11933790 - INNODB ASSERTS TRX->IN_MYSQL_TRX_LIST IN ANALYZE WITH +# PERSISTENT STATS +# + +-- source include/have_innodb.inc + +call mtr.add_suppression("InnoDB: Error while trying to save table statistics for table .+bug11933790.*: Lock wait timeout"); + +# we are only interested that the below commands do not crash the server +-- disable_query_log +-- disable_result_log + +CREATE TABLE bug11933790 (c INT) ENGINE=INNODB STATS_PERSISTENT=1; + +# add some records to mysql.innodb_table_stats +ANALYZE TABLE bug11933790; + +SET autocommit=0; + +# lock the records in mysql.innodb_table_stats +SELECT * FROM mysql.innodb_table_stats FOR UPDATE; + +-- connect (con1,localhost,root,,) + +-- connection con1 + +# this will fail with lock wait timeout; if the bug is present then mysqld +# crashes here +-- enable_query_log +-- enable_result_log +ANALYZE TABLE bug11933790; +-- disable_query_log +-- disable_result_log + +-- connection default + +-- disconnect con1 + +COMMIT; + +DROP TABLE bug11933790; diff --git a/mysql-test/suite/innodb/t/innodb_bug12429573.test b/mysql-test/suite/innodb/t/innodb_bug12429573.test new file mode 100644 index 00000000000..46a3d9d7d37 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug12429573.test @@ -0,0 +1,42 @@ +# +# Bug#12429573 TIMESTAMP COLUMN OF INNODB.INDEX_STATS ARE NOT UPDATED +# WHEN RE-RUNNING ANALYZE +# + +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +CREATE TABLE bug12429573 (i INTEGER PRIMARY KEY, j INTEGER, KEY(j)) +ENGINE=INNODB STATS_PERSISTENT=1; + +ANALYZE TABLE bug12429573; + +# Cannot check the exact timestamp here because it is always different +# but at least check that both timestamps in innodb_table_stats and in +# innodb_index_stats have been updated to the same value. If the bug is +# present this check will fail. + +SELECT last_update FROM mysql.innodb_index_stats WHERE +table_name = 'bug12429573' AND +last_update NOT IN +(SELECT last_update FROM mysql.innodb_table_stats + WHERE table_name = 'bug12429573'); + +# The first ANALYZE would insert timestamp e.g. 17:23:39 in both +# innodb_table_stats and innodb_index_stats. The bug is that the second +# ANALYZE only updates the timestamp in innodb_table_stats. In order to +# check if the timestamp in innodb_index_stats has really been updated we +# need it to be different from the previous one (17:23:39) with at least +# one second. +-- sleep 1 + +ANALYZE TABLE bug12429573; + +# If the bug is present we get the timestamps different here. +SELECT last_update FROM mysql.innodb_index_stats WHERE +table_name = 'bug12429573' AND +last_update NOT IN +(SELECT last_update FROM mysql.innodb_table_stats + WHERE table_name = 'bug12429573'); + +DROP TABLE bug12429573; diff --git a/mysql-test/suite/innodb/t/innodb_bug13635833.test b/mysql-test/suite/innodb/t/innodb_bug13635833.test new file mode 100644 index 00000000000..47185b9d526 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug13635833.test @@ -0,0 +1,64 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/not_embedded.inc + +SET DEBUG_SYNC='reset'; + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +create table t1 (f1 integer, key k1 (f1)) engine=innodb; +create table t2 (f1 int, f2 int, key(f1), key(f2)) engine=innodb; +create table t3 (f2 int, key(f2)) engine=innodb; + +insert into t1 values (10); +insert into t2 values (10, 20); +insert into t3 values (20); + +alter table t2 add constraint c1 foreign key (f1) + references t1(f1) on update cascade; + +show create table t1; +show create table t2; +show create table t3; + +SET DEBUG_SYNC='innodb_rename_table_ready SIGNAL update_can_proceed + WAIT_FOR dict_unfreeze'; + +--send +alter table t2 add constraint z1 foreign key (f2) + references t3(f2) on update cascade; + +connect (thr2,localhost,root,,); +connection thr2; + +SET DEBUG_SYNC='innodb_row_update_for_mysql_begin + WAIT_FOR update_can_proceed'; +SET DEBUG_SYNC='innodb_dml_cascade_dict_unfreeze SIGNAL dict_unfreeze + WAIT_FOR foreign_free_cache'; + +--send +update ignore t1 set f1 = 20; + +connection default; +--replace_regex /'[^']*test\/#sql2-[0-9a-f-]*'/'#sql2-temporary'/ +--error ER_ERROR_ON_RENAME +reap; + +SET DEBUG_SYNC='now SIGNAL foreign_free_cache'; + +connection thr2; +reap; +disconnect thr2; +--source include/wait_until_disconnected.inc + +connection default; + +drop table t2; +drop table t1; +drop table t3; + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc + +SET DEBUG_SYNC='reset'; diff --git a/mysql-test/suite/innodb/t/innodb_bug13867871.test b/mysql-test/suite/innodb/t/innodb_bug13867871.test new file mode 100644 index 00000000000..bc271de4af6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug13867871.test @@ -0,0 +1,199 @@ +# Test for Bug 13867871 - ROW_INS_CHECK_FOREIGN_CONSTRAINT() ACCESSES +# FREED DICT_INDEX_T +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +# Save the initial number of concurrent sessions. +--source include/count_sessions.inc + +CREATE TABLE parent ( +a INT, d INT, b VARCHAR(20), c VARCHAR(75), +PRIMARY KEY (a, d, b), INDEX (b, c), INDEX (c)) +ENGINE = INNODB; + +CREATE TABLE child ( +a INT, d INT, b VARCHAR(20), c VARCHAR(75), +PRIMARY KEY (a, d, b), INDEX (b, c), INDEX (c), +FOREIGN KEY (a, d) REFERENCES parent (a, d) +ON DELETE CASCADE ON UPDATE CASCADE, +CONSTRAINT kukkuu FOREIGN KEY (b, c) REFERENCES parent (b, c) +ON DELETE CASCADE ON UPDATE CASCADE) +ENGINE = INNODB; + +INSERT INTO parent VALUES (1, 5, 'khD','khD'); +SET innodb_lock_wait_timeout=1; + +connect (con1,localhost,root,,); + +connection con1; +--echo # connection con1: blocked before FOREIGN KEY check during INSERT + +SET DEBUG_SYNC = 'foreign_constraint_check_for_ins WAIT_FOR drop_done'; +--send +/* con1 send */ INSERT INTO child VALUES (1, 5, 'khD','khD'); + +connection default; +--echo # connection default: replace the underlying index of FOREIGN KEY +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = 'debug sync point: foreign_constraint_check_for_ins' + AND info = '/* con1 send */ INSERT INTO child VALUES (1, 5, ''khD'',''khD'')'; +--source include/wait_condition.inc + +CREATE INDEX idx1 ON parent(b, c); +DROP INDEX b ON parent; +SET DEBUG_SYNC = 'now SIGNAL drop_done'; + +connection con1; +--echo /* con1 reap */ INSERT INTO child VALUES (1, 5, 'khD','khD'); +reap; +--echo # connection con1: test ON UPDATE CASCADE +BEGIN; +SET DEBUG_SYNC = 'foreign_constraint_update_cascade WAIT_FOR create_index'; +SET DEBUG_SYNC = 'now SIGNAL start_test'; +--send +/* con1 send */ DELETE FROM parent WHERE a = 1; + +connection default; +--echo # connection default: con1 already IX-locked table child + +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = 'debug sync point: foreign_constraint_update_cascade' + AND info = '/* con1 send */ DELETE FROM parent WHERE a = 1'; +--source include/wait_condition.inc + +--error ER_LOCK_DEADLOCK +--send +/* default send */ CREATE INDEX idx ON child(b, c); + +connect (con2,localhost,root,,); +SET DEBUG_SYNC = 'now WAIT_FOR start_test'; +--echo # connection con2: unblock connection default +SET DEBUG_SYNC = 'now SIGNAL create_index'; + +connection default; +--echo /* default reap */ CREATE INDEX idx ON child(b, c); +--error 0, ER_LOCK_WAIT_TIMEOUT +reap; + +connection con1; +--echo /* con1 reap */ DELETE FROM parent WHERE a = 1; +reap; + +connection default; +--echo # connection default: con1 is holding IX-lock on table child +--error ER_LOCK_WAIT_TIMEOUT +CREATE INDEX idx ON child(b, c); +--error ER_DROP_INDEX_FK +DROP INDEX b ON child; + +connection con1; +--echo # connection con1 +COMMIT; + +connection default; +--echo # connection default: no locks on table child +CREATE INDEX idx ON child(b, c); +DROP INDEX b ON child; + +SELECT * FROM child; +SELECT * FROM parent; + +connection con1; +--echo # connection con1: test ON UPDATE CASCADE + +INSERT INTO parent VALUES (1, 5, 'khD','khD'); + +INSERT INTO child VALUES (1, 5, 'khD','khD'); + +BEGIN; +SET DEBUG_SYNC = 'foreign_constraint_check_for_update_done WAIT_FOR alter'; +--send +/* con1 send */ UPDATE parent SET a = 2; + +connection default; +--echo # connection default: con1 is holding IX-lock on table child + +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = 'debug sync point: foreign_constraint_check_for_update_done' + AND info = '/* con1 send */ UPDATE parent SET a = 2'; +--source include/wait_condition.inc + +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx, LOCK=NONE; + +SET DEBUG_SYNC = 'now SIGNAL alter'; + +connection con1; +--echo /* con1 reap */ UPDATE parent SET a = 2; +reap; +connection default; +--echo # connection default: con1 is holding IX-lock on table child +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx, ALGORITHM=INPLACE; +connection con1; +--echo # connection con1 +ROLLBACK; + +BEGIN; +SET DEBUG_SYNC = 'foreign_constraint_check_for_update WAIT_FOR altered'; +SET DEBUG_SYNC = 'now SIGNAL start_test'; +--send +/* con1 send */ UPDATE parent SET a = 3; + +connection default; +--echo # connection default: con1 is not yet holding locks on table child + +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = 'debug sync point: foreign_constraint_check_for_update' + AND info = '/* con1 send */ UPDATE parent SET a = 3'; +--source include/wait_condition.inc + +# This should be blocked in commit_inplace_alter_table +--send +/* default send */ ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx; + +connection con2; + +SET DEBUG_SYNC = 'now WAIT_FOR start_test'; + +--echo # connection con2: unblock connection con1 +SET DEBUG_SYNC = 'now SIGNAL altered'; +disconnect con2; + +connection con1; +--echo /* con1 reap */ UPDATE parent SET a = 3; +reap; + +connection default; +--echo /* default reap */ ALTER TABLE child ADD INDEX idx_2(B, C), DROP INDEX idx; +# TODO (Bug#14529475): investigate why this is nondeterministic +# Progress report: Added a new sync point 'start_test', chtest.sh does +# not report problem any more. However, it needs some more confirmation +# before this go arounds can be removed. +--error 0, ER_LOCK_WAIT_TIMEOUT +reap; +SELECT * FROM child; + +connection con1; +--echo # connection con1 +SELECT * FROM child; +COMMIT; +disconnect con1; + +connection default; + +SELECT * FROM child; +SELECT * FROM parent; + +DROP TABLE child; +DROP TABLE parent; + +SET DEBUG_SYNC = 'RESET'; + +# Check that all connections opened by test cases in this file are really +# gone so execution of other tests won't be affected by their presence. +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb_bug14006907.test b/mysql-test/suite/innodb/t/innodb_bug14006907.test new file mode 100644 index 00000000000..726bfbcb844 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14006907.test @@ -0,0 +1,56 @@ +# Test for Bug 14006907 - FOREIGN KEY PROBLEMS AFTER DROP INDEX +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +# Save the initial number of concurrent sessions. +--source include/count_sessions.inc + +SET DEBUG_SYNC='RESET'; +CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, INDEX(c2)) ENGINE = InnoDB; + +CREATE TABLE t2 ( + c2 INT PRIMARY KEY, + CONSTRAINT t2c2 FOREIGN KEY (c2) REFERENCES t1 (c2)) +ENGINE = InnoDB; + +--error ER_DROP_INDEX_FK +DROP INDEX c2 ON t1; + +DROP TABLE t2; + +SET DEBUG_SYNC = 'innodb_after_inplace_alter_table SIGNAL drop WAIT_FOR fk'; +--send +DROP INDEX c2 ON t1; + +--echo # Establish session con1 (user=root) +connect (con1,localhost,root,,); +--echo # Session con1 +connection con1; + +SET DEBUG_SYNC = 'now WAIT_FOR drop'; +--error ER_CANNOT_ADD_FOREIGN +CREATE TABLE t2 ( + c2 INT PRIMARY KEY, + CONSTRAINT t2c2 FOREIGN KEY (c2) REFERENCES t1 (c2)) +ENGINE = InnoDB; +SET DEBUG_SYNC = 'now SIGNAL fk'; + +disconnect con1; + +--echo # Session default +connection default; +--echo /* reap */ DROP INDEX c2 ON t1; +reap; + +--error ER_CANNOT_ADD_FOREIGN +CREATE TABLE t2 ( + c2 INT PRIMARY KEY, + CONSTRAINT t2c2 FOREIGN KEY (c2) REFERENCES t1 (c2)) +ENGINE = InnoDB; + +SET DEBUG_SYNC='RESET'; +DROP TABLE t1; + +# Check that all connections opened by test cases in this file are really +# gone so execution of other tests won't be affected by their presence. +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb_bug14007109.test b/mysql-test/suite/innodb/t/innodb_bug14007109.test new file mode 100644 index 00000000000..addc7799520 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14007109.test @@ -0,0 +1,38 @@ +# +# Bug#14007109 RECURSIVE ACQ OF BLOCK LOCK IN S MODE, STATS UPDATE ASRT !RW_LOCK_OWN(LOCK, 352) +# + +-- source include/have_innodb.inc +# The assertion only fails in debug versions, so no need to test in non-debug +-- source include/have_debug.inc + +CREATE TABLE bug14007109 ( + a VARCHAR(512), PRIMARY KEY (a) +) ENGINE=INNODB STATS_PERSISTENT=1; + +BEGIN; +-- disable_query_log +# As of the time this test is added, 854 pages do not trigger the assert, +# while 855 do. We use a bigger number here just in case. What is needed +# is to have a btree with 3 levels, where the level in the middle contains +# two (or more) pages. The persistent stats code crawls that level twice +# in the same mtr: +# dict_stats_analyze_index() +# start mtr +# dict_stats_analyze_index_level(mtr) +# traverse the level (leaves the last page in the middle level S-latched) +# dict_stats_analyze_index_for_n_prefix(mtr) +# traverse the level (would try to S-latch the last page) +# commit mtr +let $i=900; +while ($i) { + eval INSERT INTO bug14007109 VALUES (REPEAT(1000+$i, 128)); + dec $i; +} +-- enable_query_log +COMMIT; + +# We get a (debug) assertion failure here if the bug exists +ANALYZE TABLE bug14007109; + +DROP TABLE bug14007109; diff --git a/mysql-test/suite/innodb/t/innodb_bug14169459.test b/mysql-test/suite/innodb/t/innodb_bug14169459.test new file mode 100644 index 00000000000..d37994d8871 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14169459.test @@ -0,0 +1,64 @@ +# This is the test for bug #14169459. + +--source include/have_innodb.inc + +SET default_storage_engine=InnoDB; + +--disable_query_log +# These values can change during the test +LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`; + +# Set up some variables +LET $MYSQL_DATA_DIR = `select @@datadir`; +--enable_query_log + +SET GLOBAL innodb_file_per_table=ON; + +--echo # +--echo # Create a temporary table and drop it. Make sure the ibd file is gone. +--echo # Make sure a discarded table can be dropped with all files deleted. +--echo # +CREATE TEMPORARY TABLE t14169459_1 (a INT, b TEXT) engine=InnoDB; +CREATE TABLE t14169459_2 (a INT, b TEXT) engine=InnoDB; + +INSERT INTO t14169459_1 VALUES (1, 'one'),(2, 'two'); +INSERT INTO t14169459_2 VALUES (1, 'one'),(2, 'two'); +SELECT * FROM t14169459_1; +SELECT * FROM t14169459_2; +SHOW CREATE TABLE t14169459_1; +SHOW CREATE TABLE t14169459_2; + +--echo ### directory of MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### directory of MYSQL_TMP_DIR/mysqld.1 +--replace_regex /#sql[0-9a-f_]*/#sql<temporary>/ +--list_files $MYSQL_TMP_DIR/mysqld.1 *.ibd + +FLUSH TABLES t14169459_2 FOR EXPORT; +SELECT * FROM t14169459_2; +UNLOCK TABLES; +--echo ### directory of MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +ALTER TABLE t14169459_2 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t14169459_2; +--echo ### directory of MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### directory of MYSQL_TMP_DIR/mysqld.1 +--replace_regex /#sql[0-9a-f_]*/#sql<temporary>/ +--list_files $MYSQL_TMP_DIR/mysqld.1 *.ibd + +#--file_exists $MYSQL_TMP_DIR/mysqld.1/#sql15f8_2_1.ibd + +DROP TABLE t14169459_1; +DROP TABLE t14169459_2; +--echo ### directory of MYSQL_DATA_DIR/test +--list_files $MYSQL_DATA_DIR/test +--echo ### directory of MYSQL_TMP_DIR/mysqld.1 +--replace_regex /#sql[0-9a-f_]*/#sql<temporary>/ +--list_files $MYSQL_TMP_DIR/mysqld.1 *.ibd + +-- disable_query_log +eval set global innodb_file_per_table=$innodb_file_per_table_orig; +-- enable_query_log + diff --git a/mysql-test/suite/innodb/t/innodb_bug47167-master.opt b/mysql-test/suite/innodb/t/innodb_bug47167-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug47167-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/innodb/t/innodb_bug59307.test b/mysql-test/suite/innodb/t/innodb_bug59307.test new file mode 100644 index 00000000000..31841fa6018 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug59307.test @@ -0,0 +1,32 @@ +-- source include/have_innodb.inc +# Bug #59307 uninitialized value in rw_lock_set_writer_id_and_recursion_flag() +# when Valgrind instrumentation (UNIV_DEBUG_VALGRIND) is not enabled + +CREATE TABLE t1 ( + t1_int INT, + t1_time TIME +) ENGINE=innodb; + +CREATE TABLE t2 ( + t2_int int PRIMARY KEY, + t2_int2 INT +) ENGINE=INNODB; + +INSERT INTO t2 VALUES (); +INSERT INTO t1 VALUES (); + +SELECT * +FROM t1 AS t1a +WHERE NOT EXISTS + (SELECT * + FROM t1 AS t1b + WHERE t1b.t1_int NOT IN + (SELECT t2.t2_int + FROM t2 + WHERE t1b.t1_time LIKE t1b.t1_int + OR t1b.t1_time <> t2.t2_int2 + AND 6=7 + ) +) +; +DROP TABLE t1,t2; diff --git a/mysql-test/suite/innodb/t/innodb_bug70867.test b/mysql-test/suite/innodb/t/innodb_bug70867.test new file mode 100644 index 00000000000..1301924d037 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug70867.test @@ -0,0 +1,53 @@ +# +# Bug#70867 WRONG OS ERROR NUMBER REPORTED IN ERROR LOG DURING FAILURE AT STARTUP +# + +--source include/have_innodb.inc + + +# This test uses chmod, can't be run with root permissions +--source include/not_as_root.inc +# Embedded server does not support crashing +--source include/not_embedded.inc +# disabling it on Windows as chmod semantics that we need in test-case +# is not same as on Windows given the limited ACL bits available on Windows. +# Aim of the TC is still being served by keep it enabled on other platforms. +--source include/not_windows.inc + + +#----------------------------------------------------------------------------- +# +let $MYSQL_DATA_DIR = `select @@datadir`; +let SEARCH_FILE = $MYSQLTEST_VARDIR/log/my_restart.err; +let $args = --loose-console > $SEARCH_FILE 2>&1; + +#----------------------------------------------------------------------------- +use test; +# +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 60 +--source include/wait_until_disconnected.inc +# +--mkdir $MYSQL_DATA_DIR/tmpdata +--chmod 0400 $MYSQL_DATA_DIR/tmpdata +--error 1 +--exec $MYSQLD_CMD --innodb_data_home_dir=$MYSQL_DATA_DIR/tmpdata $args +let SEARCH_PATTERN = returned OS error 113; +--source ./include/search_pattern.inc +let SEARCH_PATTERN = The error means mysqld does not have the access rights to; +--source ./include/search_pattern.inc +# +--remove_file $SEARCH_FILE +--chmod 0777 $MYSQL_DATA_DIR/tmpdata +--rmdir $MYSQL_DATA_DIR/tmpdata +# +--echo "restarting server in normal mode" +--enable_reconnect +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect +# +# +use test; + diff --git a/mysql-test/suite/innodb/t/innodb_copy_col_in_partition.test b/mysql-test/suite/innodb/t/innodb_copy_col_in_partition.test new file mode 100644 index 00000000000..cc1c03957b0 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_copy_col_in_partition.test @@ -0,0 +1,21 @@ +--source include/have_innodb.inc + +CREATE TABLE t (id INT, a INT, b INT, KEY (a), KEY (b)) ENGINE=INNODB +PARTITION BY HASH (id) PARTITIONS 10; + +insert into t values (0,4,1); +insert into t values (6,2,5); +insert into t values (6,7,5); +insert into t values (2,4,6); +insert into t values (3,5,6); +insert into t values (1,3,9); +insert into t values (1,3,9); +insert into t values (3,4,6); +insert into t values (4,4,6); + +EXPLAIN SELECT SQL_NO_CACHE COUNT(*) FROM t WHERE a=4 AND b=6; +EXPLAIN SELECT SQL_NO_CACHE a,b FROM t WHERE a=4 AND b=6; +SELECT SQL_NO_CACHE * FROM t WHERE a=4 AND b=6 ORDER BY id; +SELECT SQL_NO_CACHE COUNT(*) FROM t WHERE a=4 AND b=6; + +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc-master.opt b/mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc-master.opt new file mode 100644 index 00000000000..fad0da2ac2e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc-master.opt @@ -0,0 +1 @@ +--innodb-autoinc-lock-mode=0 diff --git a/mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc.test b/mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc.test new file mode 100644 index 00000000000..a854c02a87d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc.test @@ -0,0 +1,47 @@ +--source include/have_debug.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/count_sessions.inc + +--echo # +--echo # Bug #21983865 UNEXPECTED DEADLOCK WITH INNODB_AUTOINC_LOCK_MODE=0 +--echo # + +create table t1(f1 int not null auto_increment primary key) engine=innodb; + +--echo # Hold autoinc_lock on table t1 from connection con1 +connect (con1, localhost, root); +set debug_sync='ib_after_row_insert SIGNAL others WAIT_FOR continue_others'; +--send insert into t1 values(NULL) + +connection default; +--echo # Create 40 connections and make it to wait for autoinc_lock on table t1. +--disable_query_log +set debug_sync='now WAIT_FOR others'; +let $1=2; +while ($1 < 40) { + connect (con$1,localhost,root); + --send insert into t1 values(NULL) + inc $1; + connection default; +} + +connect (con40,localhost,root); +--enable_query_log +--echo # Release the auto_inc lock on table t1 for connection con1 +set debug_sync='now SIGNAL continue_others'; + +--echo # Now all 40 connections can finish the insert operation on t1. +let $1=1; +connection default; +disconnect con40; +while ($1 < 40) { + connection con$1; + --reap + connection default; + disconnect con$1; + inc $1; +} + +drop table t1; +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb_file_format-master.opt b/mysql-test/suite/innodb/t/innodb_file_format-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_file_format-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/suite/innodb/t/innodb_file_limit_check-master.opt b/mysql-test/suite/innodb/t/innodb_file_limit_check-master.opt new file mode 100644 index 00000000000..e5636da0796 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_file_limit_check-master.opt @@ -0,0 +1 @@ +--no-console --log-error=$MYSQLTEST_VARDIR/tmp/innodb_file_limit.err diff --git a/mysql-test/suite/innodb/t/innodb_file_limit_check.test b/mysql-test/suite/innodb/t/innodb_file_limit_check.test new file mode 100644 index 00000000000..af24bd57abc --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_file_limit_check.test @@ -0,0 +1,31 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/big_test.inc + +CALL mtr.add_suppression("innodb_open_files should not be greater than the open_files_limit."); + +CREATE TABLE t1 (a INT)ENGINE=INNODB PARTITION BY HASH(a) PARTITIONS 1024; + +let $innodb_file_limit= `SELECT @@open_files_limit`; +inc $innodb_file_limit; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc +--enable_reconnect + +--exec echo "restart: --innodb_open_files=$innodb_file_limit --no-console --log-error=$MYSQLTEST_VARDIR/tmp/innodb_file_limit.err" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/innodb_file_limit.err; +let SEARCH_PATTERN= innodb_open_files should not be greater than the open_files_limit.; +--source include/search_pattern_in_file.inc + +SELECT 1 UNION SELECT * FROM t1 UNION SELECT * FROM t1 UNION +SELECT * FROM t1 UNION SELECT * FROM t1 UNION SELECT * FROM +t1; + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery.test b/mysql-test/suite/innodb/t/innodb_force_recovery.test new file mode 100644 index 00000000000..9912a907067 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_force_recovery.test @@ -0,0 +1,228 @@ +# Not supported in embedded +--source include/not_embedded.inc + +# This test case needs InnoDB. +-- source include/have_innodb.inc + +call mtr.add_suppression('InnoDB: Failed to find tablespace for table \'".*".".*"\' in the cache'); +call mtr.add_suppression('InnoDB: Allocated tablespace [0-9]+, old maximum was [0-9]+'); + +create table t1(f1 int not null, f2 int not null, index idx(f2))engine=innodb; +create table t2(f1 int not null, f2 int not null, index idx(f2))engine=innodb; +insert into t1 values(1, 2); +insert into t2 values(1, 2); + +SET GLOBAL innodb_fast_shutdown = 0; + +# Restart the server in force recovery mode +--echo # Stop server + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Request shutdown +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart:--innodb-force-recovery=4" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +select * from t1; + +--error ER_OPEN_AS_READONLY +insert into t1 values(2, 3); + +--error ER_INNODB_READ_ONLY +alter table t1 add f3 int not null, algorithm=copy; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t1 add f3 int not null, algorithm=inplace; + +--error ER_INNODB_READ_ONLY +drop index idx on t1; + +--error ER_OPEN_AS_READONLY +update t1 set f1=3 where f2=2; + +--error ER_INNODB_READ_ONLY +create table t3(f1 int not null)engine=innodb; + +--error ER_BAD_TABLE_ERROR +drop table t3; + +--error ER_ERROR_ON_RENAME +rename table t1 to t3; + +--error ER_OPEN_AS_READONLY +truncate table t1; + +drop table t1; +show tables; + +# Restart the server in force recovery mode +--echo # Stop server + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Request shutdown +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart:--innodb-force-recovery=5" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +select * from t2; + +--error ER_OPEN_AS_READONLY +insert into t2 values(2, 3); + +--error ER_INNODB_READ_ONLY +alter table t2 add f3 int not null, algorithm=copy; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t2 add f3 int not null, algorithm=inplace; + +--error ER_INNODB_READ_ONLY +drop index idx on t2; + +--error ER_OPEN_AS_READONLY +update t2 set f1=3 where f2=2; + +--error ER_INNODB_READ_ONLY +create table t4(f1 int not null)engine=innodb; + +--error ER_BAD_TABLE_ERROR +drop table t4; + +--error ER_ERROR_ON_RENAME +rename table t2 to t3; + +--error ER_OPEN_AS_READONLY +truncate table t2; + +--error ER_BAD_TABLE_ERROR +drop table t2; +show tables; + +# Restart the server in force recovery mode +--echo # Stop server + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Request shutdown +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart:--innodb-force-recovery=6" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +select * from t2; + +--error ER_CANT_LOCK +insert into t2 values(2, 3); + +--error ER_CANT_LOCK +alter table t2 add f3 int not null, algorithm=copy; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +alter table t2 add f3 int not null, algorithm=inplace; + +--error ER_CANT_LOCK +drop index idx on t2; + +--error ER_CANT_LOCK +update t2 set f1=3 where f2=2; + +--error ER_INNODB_READ_ONLY +create table t4(f1 int not null)engine=innodb; + +--error ER_BAD_TABLE_ERROR +drop table t4; + +--error ER_ERROR_ON_RENAME +rename table t2 to t3; + +--error ER_OPEN_AS_READONLY +truncate table t2; + +--error ER_BAD_TABLE_ERROR +drop table t2; +show tables; + +# Restart the server without force recovery mode +--echo # Stop server + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Request shutdown +-- send_shutdown + +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +drop table t2; +show tables; diff --git a/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test b/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test new file mode 100644 index 00000000000..d1c7c22fe4e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test @@ -0,0 +1,174 @@ +# +# Test that user data is correctly "visualized" in +# INFORMATION_SCHEMA.innodb_locks.lock_data +# + +-- source include/have_innodb.inc + +# Make sure the locks keep waiting until they are released, +# even on a busy system. +SET GLOBAL innodb_lock_wait_timeout=600; + +-- disable_warnings +DROP TABLE IF EXISTS t_min, t_max; +-- enable_warnings + +let $table_def = +( + c01 TINYINT, + c02 TINYINT UNSIGNED, + c03 SMALLINT, + c04 SMALLINT UNSIGNED, + c05 MEDIUMINT, + c06 MEDIUMINT UNSIGNED, + c07 INT, + c08 INT UNSIGNED, + c09 BIGINT, + c10 BIGINT UNSIGNED, + PRIMARY KEY(c01, c02, c03, c04, c05, c06, c07, c08, c09, c10) +) ENGINE=INNODB; + +-- eval CREATE TABLE t_min $table_def; +INSERT INTO t_min VALUES +(-128, 0, + -32768, 0, + -8388608, 0, + -2147483648, 0, + -9223372036854775808, 0); + +-- eval CREATE TABLE t_max $table_def; +INSERT INTO t_max VALUES +(127, 255, + 32767, 65535, + 8388607, 16777215, + 2147483647, 4294967295, + 9223372036854775807, 18446744073709551615); + +CREATE TABLE ```t'\"_str` ( + c1 VARCHAR(32), + c2 VARCHAR(32), + c3 VARCHAR(32), + c4 VARCHAR(32), + c5 VARCHAR(32), + c6 VARCHAR(32), + c7 VARCHAR(32), + PRIMARY KEY(c1, c2, c3, c4, c5, c6, c7) +) ENGINE=INNODB; +INSERT INTO ```t'\"_str` VALUES +('1', 'abc', '''abc', 'abc''', 'a''bc', 'a''bc''', '''abc'''''); +INSERT INTO ```t'\"_str` VALUES +('2', 'abc', '"abc', 'abc"', 'a"bc', 'a"bc"', '"abc""'); +INSERT INTO ```t'\"_str` VALUES +('3', 'abc', '\\abc', 'abc\\', 'a\\bc', 'a\\bc\\', '\\abc\\\\'); +INSERT INTO ```t'\"_str` VALUES +('4', 'abc', 0x00616263, 0x61626300, 0x61006263, 0x6100626300, 0x610062630000); + +-- source include/count_sessions.inc + +-- connect (con_lock,localhost,root,,) +-- connect (con_min_trylock,localhost,root,,) +-- connect (con_max_trylock,localhost,root,,) +-- connect (con_str_insert_supremum,localhost,root,,) +-- connect (con_str_lock_row1,localhost,root,,) +-- connect (con_str_lock_row2,localhost,root,,) +-- connect (con_str_lock_row3,localhost,root,,) +-- connect (con_str_lock_row4,localhost,root,,) +-- connect (con_verify_innodb_locks,localhost,root,,) + +-- connection con_lock +SET autocommit=0; +SELECT * FROM t_min FOR UPDATE; +SELECT * FROM t_max FOR UPDATE; +SELECT * FROM ```t'\"_str` FOR UPDATE; + +-- connection con_min_trylock +-- send +SELECT * FROM t_min FOR UPDATE; + +-- connection con_max_trylock +-- send +SELECT * FROM t_max FOR UPDATE; + +-- connection con_str_insert_supremum +-- send +INSERT INTO ```t'\"_str` VALUES +('z', 'z', 'z', 'z', 'z', 'z', 'z'); + +-- connection con_str_lock_row1 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '1' FOR UPDATE; + +-- connection con_str_lock_row2 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '2' FOR UPDATE; + +-- connection con_str_lock_row3 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE; + +-- connection con_str_lock_row4 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE; + +-- connection con_verify_innodb_locks +# Wait for the above queries to execute before continuing. +# Without this, it sometimes happens that the SELECT from innodb_locks +# executes before some of them, resulting in less than expected number +# of rows being selected from innodb_locks. If there is a bug and there +# are no 14 rows in innodb_locks then this test will fail with timeout. +# Notice that if we query INNODB_LOCKS more often than once per 0.1 sec +# then its contents will never change because the cache from which it is +# filled is updated only if it has not been read for 0.1 seconds. See +# CACHE_MIN_IDLE_TIME_US in trx/trx0i_s.c. +let $cnt=10; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 14 FROM INFORMATION_SCHEMA.INNODB_LOCKS`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 0.2; + dec $cnt; + } +} +if (!$success) +{ + -- echo Timeout waiting for rows in INNODB_LOCKS to appear +} + +SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data +FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data; + +SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS +GROUP BY lock_table; + +set @save_sql_mode = @@sql_mode; +SET SQL_MODE='ANSI_QUOTES'; +SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS +GROUP BY lock_table; +SET @@sql_mode=@save_sql_mode; + +# Release all the locks; +-- connection con_lock +COMMIT; + +-- connection default + +-- disconnect con_lock +-- disconnect con_min_trylock +-- disconnect con_max_trylock +-- disconnect con_str_insert_supremum +-- disconnect con_str_lock_row1 +-- disconnect con_str_lock_row2 +-- disconnect con_str_lock_row3 +-- disconnect con_str_lock_row4 +-- disconnect con_verify_innodb_locks + +DROP TABLE t_min, t_max, ```t'\"_str`; + +-- source include/wait_until_count_sessions.inc + +SET GLOBAL innodb_lock_wait_timeout=default; diff --git a/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test b/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test new file mode 100644 index 00000000000..12183e61017 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test @@ -0,0 +1,100 @@ +# +# Test that transaction data is correctly "visualized" in +# INFORMATION_SCHEMA.INNODB_TRX +# + +# Make sure the locks keep waiting until they are released, +# even on a busy system. +SET GLOBAL innodb_lock_wait_timeout=600; + +DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; + +-- disable_warnings +DROP TABLE IF EXISTS t1; +-- enable_warnings + +CREATE TABLE t1 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; + +INSERT INTO t1 VALUES +(1,2),(2,4),(3,6),(4,8); + +CREATE TABLE t2 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01), + FOREIGN KEY fk1 (c02) REFERENCES t1 (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; + +INSERT INTO t2 VALUES +(1,1),(2,2),(3,3); + +-- source include/count_sessions.inc + +-- connect (con_trx,localhost,root,,) +-- connect (con_verify_innodb_trx,localhost,root,,) + +-- connection con_trx +SET autocommit=0; +INSERT INTO t1 VALUES (5,10); +SELECT * FROM t1 FOR UPDATE; + +let $wait_timeout= 300; +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc + +-- connection con_verify_innodb_trx +SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, +trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, +trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection con_trx +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 0; +SET UNIQUE_CHECKS = 0; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +INSERT INTO t1 VALUES (6,12); + +let $wait_timeout= 300; +let $wait_condition= + SELECT trx_unique_checks = 0 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc + +-- connection con_verify_innodb_trx +SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection con_trx +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 1; +SET UNIQUE_CHECKS = 1; +BEGIN; +-- error 1452 +INSERT INTO t2 VALUES (4,10); + +let $wait_timeout= 300; +let $wait_condition= + SELECT trx_unique_checks = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc + +-- connection con_verify_innodb_trx +SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection default + +-- disconnect con_trx +-- disconnect con_verify_innodb_trx + +DROP TABLE t2; +DROP TABLE t1; + +-- source include/wait_until_count_sessions.inc + +SET GLOBAL innodb_lock_wait_timeout=default; diff --git a/mysql-test/suite/innodb/t/innodb_io_pf.test b/mysql-test/suite/innodb/t/innodb_io_pf.test new file mode 100644 index 00000000000..8d4b71ff21c --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_io_pf.test @@ -0,0 +1,15 @@ +--source include/have_innodb.inc +--source include/have_perfschema.inc +--source include/not_embedded.inc + +USE test; +CREATE TABLE t1(id INT); +INSERT INTO t1 VALUES(1),(2),(3),(4),(5); +SELECT * FROM t1; + +USE performance_schema; +--replace_column 2 5 +SELECT EVENT_NAME,COUNT_STAR FROM performance_schema.file_summary_by_event_name + WHERE EVENT_NAME like "%inno%"; +USE test; +DROP table t1; diff --git a/mysql-test/suite/innodb/t/innodb_misc1-master.opt b/mysql-test/suite/innodb/t/innodb_misc1-master.opt new file mode 100644 index 00000000000..4901efb416c --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_misc1-master.opt @@ -0,0 +1 @@ +--binlog_cache_size=32768 --innodb_lock_wait_timeout=1 diff --git a/mysql-test/suite/innodb/t/innodb_misc1.test b/mysql-test/suite/innodb/t/innodb_misc1.test new file mode 100644 index 00000000000..e4d200fe815 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_misc1.test @@ -0,0 +1,1171 @@ +-- source include/have_innodb.inc + +let $MYSQLD_DATADIR= `select @@datadir`; + +# Save the original values of some variables in order to be able to +# estimate how much they have changed during the tests. Previously this +# test assumed that e.g. rows_deleted is 0 here and after deleting 23 +# rows it expected that rows_deleted will be 23. Now we do not make +# assumptions about the values of the variables at the beginning, e.g. +# rows_deleted should be 23 + "rows_deleted before the test". This allows +# the test to be run multiple times without restarting the mysqld server. +# See Bug#43309 Test main.innodb can't be run twice +-- disable_query_log +SET @innodb_thread_concurrency_orig = @@innodb_thread_concurrency; +-- enable_query_log + +--disable_warnings +drop table if exists t1,t2,t3,t4; +drop database if exists mysqltest; +--enable_warnings + +# InnoDB specific varchar tests +create table t1 (v varchar(16384)) engine=innodb; +drop table t1; + +# +# BUG#11039 Wrong key length in min() +# + +create table t1 (a char(1), b char(1), key(a, b)) engine=innodb; +insert into t1 values ('8', '6'), ('4', '7'); +select min(a) from t1; +select min(b) from t1 where a='8'; +drop table t1; + +# +# Bug #11080 & #11005 Multi-row REPLACE fails on a duplicate key error +# + +CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)) ENGINE=innodb; +insert into t1 (b) values (1); +replace into t1 (b) values (2), (1), (3); +select * from t1; +truncate table t1; +insert into t1 (b) values (1); +replace into t1 (b) values (2); +replace into t1 (b) values (1); +replace into t1 (b) values (3); +select * from t1; +drop table t1; + +create table t1 (rowid int not null auto_increment, val int not null,primary +key (rowid), unique(val)) engine=innodb; +replace into t1 (val) values ('1'),('2'); +replace into t1 (val) values ('1'),('2'); +--error ER_DUP_ENTRY +insert into t1 (val) values ('1'),('2'); +select * from t1; +drop table t1; + +# +# Test that update does not change internal auto-increment value +# + +create table t1 (a int not null auto_increment primary key, val int) engine=InnoDB; +insert into t1 (val) values (1); +update t1 set a=2 where a=1; +# We should get the following error because InnoDB does not update the counter +--error ER_DUP_ENTRY +insert into t1 (val) values (1); +select * from t1; +drop table t1; +# +# Bug #10465 +# + +--disable_warnings +CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)) ENGINE=INNODB; +--enable_warnings +INSERT INTO t1 (GRADE) VALUES (151),(252),(343); +SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300; +SELECT GRADE FROM t1 WHERE GRADE= 151; +DROP TABLE t1; + +# +# Bug #12340 multitable delete deletes only one record +# +create table t1 (f1 varchar(10), f2 varchar(10), primary key (f1,f2)) engine=innodb; +create table t2 (f3 varchar(10), f4 varchar(10), key (f4)) engine=innodb; +insert into t2 values ('aa','cc'); +insert into t1 values ('aa','bb'),('aa','cc'); +delete t1 from t1,t2 where f1=f3 and f4='cc'; +select * from t1; +drop table t1,t2; + +# +# Test that the slow TRUNCATE implementation resets autoincrement columns +# (bug #11946) +# + +CREATE TABLE t1 ( +id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( +id INTEGER NOT NULL, +FOREIGN KEY (id) REFERENCES t1 (id) +) ENGINE=InnoDB; + +INSERT INTO t1 (id) VALUES (NULL); +SELECT * FROM t1; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE t1; +INSERT INTO t1 (id) VALUES (NULL); +SELECT * FROM t1; + +# continued from above; test that doing a slow TRUNCATE on a table with 0 +# rows resets autoincrement columns +DELETE FROM t1; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE t1; +INSERT INTO t1 (id) VALUES (NULL); +SELECT * FROM t1; +DROP TABLE t2, t1; + +# Test that foreign keys in temporary tables are not accepted (bug #12084) +CREATE TABLE t1 +( + id INT PRIMARY KEY +) ENGINE=InnoDB; + +--error ER_CANNOT_ADD_FOREIGN +CREATE TEMPORARY TABLE t2 +( + id INT NOT NULL PRIMARY KEY, + b INT, + FOREIGN KEY (b) REFERENCES test.t1(id) +) ENGINE=InnoDB; +DROP TABLE t1; + +# +# Test that index column max sizes are honored (bug #13315) +# + +# prefix index +create table t1 (col1 varchar(2000), index (col1(767))) + character set = latin1 engine = innodb; + +# normal indexes +create table t2 (col1 char(255), index (col1)) + character set = latin1 engine = innodb; +create table t3 (col1 binary(255), index (col1)) + character set = latin1 engine = innodb; +create table t4 (col1 varchar(767), index (col1)) + character set = latin1 engine = innodb; +create table t5 (col1 varchar(767) primary key) + character set = latin1 engine = innodb; +create table t6 (col1 varbinary(767) primary key) + character set = latin1 engine = innodb; +create table t7 (col1 text, index(col1(767))) + character set = latin1 engine = innodb; +create table t8 (col1 blob, index(col1(767))) + character set = latin1 engine = innodb; + +# multi-column tests can be found in innodb_16k, innodb_8k & innodb_4k + +drop table t1, t2, t3, t4, t5, t6, t7, t8; + +# these should have their index length trimmed +create table t1 (col1 varchar(768), index(col1)) + character set = latin1 engine = innodb; +create table t2 (col1 varbinary(768), index(col1)) + character set = latin1 engine = innodb; +create table t3 (col1 text, index(col1(768))) + character set = latin1 engine = innodb; +create table t4 (col1 blob, index(col1(768))) + character set = latin1 engine = innodb; + +show create table t1; + +drop table t1, t2, t3, t4; + +# these should be refused +--error ER_TOO_LONG_KEY +create table t1 (col1 varchar(768) primary key) + character set = latin1 engine = innodb; +--error ER_TOO_LONG_KEY +create table t2 (col1 varbinary(768) primary key) + character set = latin1 engine = innodb; +--error ER_TOO_LONG_KEY +create table t3 (col1 text, primary key(col1(768))) + character set = latin1 engine = innodb; +--error ER_TOO_LONG_KEY +create table t4 (col1 blob, primary key(col1(768))) + character set = latin1 engine = innodb; + +# +# Test improved foreign key error messages (bug #3443) +# + +CREATE TABLE t1 +( + id INT PRIMARY KEY +) ENGINE=InnoDB; + +CREATE TABLE t2 +( + v INT, + CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id) +) ENGINE=InnoDB; + +--error 1452 +INSERT INTO t2 VALUES(2); + +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1); + +--error 1451 +DELETE FROM t1 WHERE id = 1; + +--error 1217 +DROP TABLE t1; + +SET FOREIGN_KEY_CHECKS=0; +DROP TABLE t1; +SET FOREIGN_KEY_CHECKS=1; + +--error 1452 +INSERT INTO t2 VALUES(3); + +DROP TABLE t2; +# +# Test that checksum table uses a consistent read Bug #12669 +# +connect (a,localhost,root,,); +connect (b,localhost,root,,); +connection a; +create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1; +insert into t1 values (1),(2); +set autocommit=0; +checksum table t1; +connection b; +insert into t1 values(3); +connection a; +# +# Here checksum should not see insert +# +checksum table t1; +connection a; +commit; +checksum table t1; +commit; +drop table t1; +# +# autocommit = 1 +# +connection a; +create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1; +insert into t1 values (1),(2); +set autocommit=1; +checksum table t1; +connection b; +set autocommit=1; +insert into t1 values(3); +connection a; +# +# Here checksum sees insert +# +checksum table t1; +drop table t1; + +connection default; +disconnect a; +disconnect b; + +# tests for bugs #9802 and #13778 + +# test that FKs between invalid types are not accepted + +set foreign_key_checks=0; +create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; +--error ER_CANNOT_ADD_FOREIGN +create table t1(a char(10) primary key, b varchar(20)) engine = innodb; +set foreign_key_checks=1; +drop table t2; + +# test that FKs between different charsets are not accepted in CREATE even +# when f_k_c is 0 + +set foreign_key_checks=0; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +--error ER_CANNOT_ADD_FOREIGN +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; +set foreign_key_checks=1; +drop table t1; + +# test that invalid datatype conversions with ALTER are not allowed + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb; +create table t1(a varchar(10) primary key) engine = innodb; +-- error 1025,1025 +alter table t1 modify column a int; +set foreign_key_checks=1; +drop table t2,t1; + +# test that charset conversions with ALTER are allowed when f_k_c is 0 + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +alter table t1 convert to character set utf8; +set foreign_key_checks=1; +drop table t2,t1; + +# test that RENAME does not allow invalid charsets when f_k_c is 0 + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; +# Embedded server doesn't chdir to data directory +--replace_result $MYSQLD_DATADIR ./ master-data/ '' +-- error 1025 +rename table t3 to t1; +set foreign_key_checks=1; +drop table t2,t3; + +# test that foreign key errors are reported correctly (Bug #15550) + +create table t1(a int primary key) row_format=redundant engine=innodb; +create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb; +create table t3(a int primary key) row_format=compact engine=innodb; +create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb; + +insert into t1 values(1); +insert into t3 values(1); +-- error 1452 +insert into t2 values(2); +-- error 1452 +insert into t4 values(2); +insert into t2 values(1); +insert into t4 values(1); +-- error 1451 +update t1 set a=2; +-- error 1452 +update t2 set a=2; +-- error 1451 +update t3 set a=2; +-- error 1452 +update t4 set a=2; +-- error ER_TRUNCATE_ILLEGAL_FK +truncate t1; +-- error ER_TRUNCATE_ILLEGAL_FK +truncate t3; +truncate t2; +truncate t4; +-- error ER_TRUNCATE_ILLEGAL_FK +truncate t1; +-- error ER_TRUNCATE_ILLEGAL_FK +truncate t3; + +drop table t4,t3,t2,t1; + +# +# Test that we can create a large (>1K) key +# Moved to innodb_16k, innodb_8k, and innodb_4k +# since each page size has its own maximum key length. +# + +# test the padding of BINARY types and collations (Bug #14189) + +create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb; +create table t2 (s1 binary(2),primary key (s1)) engine=innodb; +create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb; +create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb; + +insert into t1 values (0x41),(0x4120),(0x4100); +-- error ER_DUP_ENTRY +insert into t2 values (0x41),(0x4120),(0x4100); +insert into t2 values (0x41),(0x4120); +-- error ER_DUP_ENTRY +insert into t3 values (0x41),(0x4120),(0x4100); +insert into t3 values (0x41),(0x4100); +-- error ER_DUP_ENTRY +insert into t4 values (0x41),(0x4120),(0x4100); +insert into t4 values (0x41),(0x4100); +select hex(s1) from t1; +select hex(s1) from t2; +select hex(s1) from t3; +select hex(s1) from t4; +drop table t1,t2,t3,t4; + +create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb; +create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb; + +insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42); +-- error 1452 +insert into t2 values(0x42); +insert into t2 values(0x41); +select hex(s1) from t2; +update t1 set s1=0x123456 where a=2; +select hex(s1) from t2; +-- error 1451 +update t1 set s1=0x12 where a=1; +-- error 1451 +update t1 set s1=0x12345678 where a=1; +-- error 1451 +update t1 set s1=0x123457 where a=1; +update t1 set s1=0x1220 where a=1; +select hex(s1) from t2; +update t1 set s1=0x1200 where a=1; +select hex(s1) from t2; +update t1 set s1=0x4200 where a=1; +select hex(s1) from t2; +-- error 1451 +delete from t1 where a=1; +delete from t1 where a=2; +update t2 set s1=0x4120; +-- error 1451 +delete from t1; +delete from t1 where a!=3; +select a,hex(s1) from t1; +select hex(s1) from t2; + +drop table t2,t1; + +create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb; +create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb; + +insert into t1 values(1,0x4100),(2,0x41); +insert into t2 values(0x41); +select hex(s1) from t2; +update t1 set s1=0x1234 where a=1; +select hex(s1) from t2; +update t1 set s1=0x12 where a=2; +select hex(s1) from t2; +delete from t1 where a=1; +-- error 1451 +delete from t1 where a=2; +select a,hex(s1) from t1; +select hex(s1) from t2; + +drop table t2,t1; +# Ensure that <tablename>_ibfk_0 is not mistreated as a +# generated foreign key identifier. (Bug #16387) + +CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB; +CREATE TABLE t2(a INT) ENGINE=InnoDB; +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a); +ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1; +ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a); +ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0; +SHOW CREATE TABLE t2; +DROP TABLE t2,t1; + +# +# Test case for bug #16229: MySQL/InnoDB uses full explicit table locks in trigger processing +# +## the following cannot be tested after the introduction of metadata locks +## because the create trigger command blocks and waits for connection b to +## commit +## begin disabled_mdl +#connect (a,localhost,root,,); +#connect (b,localhost,root,,); +#connection a; +#create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb; +#insert into t1(a) values (1),(2),(3); +#commit; +#delimiter |; +## in 5.5+, this needs to be created before the UPDATE due to meta-data locking +#create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end | +#delimiter ;| +#connection b; +#set autocommit = 0; +#update t1 set b = 5 where a = 2; +#connection a; +#set autocommit = 0; +#connection a; +#insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100), +#(11),(21),(31),(41),(51),(61),(71),(81),(91),(101), +#(12),(22),(32),(42),(52),(62),(72),(82),(92),(102), +#(13),(23),(33),(43),(53),(63),(73),(83),(93),(103), +#(14),(24),(34),(44),(54),(64),(74),(84),(94),(104); +#connection b; +#commit; +#connection a; +#commit; +#drop trigger t1t; +#drop table t1; +#disconnect a; +#disconnect b; +## +## Another trigger test +## +#connect (a,localhost,root,,); +#connect (b,localhost,root,,); +#connection a; +#create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb; +#create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb; +#create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb; +#create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb; +#create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb; +#insert into t1(a) values (1),(2),(3); +#insert into t2(a) values (1),(2),(3); +#insert into t3(a) values (1),(2),(3); +#insert into t4(a) values (1),(2),(3); +#insert into t3(a) values (5),(7),(8); +#insert into t4(a) values (5),(7),(8); +#insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12); +# +#delimiter |; +#create trigger t1t before insert on t1 for each row begin +# INSERT INTO t2 SET a = NEW.a; +#end | +# +#create trigger t2t before insert on t2 for each row begin +# DELETE FROM t3 WHERE a = NEW.a; +#end | +# +#create trigger t3t before delete on t3 for each row begin +# UPDATE t4 SET b = b + 1 WHERE a = OLD.a; +#end | +# +#create trigger t4t before update on t4 for each row begin +# UPDATE t5 SET b = b + 1 where a = NEW.a; +#end | +#delimiter ;| +#commit; +#set autocommit = 0; +#update t1 set b = b + 5 where a = 1; +#update t2 set b = b + 5 where a = 1; +#update t3 set b = b + 5 where a = 1; +#update t4 set b = b + 5 where a = 1; +#insert into t5(a) values(20); +#connection b; +#set autocommit = 0; +#insert into t1(a) values(7); +#insert into t2(a) values(8); +#delete from t2 where a = 3; +#update t4 set b = b + 1 where a = 3; +#commit; +#connection a; +#drop trigger t1t; +#drop trigger t2t; +#drop trigger t3t; +#drop trigger t4t; +#drop table t1, t2, t3, t4, t5; +#connection default; +#disconnect a; +#disconnect b; +## end disabled_mdl + +# +# Test that cascading updates leading to duplicate keys give the correct +# error message (bug #9680) +# + +CREATE TABLE t1 ( + field1 varchar(8) NOT NULL DEFAULT '', + field2 varchar(8) NOT NULL DEFAULT '', + PRIMARY KEY (field1, field2) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY, + FOREIGN KEY (field1) REFERENCES t1 (field1) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES ('old', 'somevalu'); +INSERT INTO t1 VALUES ('other', 'anyvalue'); + +INSERT INTO t2 VALUES ('old'); +INSERT INTO t2 VALUES ('other'); + +--error ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO +UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu'; + +DROP TABLE t2; +DROP TABLE t1; + +# +# Bug#18477 - MySQL/InnoDB Ignoring Foreign Keys in ALTER TABLE +# +create table t1 ( + c1 bigint not null, + c2 bigint not null, + primary key (c1), + unique key (c2) +) engine=innodb; +# +create table t2 ( + c1 bigint not null, + primary key (c1) +) engine=innodb; +# +alter table t1 add constraint c2_fk foreign key (c2) + references t2(c1) on delete cascade; +show create table t1; +# +alter table t1 drop foreign key c2_fk; +show create table t1; +# +drop table t1, t2; + +# +# Bug #14360: problem with intervals +# + +create table t1(a date) engine=innodb; +create table t2(a date, key(a)) engine=innodb; +insert into t1 values('2005-10-01'); +insert into t2 values('2005-10-01'); +select * from t1, t2 + where t2.a between t1.a - interval 2 day and t1.a + interval 2 day; +drop table t1, t2; + +create table t1 (id int not null, f_id int not null, f int not null, +primary key(f_id, id)) engine=innodb; +create table t2 (id int not null,s_id int not null,s varchar(200), +primary key(id)) engine=innodb; +INSERT INTO t1 VALUES (8, 1, 3); +INSERT INTO t1 VALUES (1, 2, 1); +INSERT INTO t2 VALUES (1, 0, ''); +INSERT INTO t2 VALUES (8, 1, ''); +commit; +DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id) +WHERE mm.id IS NULL; +select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id) +where mm.id is null lock in share mode; +drop table t1,t2; + +# +# Test case where X-locks on unused rows should be released in a +# update (because READ COMMITTED isolation level) +# + +connect (a,localhost,root,,); +connect (b,localhost,root,,); +connection a; +create table t1(a int not null, b int, primary key(a)) engine=innodb; +insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3); +commit; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +update t1 set b = 5 where b = 1; +connection b; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +# +# X-lock to record (7,3) should be released in a update +# +select * from t1 where a = 7 and b = 3 for update; +connection a; +commit; +connection b; +commit; +drop table t1; +connection default; +disconnect a; +disconnect b; + +# +# Test case where no locks should be released (because we are not +# using READ COMMITTED isolation level) +# + +connect (a,localhost,root,,); +connect (b,localhost,root,,); +connection a; +create table t1(a int not null, b int, primary key(a)) engine=innodb; +insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2); +commit; +set autocommit = 0; +select * from t1 lock in share mode; +update t1 set b = 5 where b = 1; +connection b; +set autocommit = 0; +# +# S-lock to records (2,2),(4,2), and (6,2) should not be released in a update +# +--error 1205 +select * from t1 where a = 2 and b = 2 for update; +# +# X-lock to record (1,1),(3,1),(5,1) should not be released in a update +# +--error 1205 +connection a; +commit; +connection b; +commit; +connection default; +disconnect a; +disconnect b; +drop table t1; + +# +# Consistent read should be used in following selects +# +# 1) INSERT INTO ... SELECT +# 2) UPDATE ... = ( SELECT ...) +# 3) CREATE ... SELECT + +connect (a,localhost,root,,); +connect (b,localhost,root,,); +connection a; +create table t1(a int not null, b int, primary key(a)) engine=innodb; +insert into t1 values (1,2),(5,3),(4,2); +create table t2(d int not null, e int, primary key(d)) engine=innodb; +insert into t2 values (8,6),(12,1),(3,1); +commit; +set autocommit = 0; +select * from t2 for update; +connection b; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +insert into t1 select * from t2; +update t1 set b = (select e from t2 where a = d); +create table t3(d int not null, e int, primary key(d)) engine=innodb +select * from t2; +commit; +connection a; +commit; +connection default; +disconnect a; +disconnect b; +drop table t1, t2, t3; + +# +# Consistent read should not be used if +# +# (a) isolation level is serializable OR +# (b) select ... lock in share mode OR +# (c) select ... for update +# +# in following queries: +# +# 1) INSERT INTO ... SELECT +# 2) UPDATE ... = ( SELECT ...) +# 3) CREATE ... SELECT + +connect (a,localhost,root,,); +connect (b,localhost,root,,); +connect (c,localhost,root,,); +connect (d,localhost,root,,); +connect (e,localhost,root,,); +connect (f,localhost,root,,); +connect (g,localhost,root,,); +connect (h,localhost,root,,); +connect (i,localhost,root,,); +connect (j,localhost,root,,); +connection a; +create table t1(a int not null, b int, primary key(a)) engine=innodb; +insert into t1 values (1,2),(5,3),(4,2); +create table t2(a int not null, b int, primary key(a)) engine=innodb; +insert into t2 values (8,6),(12,1),(3,1); +create table t3(d int not null, b int, primary key(d)) engine=innodb; +insert into t3 values (8,6),(12,1),(3,1); +create table t5(a int not null, b int, primary key(a)) engine=innodb; +insert into t5 values (1,2),(5,3),(4,2); +create table t6(d int not null, e int, primary key(d)) engine=innodb; +insert into t6 values (8,6),(12,1),(3,1); +create table t8(a int not null, b int, primary key(a)) engine=innodb; +insert into t8 values (1,2),(5,3),(4,2); +create table t9(d int not null, e int, primary key(d)) engine=innodb; +insert into t9 values (8,6),(12,1),(3,1); +commit; +set autocommit = 0; +select * from t2 for update; +connection b; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +--send +insert into t1 select * from t2; +connection c; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +--send +update t3 set b = (select b from t2 where a = d); +connection d; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +--send +create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2; +connection e; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--send +insert into t5 (select * from t2 lock in share mode); +connection f; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--send +update t6 set e = (select b from t2 where a = d lock in share mode); +connection g; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--send +create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode; +connection h; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--send +insert into t8 (select * from t2 for update); +connection i; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--send +update t9 set e = (select b from t2 where a = d for update); +connection j; +SET binlog_format='MIXED'; +set autocommit = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--send +create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update; + +connection b; +--error 1205 +reap; + +connection c; +--error 1205 +reap; + +connection d; +--error 1205 +reap; + +connection e; +--error 1205 +reap; + +connection f; +--error 1205 +reap; + +connection g; +--error 1205 +reap; + +connection h; +--error 1205 +reap; + +connection i; +--error 1205 +reap; + +connection j; +--error ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT +reap; + +connection a; +commit; + +connection default; +disconnect a; +disconnect b; +disconnect c; +disconnect d; +disconnect e; +disconnect f; +disconnect g; +disconnect h; +disconnect i; +disconnect j; +drop table t1, t2, t3, t5, t6, t8, t9; + +# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID" +--error ER_WRONG_COLUMN_NAME +CREATE TABLE t1 (DB_ROW_ID int) engine=innodb; + +# +# Bug #17152: Wrong result with BINARY comparison on aliased column +# + +CREATE TABLE t1 ( + a BIGINT(20) NOT NULL, + PRIMARY KEY (a) + ) ENGINE=INNODB DEFAULT CHARSET=UTF8; + +CREATE TABLE t2 ( + a BIGINT(20) NOT NULL, + b VARCHAR(128) NOT NULL, + c TEXT NOT NULL, + PRIMARY KEY (a,b), + KEY idx_t2_b_c (b,c(100)), + CONSTRAINT t_fk FOREIGN KEY (a) REFERENCES t1 (a) + ON DELETE CASCADE + ) ENGINE=INNODB DEFAULT CHARSET=UTF8; + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1, 'bar', 'vbar'); +INSERT INTO t2 VALUES (1, 'BAR2', 'VBAR'); +INSERT INTO t2 VALUES (1, 'bar_bar', 'bibi'); +INSERT INTO t2 VALUES (1, 'customer_over', '1'); + +SELECT * FROM t2 WHERE b = 'customer_over'; +SELECT * FROM t2 WHERE BINARY b = 'customer_over'; +SELECT DISTINCT p0.a FROM t2 p0 WHERE p0.b = 'customer_over'; +/* Bang: Empty result set, above was expected: */ +SELECT DISTINCT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over'; +SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over'; + +drop table t2, t1; + +# +# Test optimize on table with open transaction +# + +CREATE TABLE t1 ( a int ) ENGINE=innodb; +BEGIN; +INSERT INTO t1 VALUES (1); +OPTIMIZE TABLE t1; +DROP TABLE t1; + +# +# Bug #24741 (existing cascade clauses disappear when adding foreign keys) +# + +CREATE TABLE t1 (id int PRIMARY KEY, f int NOT NULL, INDEX(f)) ENGINE=InnoDB; + +CREATE TABLE t2 (id int PRIMARY KEY, f INT NOT NULL, + CONSTRAINT t2_t1 FOREIGN KEY (id) REFERENCES t1 (id) + ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB; + +ALTER TABLE t2 ADD FOREIGN KEY (f) REFERENCES t1 (f) ON +DELETE CASCADE ON UPDATE CASCADE; + +SHOW CREATE TABLE t2; +DROP TABLE t2, t1; + +# +# Bug #25927: Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns +# for which there is a foreign key constraint ON ... SET NULL. +# + +CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL; +# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on. +SET @old_sql_mode = @@sql_mode; +SET @@sql_mode = 'STRICT_TRANS_TABLES'; +--error ER_FK_COLUMN_NOT_NULL +ALTER TABLE t2 MODIFY a INT NOT NULL; +SET @@sql_mode = @old_sql_mode; +DELETE FROM t1; +DROP TABLE t2,t1; + +# +# Bug #26835: table corruption after delete+insert +# + +CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4); +DELETE FROM t1; +INSERT INTO t1 VALUES ('DDD'); +SELECT * FROM t1; +DROP TABLE t1; + +# +# Bug #23313 (AUTO_INCREMENT=# not reported back for InnoDB tables) +# Bug #21404 (AUTO_INCREMENT value reset when Adding FKEY (or ALTER?)) +# + +CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB +AUTO_INCREMENT=42; + +INSERT INTO t1 VALUES (0),(347),(0); +SELECT * FROM t1; + +SHOW CREATE TABLE t1; + +CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES(42),(347),(348); +ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id); +SHOW CREATE TABLE t1; + +DROP TABLE t1,t2; + +# +# Bug #21101 (Prints wrong error message if max row size is too large) +# +SET innodb_strict_mode=ON; +--replace_result 8126 {checked_valid} 4030 {checked_valid} 1982 {checked_valid} +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( + c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255), + c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255), + c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255), + c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255), + c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255), + c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255), + c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255), + c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255) + ) ENGINE = InnoDB; +SET innodb_strict_mode=OFF; + +# +# Bug #31860 InnoDB assumes AUTOINC values can only be positive. +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1( + id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY + ) ENGINE=InnoDB; +INSERT INTO t1 VALUES(-10); +SELECT * FROM t1; +# +# NOTE: The server really needs to be restarted at this point +# for the test to be useful. +# +# Without the fix InnoDB would trip over an assertion here. +INSERT INTO t1 VALUES(NULL); +# The next value should be 1 and not -9 or a -ve number +SELECT * FROM t1; +DROP TABLE t1; + +# +# Bug #21409 Incorrect result returned when in READ-COMMITTED with +# query_cache ON +# +CONNECT (c1,localhost,root,,); +CONNECT (c2,localhost,root,,); +CONNECTION c1; +SET binlog_format='MIXED'; +SET TX_ISOLATION='read-committed'; +SET AUTOCOMMIT=0; +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1 ( a int ) ENGINE=InnoDB; +CREATE TABLE t2 LIKE t1; +SELECT * FROM t2; +CONNECTION c2; +SET binlog_format='MIXED'; +SET TX_ISOLATION='read-committed'; +SET AUTOCOMMIT=0; +INSERT INTO t1 VALUES (1); +COMMIT; +CONNECTION c1; +SELECT * FROM t1 WHERE a=1; +DISCONNECT c1; +DISCONNECT c2; +CONNECT (c1,localhost,root,,); +CONNECT (c2,localhost,root,,); +CONNECTION c1; +SET binlog_format='MIXED'; +SET TX_ISOLATION='read-committed'; +SET AUTOCOMMIT=0; +SELECT * FROM t2; +CONNECTION c2; +SET binlog_format='MIXED'; +SET TX_ISOLATION='read-committed'; +SET AUTOCOMMIT=0; +INSERT INTO t1 VALUES (2); +COMMIT; +CONNECTION c1; +# The result set below should be the same for both selects +SELECT * FROM t1 WHERE a=2; +SELECT * FROM t1 WHERE a=2; +DROP TABLE t1; +DROP TABLE t2; +DISCONNECT c1; +DISCONNECT c2; +CONNECTION default; + +# +# Bug #29157 UPDATE, changed rows incorrect +# +create table t1 (i int, j int) engine=innodb; +insert into t1 (i, j) values (1, 1), (2, 2); +--enable_info +update t1 set j = 2; +--disable_info +drop table t1; + +# +# Bug #32440 InnoDB free space info does not appear in SHOW TABLE STATUS or +# I_S +# +set @save_innodb_file_per_table= @@global.innodb_file_per_table; +set @@global.innodb_file_per_table=0; +create table t1 (id int) comment='this is a comment' engine=innodb; +select table_comment, data_free > 0 as data_free_is_set + from information_schema.tables + where table_schema='test' and table_name = 't1'; +drop table t1; +set @@global.innodb_file_per_table= @save_innodb_file_per_table; + +# +# Bug 34920 test +# +CONNECTION default; +CREATE TABLE t1 ( + c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + c2 VARCHAR(128) NOT NULL, + PRIMARY KEY(c1) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=100; + +CREATE TABLE t2 ( + c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + c2 INT(10) UNSIGNED DEFAULT NULL, + PRIMARY KEY(c1) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=200; + +SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2'; +ALTER TABLE t2 ADD CONSTRAINT t1_t2_1 FOREIGN KEY(c1) REFERENCES t1(c1); +SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2'; +DROP TABLE t2; +DROP TABLE t1; +# End 34920 test +# +# Bug #29507 TRUNCATE shows to many rows effected +# +CONNECTION default; +CREATE TABLE t1 (c1 int default NULL, + c2 int default NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +--enable_info +TRUNCATE TABLE t1; + +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +TRUNCATE TABLE t1; + +--disable_info +DROP TABLE t1; +# +# Bug#35537 Innodb doesn't increment handler_update and handler_delete. +# +-- disable_query_log +-- disable_result_log + +CONNECT (c1,localhost,root,,); + +DROP TABLE IF EXISTS bug35537; +CREATE TABLE bug35537 ( + c1 int +) ENGINE=InnoDB; + +INSERT INTO bug35537 VALUES (1); + +-- enable_result_log + +SHOW SESSION STATUS LIKE 'Handler_update%'; +SHOW SESSION STATUS LIKE 'Handler_delete%'; + +UPDATE bug35537 SET c1 = 2 WHERE c1 = 1; +DELETE FROM bug35537 WHERE c1 = 2; + +SHOW SESSION STATUS LIKE 'Handler_update%'; +SHOW SESSION STATUS LIKE 'Handler_delete%'; + +DROP TABLE bug35537; + +DISCONNECT c1; +CONNECTION default; + +SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; diff --git a/mysql-test/suite/innodb/t/innodb_page_size_func.test b/mysql-test/suite/innodb/t/innodb_page_size_func.test new file mode 100644 index 00000000000..47772f8e4ec --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_page_size_func.test @@ -0,0 +1,296 @@ +# Purpose of this test: +# Check that server and InnoDB behave correct and give the right messages in +# case it is tried to restart the server with +# - plain wrong +# - too small +# - unsupported between too small and too high +# - too high +# - legal but not to the size during first server startup fitting +# innodb page size. So every restart attempt with such a value +# has to fail. +# +# This test should pass with calls of mtr and the following assignments +# --mysqld=--innodb-page-size=4k +# --mysqld=--innodb-page-size=4096 +# --mysqld=--innodb-page-size=8k +# --mysqld=--innodb-page-size=8192 +# --mysqld=--innodb-page-size=16k +# --mysqld=--innodb-page-size=16384 +# <no assignment of innodb-page-size at all> +# +# The current test is placed within the suite "innodb" though many tests for +# system variables are stored within the suite "sys_vars". The reason is the +# following: +# The test is adjusted to be used with different legal innodb page sizes +# assigned on command line. +# Our current test collections run the test suite +# - sys_vars without assignment of innodb-page-size +# - innodb with several different assignments of innodb-page-size +# Therefore placing this test within the suite "innodb" is better. +# +# Created: 2011-11-11 mleich +# + +# Set this variable to +# - 0 for standard test runs (file with expected results is made for such). +# - 1 for debugging.(a result difference will show up) +let $test_debug= 0; + +--echo # 0. Check and generate prerequites +#----------------------------------------- +--source include/not_embedded.inc +--source include/have_innodb.inc + +# InnoDb page size values in 2011-11 +# - supported: 4k, 8k, 16k +# - default: 16k +let $minimal_page_size= 4096; +let $default_page_size= 16384; +let $maximal_page_size= 16384; +let $legal_page_size_list= $minimal_page_size,8192,$maximal_page_size; +let $start_page_size= +`SELECT variable_value FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE LOWER(variable_name) = 'innodb_page_size'`; +if(`SELECT $start_page_size NOT IN ($legal_page_size_list)`) +{ + --echo # ERROR: The current innodb page size ($start_page_size) is not in + --echo # the list of expected legal page sizes : $legal_page_size_list + --echo # abort + exit; +} +let $other_page_size= $minimal_page_size; +if($start_page_size == $minimal_page_size) +{ + let $other_page_size= $maximal_page_size; +} +let $other_page_size_k= `SELECT $other_page_size DIV 1024`; +let $other_page_size_nk= `SELECT CONCAT($other_page_size_k,'k')`; +let $other_page_size_nkaramel= `SELECT CONCAT($other_page_size_k,'karamel')`; +let $other_page_size_ncaramel= `SELECT CONCAT($other_page_size_k,'caramel')`; +if ($start_page_size < $maximal_page_size) +{ + let $out_range_page_size= `SELECT $maximal_page_size * 4`; + let $adjust_page_size = $maximal_page_size; +} +if ($start_page_size > $minimal_page_size) +{ + let $out_range_page_size= `SELECT $minimal_page_size DIV 2`; + let $adjust_page_size = $minimal_page_size; +} +let $illegal_pagesize= `SELECT $minimal_page_size + 1`; +let $zero_test= 1; +if ($start_page_size == $minimal_page_size) +{ + let $zero_test= 0; +} +if ($test_debug) +{ + --echo # --- Set in test script -------------------------- + --echo # minimal_page_size : $minimal_page_size + --echo # default_page_size : $default_page_size + --echo # maximal_page_size : $maximal_page_size + --echo # legal_page_size_list : $legal_page_size_list + --echo # --- Calculated --------------------------------- + --echo # start_page_size : $start_page_size + --echo # other_page_size_k : $other_page_size_k + --echo # other_page_size_nk : $other_page_size_nk + --echo # other_page_size_nkaramel : $other_page_size_nkaramel + --echo # other_page_size_ncaramel : $other_page_size_ncaramel + --echo # out_range_page_size : $out_range_page_size + --echo # adjust_page_size : $adjust_page_size + --echo # illegal_pagesize : $illegal_pagesize + --echo # zero_test : $zero_test +} + +# We let our server restart attempts write to the file $error_log. +let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err; +--error 0,1 +--remove_file $error_log +# $error_log has to be processed by include/search_pattern_in_file.inc which +# contains Perl code requiring that the environment variable SEARCH_FILE points +# to this file. +let SEARCH_FILE= $error_log; +# Stop the server +let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; +--exec echo "wait" > $restart_file +--shutdown_server 10 +--source include/wait_until_disconnected.inc + + +--echo # 1. Try to restart the server with some other legal innodb page size value. +--echo # It must fail because we had a different value before. +#---------------------------------------------------------------------------------- +--echo # 1.1 The value assigned is a number. +# Detailed explanations of what happens are placed nearby the checks. +--error 1 +--exec $MYSQLD_CMD --innodb-page-size=$other_page_size --loose-console > $error_log 2>&1 +if ( $default_page_size != $other_page_size ) +{ + # It gets detected that the assigned page size is not the default one + let SEARCH_PATTERN= InnoDB: innodb-page-size has been changed from the default value $default_page_size to $other_page_size; + --source include/search_pattern_in_file.inc +} +# We get depending on the platform either "./ibdata1" or ".\ibdata1". +let SEARCH_PATTERN=innodb-page-size mismatch in data file ..ibdata1; +--source include/search_pattern_in_file.inc +# Finally InnoDB becomes an Unknown/unsupported storage engine +let SEARCH_PATTERN= \[ERROR\] Unknown/unsupported storage engine: InnoDB; +--source include/search_pattern_in_file.inc +# The server restart aborts +let SEARCH_PATTERN= \[ERROR\] Aborting; +--source include/search_pattern_in_file.inc +--echo # 1.2 The value assigned is a number followed by 'k'. +--error 1 +--exec $MYSQLD_CMD --innodb-page-size=$other_page_size_nk --loose-console > $error_log 2>&1 +if ( $default_page_size != $other_page_size ) +{ + # It gets detected that the assigned page size is not the default one + let SEARCH_PATTERN= InnoDB: innodb-page-size has been changed from the default value $default_page_size to $other_page_size; + --source include/search_pattern_in_file.inc +} +let SEARCH_PATTERN=innodb-page-size mismatch in data file ..ibdata1; + +--source include/search_pattern_in_file.inc +# Finally InnoDB becomes an Unknown/unsupported storage engine +let SEARCH_PATTERN= \[ERROR\] Unknown/unsupported storage engine: InnoDB; +--source include/search_pattern_in_file.inc +# The server restart aborts +let SEARCH_PATTERN= \[ERROR\] Aborting; +--source include/search_pattern_in_file.inc + + +--echo # 2. Try to restart the server with some innodb page size.which is either +--echo # bigger than the maximum or smaller than the minimum supported one. +--echo # It must fail because we had a different value before. +#------------------------------------------------------------------------------- +# Properties of the value: +# 1. not supported +# 2. below the smallest supported one +# The restart attempt has to fail. +--error 1 +--exec $MYSQLD_CMD --innodb-page-size=$out_range_page_size --loose-console > $error_log 2>&1 +# The innodb page size gets raised to the lowest or biggest legal value. +let SEARCH_PATTERN= \[Warning\] option 'innodb-page-size': unsigned value $out_range_page_size adjusted to $adjust_page_size; +--source include/search_pattern_in_file.inc +if ( $default_page_size != $adjust_page_size ) +{ + # It gets detected that the assigned page size is not the default one + let SEARCH_PATTERN= InnoDB: innodb-page-size has been changed from the default value $default_page_size to $adjust_page_size; + --source include/search_pattern_in_file.inc +} +# Some checks omitted because they are already in 1. +# Finally InnoDB becomes an Unknown/unsupported storage engine +let SEARCH_PATTERN= \[ERROR\] Unknown/unsupported storage engine: InnoDB; +--source include/search_pattern_in_file.inc + + +--echo # 3. Try to restart the server with the plain wrong innodb page size value "garbage". +--echo # The restart attempt has to +--echo # - fail in case start of test page size <> the minimal legal page size. +--echo # - to be successful in case start of test page size = minimal legal page size. +--echo # In this case we omit the execution of the current sub test! +#------------------------------------------------------------------------------------------- +if ($zero_test) +{ + if ($test_debug) + { + --echo # We do not omit the test. + } +--error 1 +--exec $MYSQLD_CMD --innodb-page-size=garbage --loose-console > $error_log 2>&1 +# General server properties cause that +# - the plain wrong value "garbage" assigned to innodb page size gets +# mangled to 0. +# - the 0 which is below the smallest possible page size is adjusted +# to the smallest possible page size +let SEARCH_PATTERN= \[Warning\] option 'innodb-page-size': unsigned value 0 adjusted to $minimal_page_size; +--source include/search_pattern_in_file.inc +# It gets detected that the innodb page size has been changed. +let SEARCH_PATTERN= InnoDB: innodb-page-size has been changed from the default value $default_page_size to $minimal_page_size; +--source include/search_pattern_in_file.inc +# Some checks omitted because they are already in 1. +# Finally InnoDB becomes an Unknown/unsupported storage engine +let SEARCH_PATTERN= \[ERROR\] Unknown/unsupported storage engine: InnoDB; +--source include/search_pattern_in_file.inc +} + + +--echo # 4. Try to restart the server with some illegal innodb page size value +--echo # being between minimum and maximum legal page size value. +--echo # The restart attempt has to fail. +#------------------------------------------------------------------------------ +# Properties of the value: +# 1. not supported +# 2. between smallest (4k) and biggest (16k) supported one +--error 1 +--exec $MYSQLD_CMD --innodb-page-size=$illegal_pagesize --loose-console > $error_log 2>&1 +# InnoDB cannot handle this value. +let SEARCH_PATTERN= \[ERROR\] InnoDB: Invalid page size=$illegal_pagesize; +--source include/search_pattern_in_file.inc +# Some checks omitted because they are already in 1. +# Finally InnoDB becomes an Unknown/unsupported storage engine +let SEARCH_PATTERN= \[ERROR\] Unknown/unsupported storage engine: InnoDB; +--source include/search_pattern_in_file.inc + + +--echo # 5. Try to restart the server with wrong innodb page size <number>karamel. +--echo # <number>k is a legal page size. +#--------------------------------------------------------------------------------- +# The restart attempt has to fail. +--error 1 +--exec $MYSQLD_CMD --innodb-page-size=$other_page_size_nkaramel --loose-console > $error_log 2>&1 +# The plain wrong value "<number>karamel" assigned to innodb page size seems +# to get mangled to "<number>k" which is a legal value. +if ( $default_page_size != $adjust_page_size ) +{ + # It gets detected that the assigned page size is not the default one + let SEARCH_PATTERN= InnoDB: innodb-page-size has been changed from the default value $default_page_size to $other_page_size; + --source include/search_pattern_in_file.inc +} +# But this change does not fit to the history of the data. +# Some checks omitted because they are already in 1. +# Finally InnoDB becomes an Unknown/unsupported storage engine +let SEARCH_PATTERN= \[ERROR\] Aborting; +--source include/search_pattern_in_file.inc + + +--echo # 6. Try to restart the server with the plain wrong innodb page size <number>caramel +--echo # <number>k is a legal page size. +--echo # The restart attempt has to +--echo # - fail in case start of test page size <> the minimal legal page size. +--echo # - to be successful in case start of test page size = minimal legal page size. +--echo # In this case we omit the execution of the current sub test! +#------------------------------------------------------------------------------------------ +if ($zero_test) +{ + if ($test_debug) + { + --echo # We do not omit the test. + } +--error 1 +--exec $MYSQLD_CMD --innodb-page-size=$other_page_size_ncaramel --loose-console > $error_log 2>&1 +# The server dislikes the assigned value. +let SEARCH_PATTERN= Unknown suffix 'c' used for variable 'innodb-page-size' \(value '$other_page_size_ncaramel'\); +--source include/search_pattern_in_file.inc +# The plain wrong value "<number>caramel" assigned to innodb page size gets +# mangled to 0. +let SEARCH_PATTERN= \[Warning\] option 'innodb-page-size': unsigned value 0 adjusted to $minimal_page_size; +--source include/search_pattern_in_file.inc +# Some other layer has also something to tell. +let SEARCH_PATTERN= mysqld.*: Error while setting value '$other_page_size_ncaramel' to 'innodb-page-size'; +--source include/search_pattern_in_file.inc +# Finally InnoDB becomes an Unknown/unsupported storage engine +let SEARCH_PATTERN= \[ERROR\] Unknown/unsupported storage engine: InnoDB; +--source include/search_pattern_in_file.inc +} + +--echo # 7. Restart the server and cleanup +#----------------------------------------- +--enable_reconnect +--exec echo "restart" > $restart_file +--source include/wait_until_connected_again.inc +--error 0,1 +--remove_file $restart_file +--remove_file $error_log + + diff --git a/mysql-test/suite/innodb/t/innodb_replace.test b/mysql-test/suite/innodb/t/innodb_replace.test new file mode 100644 index 00000000000..a35f423c85e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_replace.test @@ -0,0 +1,186 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +--echo # +--echo #Bug#11759688 52020: InnoDB can still deadlock +--echo #on just INSERT...ON DUPLICATE KEY +--echo #a.k.a. Bug#7975 deadlock without any locking, simple select and update +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB; + +INSERT INTO t1 VALUES(3,1); + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connection con1; + +BEGIN; +# normal INSERT of a duplicate should only S-lock the existing record (3,1) +SET DEBUG_SYNC='write_row_noreplace SIGNAL insert1 WAIT_FOR select1'; +--send +INSERT INTO t1 VALUES(3,2); + +connection default; +SET DEBUG_SYNC='now WAIT_FOR insert1'; +# this should S-lock (3,1); no conflict +SELECT * FROM t1 LOCK IN SHARE MODE; +# this should X-lock (3,1), conflicting with con1 +--send +SELECT * FROM t1 FOR UPDATE; + +connection con2; +# Check that the above SELECT is blocked +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Sending data' and + info = 'SELECT * FROM t1 FOR UPDATE'; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL select1'; + +connection con1; +--error ER_DUP_ENTRY +reap; +# We are still holding an S-lock on (3,1) after the failed INSERT. +# The following will upgrade it to an X-lock, causing a deadlock. +# InnoDB should resolve the deadlock by aborting the blocked SELECT. +INSERT INTO t1 VALUES(3,3) ON DUPLICATE KEY UPDATE b=b+10; + +connection default; +--error ER_LOCK_DEADLOCK +reap; +connection con1; +COMMIT; + +SET DEBUG_SYNC='write_row_replace SIGNAL insert2 WAIT_FOR select2'; +--send +REPLACE INTO t1 VALUES(3,4); + +connection default; +SET DEBUG_SYNC='now WAIT_FOR insert2'; +SELECT * FROM t1; +--send +SELECT * FROM t1 LOCK IN SHARE MODE; + +connection con2; +# Check that the above SELECT is blocked because of X lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Sending data' and + info = 'SELECT * FROM t1 LOCK IN SHARE MODE'; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL select2'; + +connection con1; +reap; + +SET DEBUG_SYNC='write_row_replace SIGNAL insert3 WAIT_FOR select3'; +--send +INSERT INTO t1 VALUES(3,5) ON DUPLICATE KEY UPDATE b=b+20; + +connection default; +reap; +SET DEBUG_SYNC='now WAIT_FOR insert3'; +--send +SELECT b FROM t1 LOCK IN SHARE MODE; + +connection con2; +# Check that the above SELECT is blocked because of X lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Sending data' and + info = 'SELECT b FROM t1 LOCK IN SHARE MODE'; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL select3'; + +connection default; +reap; + +connection con1; +reap; +SET DEBUG_SYNC='write_row_noreplace SIGNAL insert4 WAIT_FOR select4'; +--send +LOAD DATA INFILE '../../std_data/loaddata5.dat' INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b); + +connection default; +SET DEBUG_SYNC='now WAIT_FOR insert4'; +# this should S-lock (3,1); no conflict +SELECT b FROM t1 WHERE a=3 LOCK IN SHARE MODE; +# this should X-lock (3,1), conflicting with con1 +--send +SELECT b FROM t1 WHERE a=3 FOR UPDATE; + +connection con2; +# Check that the above SELECT is blocked +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'statistics' and + info = 'SELECT b FROM t1 WHERE a=3 FOR UPDATE'; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL select4'; + +connection default; +reap; + +connection con1; +--error ER_DUP_ENTRY +reap; +SET DEBUG_SYNC='write_row_noreplace SIGNAL insert5 WAIT_FOR select5'; +--send +LOAD DATA INFILE '../../std_data/loaddata5.dat' IGNORE INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b); + +connection default; +SET DEBUG_SYNC='now WAIT_FOR insert5'; +SELECT * FROM t1; +# this should S-lock; no conflict +SELECT * FROM t1 WHERE a=3 LOCK IN SHARE MODE; +# this should X-lock, conflicting with the S-lock of the IGNORE in con1 +--send +SELECT * FROM t1 WHERE a=3 FOR UPDATE; + +connection con2; +# Check that the above SELECT is blocked +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'statistics' and + info = 'SELECT * FROM t1 WHERE a=3 FOR UPDATE'; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL select5'; + +connection con1; +reap; +connection default; +reap; + +connection con1; +SET DEBUG_SYNC='write_row_replace SIGNAL insert6 WAIT_FOR select6'; +--send +LOAD DATA INFILE '../../std_data/loaddata5.dat' REPLACE INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b); + +connection default; +SET DEBUG_SYNC='now WAIT_FOR insert6'; +SELECT * FROM t1; +# this should conflict with the X-lock acquired by the REPLACE +--send +SELECT a,b FROM t1 LOCK IN SHARE MODE; + +connection con2; +# Check that the above SELECT is blocked +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Sending data' and + info = 'SELECT a,b FROM t1 LOCK IN SHARE MODE'; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL select6'; + +connection con1; +reap; +connection default; +reap; + +disconnect con1; +disconnect con2; + +connection default; +SET DEBUG_SYNC='RESET'; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test new file mode 100644 index 00000000000..e441a795540 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test @@ -0,0 +1,48 @@ +# +# Test the persistent stats auto recalc +# + +-- source include/have_innodb.inc +# Page numbers printed by this test depend on the page size +-- source include/have_innodb_16k.inc + +-- vertical_results + +-- let $check_stats1 = SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc' +-- let $check_stats2 = SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' + +CREATE TABLE autorecalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +INSERT INTO autorecalc VALUES (1); +INSERT INTO autorecalc VALUES (2); + +# wait for the bg stats thread to update the stats, notice we wait on +# innodb_index_stats because innodb_table_stats gets updated first and +# it is possible that (if we wait on innodb_table_stats) the wait cond +# gets satisfied before innodb_index_stats is updated +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the second INSERT from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +# now DELETE the rows and trigger a second auto-recalc, InnoDB may wait a +# few seconds before triggering an auto-recalc again (it tries not to be too +# aggressive) + +DELETE FROM autorecalc; + +let $wait_timeout = 25; +let $wait_condition = SELECT stat_value = 0 FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the DELETE from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE autorecalc; diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test new file mode 100644 index 00000000000..aeb5b5c291e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test @@ -0,0 +1,49 @@ +# +# Test the persistent stats auto recalc during DDL +# + +-- source include/have_innodb.inc + +-- vertical_results + +-- let $check_stats1 = SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'arddl' ORDER BY 1 +-- let $check_stats2 = SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' ORDER BY 1, 2, 3 + +# Test ADD INDEX during background stats gathering + +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a)) ENGINE=INNODB; + +INSERT INTO arddl VALUES (1, 10); +INSERT INTO arddl VALUES (2, 10); + +ALTER TABLE arddl ADD INDEX (b); + +# wait for the bg stats thread to update the stats, notice we wait on +# innodb_index_stats because innodb_table_stats gets updated first and +# it is possible that (if we wait on innodb_table_stats) the wait cond +# gets satisfied before innodb_index_stats is updated +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the second INSERT from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE arddl; + +# Test DROP INDEX during background stats gathering + +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a), KEY (b)) ENGINE=INNODB; + +INSERT INTO arddl VALUES (3, 10); +INSERT INTO arddl VALUES (4, 10); + +ALTER TABLE arddl DROP INDEX b; + +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE arddl; diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test new file mode 100644 index 00000000000..8dff76cd693 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test @@ -0,0 +1,44 @@ +# +# Test the persistent stats auto recalc on lots of tables +# + +-- source include/have_innodb.inc + +let $check_stats = SELECT table_name, n_rows FROM mysql.innodb_table_stats WHERE table_name LIKE 'ar_%' ORDER BY table_name; + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval CREATE TABLE ar_$i (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + dec $i; +} +-- enable_query_log + +# the CREATEs above should have inserted zeroed stats +-- eval $check_stats + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval INSERT INTO ar_$i VALUES (1), (2); + dec $i; +} +-- enable_query_log + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval INSERT INTO ar_$i VALUES (3), (4); + dec $i; +} +-- enable_query_log + +# would be too long to wait for stats to become up to date here + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval DROP TABLE ar_$i; + dec $i; +} +-- enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test new file mode 100644 index 00000000000..d8e7332958d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test @@ -0,0 +1,85 @@ +# +# Test the persistent stats auto recalc when persistent stats do not exist +# + +-- source include/have_innodb.inc + +-- vertical_results + +-- let $check_stats1 = SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't' +-- let $check_stats2 = SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't' + +-- echo Test with default setting + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# close the table +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, causing stats recalc/save +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; + +-- echo Test with explicit enable + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=1; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# close the table +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, causing stats recalc/save +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; + +-- echo Test with explicit disable + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=0; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# close the table +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, stats should not be present, since autorecalc is disabled +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb_stats_del_mark-master.opt b/mysql-test/suite/innodb/t/innodb_stats_del_mark-master.opt new file mode 100644 index 00000000000..145ee2b4264 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_del_mark-master.opt @@ -0,0 +1 @@ +--innodb_stats_include_delete_marked=on diff --git a/mysql-test/suite/innodb/t/innodb_stats_del_mark.test b/mysql-test/suite/innodb/t/innodb_stats_del_mark.test new file mode 100644 index 00000000000..9f0a5c12c37 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_del_mark.test @@ -0,0 +1,130 @@ +--echo # +--echo # Bug 23333990 PERSISTENT INDEX STATISTICS UPDATE BEFORE +--echo # TRANSACTION IS COMMITTED +--echo # + +--source include/big_test.inc +--source include/not_valgrind.inc + +--echo "Test 1:- Uncommited delete test" +CREATE TABLE t1 (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + val INT UNSIGNED NOT NULL, + INDEX (val)) ENGINE=INNODB + STATS_PERSISTENT=1,STATS_AUTO_RECALC=1; + + +INSERT INTO t1 (val) VALUES (4); +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +INSERT INTO t1 (val) SELECT VAL from t1; +SELECT COUNT(*) FROM t1; + +connect(con1, localhost, root,,); + +--echo Connection 1 +connection con1; +START TRANSACTION; +DELETE FROM t1; +send SELECT COUNT(*) FROM t1; + +--echo Connection Default +connection default; +# To make test determinstic in case stats calculation is not +# triggered we will call analyze table +analyze table t1; +let $row_count= query_get_value(EXPLAIN SELECT * FROM t1 WHERE val=4, rows,1); +if ($row_count > 20000) +{ +--echo Test correctly estimates the number of rows as > 20000 +--echo even when in other uncommmited transaction +--echo all rows have been deleted. +} + +if ($row_count < 20000) +{ +--echo FAIL row count is $row_count +} +--echo Connection 1 +connection con1; +reap; +commit; + +--echo Connection deafult +connection default; + +--echo Test 2:- Insert and rollback test +CREATE TABLE t2 (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + val INT UNSIGNED NOT NULL, + INDEX (val)) ENGINE=INNODB + STATS_PERSISTENT=1,STATS_AUTO_RECALC=1; + +--echo Connection 1 +connection con1; + +START TRANSACTION; + +INSERT INTO t2 (val) VALUES (4); +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +INSERT INTO t2 (val) SELECT VAL from t2; +send SELECT COUNT(*) FROM t2; + +--echo Connection default +connection default; +select count(*) from t2; +analyze table t2; +let $row_count= query_get_value(EXPLAIN SELECT * FROM t2 WHERE val=4, rows,1); +if ($row_count > 20000) +{ +--echo Test correctly estimates the number of rows as > 20000 +--echo even when in other uncommited transaction +--echo many rows are inserted. +} + +--echo Connection 1 +connection con1; +reap; +--echo Rollback the insert +rollback; + +--echo Connection default +connection default; +let $row_count= query_get_value(EXPLAIN SELECT * FROM t2 WHERE val=4, rows,1); +if ($row_count <= 1) +{ +--echo Test correctly estimates the number of rows as $row_count +--echo after rollback. +} + +disconnect con1; +DROP TABLE t1,t2; diff --git a/mysql-test/suite/innodb/t/innodb_stats_external_pages.test b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test new file mode 100644 index 00000000000..f40802801c3 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test @@ -0,0 +1,83 @@ +# +# Bug#18384390 WRONG STATISTICS WITH BIG ROW LENGTH AND PERSISTENT STATS +# + +-- source include/have_innodb.inc + +CREATE TABLE bug18384390 ( + id INT AUTO_INCREMENT PRIMARY KEY, + txt VARCHAR(10000) +) ENGINE=INNODB STATS_AUTO_RECALC=0; + +INSERT INTO bug18384390 (txt) VALUES (REPEAT('0', 10000)); +-- let $i = 0 +while ($i < 10) { + INSERT INTO bug18384390 (txt) SELECT txt FROM bug18384390; + -- inc $i +} + +# Now we have 1024 rows in bug18384390 + +-- let $count = `SELECT COUNT(*) FROM bug18384390` + +ANALYZE TABLE bug18384390; + +-- let $n_rows = `SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'bug18384390'` + +-- let $table_rows = `SELECT table_rows FROM information_schema.tables WHERE table_name = 'bug18384390'` + +-- let $n_diff = `SELECT stat_value FROM mysql.innodb_index_stats WHERE table_name = 'bug18384390' AND stat_name = 'n_diff_pfx01'` + +-- let $cardinality = `SELECT cardinality FROM information_schema.statistics WHERE table_name = 'bug18384390'` + +-- let $margin_of_err_pct = 30 +-- let $margin_of_err_rows = `SELECT ROUND($count * $margin_of_err_pct / 100)` + +-- let $min_allowed = `SELECT $count - $margin_of_err_rows` +-- let $max_allowed = `SELECT $count + $margin_of_err_rows` + +-- let $dump_sql = SELECT COUNT(*) FROM bug18384390; SELECT * FROM mysql.innodb_table_stats; SELECT * FROM mysql.innodb_index_stats; SELECT * FROM information_schema.tables WHERE table_name = 'bug18384390'; SELECT * FROM information_schema.statistics WHERE table_name = 'bug18384390'; + +-- vertical_results + +if ($n_rows < $min_allowed) { + -- echo mysql.innodb_table_stats.n_rows is too small ($n_rows < $min_allowed) + -- eval $dump_sql +} + +if ($n_rows > $max_allowed) { + -- echo mysql.innodb_table_stats.n_rows is too big ($n_rows > $max_allowed) + -- eval $dump_sql +} + +if ($table_rows < $min_allowed) { + -- echo information_schema.tables.table_rows is too small ($table_rows < $min_allowed) + -- eval $dump_sql +} + +if ($table_rows > $max_allowed) { + -- echo information_schema.tables.table_rows is too big ($table_rows > $max_allowed) + -- eval $dump_sql +} + +if ($n_diff < $min_allowed) { + -- echo mysql.innodb_index_stats.stat_value is too small ($n_diff < $min_allowed) + -- eval $dump_sql +} + +if ($n_diff > $max_allowed) { + -- echo mysql.innodb_index_stats.stat_value is too big ($n_diff > $max_allowed) + -- eval $dump_sql +} + +if ($cardinality < $min_allowed) { + -- echo information_schema.statistics.cardinality is too small ($cardinality < $min_allowed) + -- eval $dump_sql +} + +if ($cardinality > $max_allowed) { + -- echo information_schema.statistics.cardinality is too big ($cardinality > $max_allowed) + -- eval $dump_sql +} + +DROP TABLE bug18384390; diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global_off-master.opt b/mysql-test/suite/innodb/t/innodb_stats_flag_global_off-master.opt new file mode 100644 index 00000000000..25ab333de54 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global_off-master.opt @@ -0,0 +1 @@ +--innodb-stats-persistent=0 diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global_off.test b/mysql-test/suite/innodb/t/innodb_stats_flag_global_off.test new file mode 100644 index 00000000000..301eaa525b2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global_off.test @@ -0,0 +1,10 @@ +# +# Test the persistent stats table flag when innodb_stats_persistent=OFF +# --innodb-stats-persistent=0 is specified in -master.opt +# + +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- source suite/innodb/include/innodb_stats_table_flag.inc diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global_on-master.opt b/mysql-test/suite/innodb/t/innodb_stats_flag_global_on-master.opt new file mode 100644 index 00000000000..27ec1e3f00e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global_on-master.opt @@ -0,0 +1 @@ +--innodb-stats-persistent=1 diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global_on.test b/mysql-test/suite/innodb/t/innodb_stats_flag_global_on.test new file mode 100644 index 00000000000..1291db5a2fd --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global_on.test @@ -0,0 +1,10 @@ +# +# Test the persistent stats table flag when innodb_stats_persistent=ON +# --innodb-stats-persistent=1 is specified in -master.opt +# + +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- source suite/innodb/include/innodb_stats_table_flag.inc diff --git a/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test new file mode 100644 index 00000000000..1aac71a0450 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test @@ -0,0 +1,53 @@ +# +# Test that the table option STATS_SAMPLE_PAGES=N|default is indeed +# used by InnoDB +# + +-- source include/have_innodb.inc +# Page numbers printed by this test depend on the page size +-- source include/have_innodb_16k.inc + +SET GLOBAL innodb_stats_persistent_sample_pages=17; + +CREATE TABLE test_ps_sample_pages_used ( + a VARCHAR(512), PRIMARY KEY (a) +) ENGINE=INNODB STATS_SAMPLE_PAGES=default; + +# Insert enough records into the table so that it has more than 2*17+1 pages +# If we ask to scan more than the half of the leaf pages, then the sampling +# will do full scan and we cannot check whether the sample_pages variable was +# honored. +BEGIN; +-- disable_query_log +let $i=999; +while ($i) { + eval INSERT INTO test_ps_sample_pages_used VALUES (REPEAT(1000+$i, 128)); + dec $i; +} +-- enable_query_log +COMMIT; + +ANALYZE TABLE test_ps_sample_pages_used; + +# confirm the big number of leaf pages in the index +SELECT stat_name, stat_value FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_leaf_pages'; + +# confirm that 17 pages were sampled, that is - the global +# innodb_stats_persistent_sample_pages is used when the table option +# STATS_SAMPLE_PAGES is set to 'default'. +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; + +ALTER TABLE test_ps_sample_pages_used STATS_SAMPLE_PAGES=14; + +ANALYZE TABLE test_ps_sample_pages_used; + +# confirm that 14 pages were sampled, that is - the table option +# STATS_SAMPLE_PAGES is used when it is set. +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; + +DROP TABLE test_ps_sample_pages_used; + +SET GLOBAL innodb_stats_persistent_sample_pages=default; diff --git a/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test b/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test new file mode 100644 index 00000000000..a868022d002 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test @@ -0,0 +1,83 @@ +# +# Test CREATE TABLE ... STATS_AUTO_RECALC=0|1|default +# + +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- vertical_results + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=default; + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=0; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=0; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; diff --git a/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test b/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test new file mode 100644 index 00000000000..a5c3c8624b1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test @@ -0,0 +1,103 @@ +# +# Test CREATE TABLE ... STATS_SAMPLE_PAGES=N|default +# + +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- vertical_results + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=12345; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=default; + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=-5; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=0; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=67000; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=670000; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65536; + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65535; + +SHOW CREATE TABLE test_ps_sample_pages; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=5678; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=default; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; diff --git a/mysql-test/suite/innodb/t/innodb_upd_stats_if_needed_not_inited.test b/mysql-test/suite/innodb/t/innodb_upd_stats_if_needed_not_inited.test new file mode 100644 index 00000000000..92e74b19a2c --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_upd_stats_if_needed_not_inited.test @@ -0,0 +1,38 @@ +# +# Test executing row_update_statistics_if_needed() when the stats +# for the given table are not initialized +# + +-- source include/have_debug.inc +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc +# Windows does not have grep(1) +-- source include/not_windows.inc + +CREATE TABLE parent ( + a INT PRIMARY KEY +) ENGINE=INNODB; + +CREATE TABLE child ( + a INT PRIMARY KEY, + FOREIGN KEY (a) REFERENCES parent(a) ON DELETE CASCADE +) ENGINE=INNODB; + +INSERT INTO parent VALUES (1); +INSERT INTO child VALUES (1); + +-- source include/restart_mysqld.inc + +SET SESSION DEBUG='+d,test_upd_stats_if_needed_not_inited'; + +# this will cause row_update_statistics_if_needed() to be called for a table +# that is not opened (child) and thus has table->stat_initialized set to FALSE +DELETE FROM parent; + +SET SESSION DEBUG='-d,test_upd_stats_if_needed_not_inited'; + +-- exec grep 'test_upd_stats_if_needed_not_inited was executed' $MYSQLTEST_VARDIR/log/mysqld.1.err || true + +DROP TABLE child; +DROP TABLE parent; diff --git a/mysql-test/suite/innodb/t/innodb_ut_format_name.test b/mysql-test/suite/innodb/t/innodb_ut_format_name.test new file mode 100644 index 00000000000..2145644cd37 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_ut_format_name.test @@ -0,0 +1,16 @@ +# +# Test ut_format_name() +# + +-- source include/have_debug.inc +-- source include/have_innodb.inc + +CREATE TABLE t (c INT) ENGINE=INNODB; + +# This will invoke test_ut_format_name() in debug builds + +SET SESSION DEBUG='+d,test_ut_format_name'; + +DROP TABLE t; + +SET SESSION DEBUG='-d,test_ut_format_name'; diff --git a/mysql-test/suite/innodb/t/monitor.test b/mysql-test/suite/innodb/t/monitor.test new file mode 100644 index 00000000000..f54337eec5e --- /dev/null +++ b/mysql-test/suite/innodb/t/monitor.test @@ -0,0 +1,440 @@ +# This is the test for Metrics Monitor Table feature. +# Test the metrics monitor system's control system +# and counter accuracy. + +--source include/have_innodb.inc + +set global innodb_monitor_disable = All; + +# Test turn on/off the monitor counter with "all" option +# By default, they will be off +select name, status from information_schema.innodb_metrics; + +# Turn on all monitor counters +set global innodb_monitor_enable = all; + +# status should all change to "enabled" +select name from information_schema.innodb_metrics where status!='enabled'; + +# Test wrong argument to the global configure option +--error ER_WRONG_VALUE_FOR_VAR +set global innodb_monitor_enable = aaa; + +# We require a valid monitor counter/module name. There is no default +# counter name or module. A warning will be printed asking user to +# specify a valid counter name. +#--disable_warnings +#set global innodb_monitor_enable = default; +#--enable_warnings + +# Turn off all monitor counters, option name should be case +# insensitive +set global innodb_monitor_disable = All; + +# status should all change to "disabled" +select name from information_schema.innodb_metrics where status!='disabled'; + +# Reset all counter values +set global innodb_monitor_reset_all = all; + +# count should all change to 0 +select name from information_schema.innodb_metrics where count!=0; + +# Test wildcard match, turn on all counters contain string "lock" +set global innodb_monitor_enable = "%lock%"; + +# All lock related counter should be enabled +select name from information_schema.innodb_metrics +where status != IF(name like "%lock%", 'enabled', 'disabled'); + +# Disable them +set global innodb_monitor_disable = "%lock%"; + +# All lock related counter should be disabled +select name, status from information_schema.innodb_metrics +where name like "%lock%"; + +# No match for "%lock*" +--error ER_WRONG_VALUE_FOR_VAR +set global innodb_monitor_enable = "%lock*"; + +# All counters will be turned on with wildcard match string with all "%" +set global innodb_monitor_enable="%%%%%%%%%%%%%%%%%%%%%%%%%%%"; + +select name from information_schema.innodb_metrics where status!='enabled'; + +# Turn off all counters +set global innodb_monitor_disable="%%%%%"; + +select name from information_schema.innodb_metrics where status!='disabled'; + +# One more round testing. All counters will be turned on with +# single wildcard character "%" +set global innodb_monitor_enable="%"; + +select name from information_schema.innodb_metrics where status!='enabled'; + +# Turn off all the counters with "%_%" +set global innodb_monitor_disable="%_%"; + +select name from information_schema.innodb_metrics where status!='disabled'; + +# Turn on all counters start with "log" +set global innodb_monitor_enable="log%%%%"; + +select name from information_schema.innodb_metrics +where status != IF(name like "log%", 'enabled', 'disabled'); + +# Turn on counters "os_data_fsync" with wildcard match "os_%a_fs_ncs", "_" +# is single character wildcard match word +set global innodb_monitor_enable="os_%a_fs_ncs"; + +# Turn on counters whose name contains "os" and "pending" with +# wildcard match "os%pending%" +set global innodb_monitor_enable="os%pending%"; + +select name, status from information_schema.innodb_metrics +where name like "os%"; + +# Empty string is an invalid option +--error ER_WRONG_VALUE_FOR_VAR +set global innodb_monitor_enable=""; + +--error ER_WRONG_VALUE_FOR_VAR +set global innodb_monitor_enable="_"; + +# Reset counters only in "module_metadata" module +set global innodb_monitor_disable = module_metadata; + +set global innodb_monitor_reset_all = module_metadata; + +# Only turn on "table_open" counter +set global innodb_monitor_enable = metadata_table_handles_opened; + +# Create a new table to test "metadata_table_handles_opened" counter +create table monitor_test(col int) engine = innodb; + +# This will open the monitor_test table +select * from monitor_test; + +# "metadata_table_handles_opened" should increment by 1 +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# Reset the counter value while counter is still on (started) +# This will reset value "count_reset" but not +# "count" +set global innodb_monitor_reset = metadata_table_handles_opened; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# re-create table again to increment "metadata_table_handles_opened" again +drop table monitor_test; + +# Create a new table to test "metadata_table_handles_opened" counter +create table monitor_test(col int) engine = innodb; + +select * from monitor_test; + +# "metadata_table_handles_opened" should increment +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# Cannot reset all monitor value while the counter is on +set global innodb_monitor_reset_all = metadata_table_handles_opened; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# Turn off the counter "metadata_table_handles_opened" +set global innodb_monitor_disable = metadata_table_handles_opened; + +# Reset the counter value while counter is off (disabled) +set global innodb_monitor_reset = metadata_table_handles_opened; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# re-create table again. Since monitor is off, "metadata_table_handles_opened" +# should not be incremented +drop table monitor_test; + +# Create a new table to test "metadata_table_handles_opened" counter +create table monitor_test(col int) engine = innodb; + +# "metadata_table_handles_opened" should increment +select * from monitor_test; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# Reset all the counters, include those counter *_since_start +set global innodb_monitor_reset_all = metadata_table_handles_opened; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# Turn on "table_open" counter again +set global innodb_monitor_enable = metadata_table_handles_opened; + +# Test metadata_table_handles_opened again to see if it is working correctly +# after above round of turning on/off/reset +drop table monitor_test; + +# Create a new table to test "metadata_table_handles_opened" counter +create table monitor_test(col int) engine = innodb stats_persistent=0; + +select * from monitor_test; + +# "metadata_table_handles_opened" should increment +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_opened"; + +# Test counter "metadata_table_handles_closed", +# create index will close the old handle +set global innodb_monitor_enable = metadata_table_handles_closed; + +create index idx on monitor_test(col); + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name = "metadata_table_handles_closed"; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "metadata%"; + +# Reset counters only in "module_metadata" module +set global innodb_monitor_disable = module_metadata; + +set global innodb_monitor_reset = module_metadata; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "metadata%"; + +set global innodb_monitor_reset_all = module_metadata; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "metadata%"; + +# Test Transaction Module +set global innodb_monitor_enable = module_trx; + +begin; +insert into monitor_test values(9); +commit; + +begin; +insert into monitor_test values(9); +rollback; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "trx_rollbacks" or name like "trx_active_transactions"; + +set global innodb_monitor_disable = module_trx; + +# Test DML Module +set global innodb_monitor_enable = module_dml; + +insert into monitor_test values(9); + +update monitor_test set col = 10 where col = 9; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "dml%"; + +delete from monitor_test; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status + from information_schema.innodb_metrics + where name like "dml%"; + +# test reset counter while the counter is on +set global innodb_monitor_reset = module_dml; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "dml%"; + +# insert/delete some rows after the reset +insert into monitor_test values(9); +insert into monitor_test values(1); + +delete from monitor_test; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "dml%"; + +# We do not allow reset_all while the counter is on, nothing +# should be reset here +set global innodb_monitor_reset_all = module_dml; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "dml%"; + +# Turn off the counter +set global innodb_monitor_disable = module_dml; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "dml%"; + +# Reset all counter values +set global innodb_monitor_reset_all = module_dml; + +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "dml%"; + +# Open individual counter "dml_inserts" +set global innodb_monitor_enable = dml_inserts; + +insert into monitor_test values(9); +insert into monitor_test values(1); + +delete from monitor_test; + +# Only counter "dml_inserts" should be updated +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "dml%"; + +set global innodb_monitor_disable = module_dml; + +drop table monitor_test; + +set global innodb_monitor_enable = file_num_open_files; + +# Counters are unpredictable when innodb-file-per-table is on +--replace_column 2 # 3 # 4 # 5 # 6 # 7 # +select name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +from information_schema.innodb_metrics +where name like "file_num_open_files"; + +set global innodb_monitor_disable = file_num_open_files; + +# Test ICP module counters +set global innodb_monitor_enable = "icp%"; + +create table monitor_test(a char(3), b int, c char(2), +primary key (a(1), c(1)), key(b)) engine = innodb; + +insert into monitor_test values("13", 2, "aa"); + +select a from monitor_test where b < 1 for update; + +# should have icp_attempts = 1 and icp_out_of_range = 1 +select name, count from information_schema.innodb_metrics +where name like "icp%"; + +# should have icp_attempts = 2 and icp_match = 1 +select a from monitor_test where b < 3 for update; + +select name, count from information_schema.innodb_metrics +where name like "icp%"; + +drop table monitor_test; + +set global innodb_monitor_disable = all; +set global innodb_monitor_reset_all = all; + +# Test for bug #13966091 +select 1 from `information_schema`.`INNODB_METRICS` +where case (1) when (1) then (AVG_COUNT_RESET) else (1) end; + +-- disable_warnings +set global innodb_monitor_enable = default; +set global innodb_monitor_disable = default; +set global innodb_monitor_reset = default; +set global innodb_monitor_reset_all = default; +-- enable_warnings + +--echo # +--echo # Bug#22576241 SETTING INNODB_MONITOR_ENABLE TO ALL DOES NOT ENABLE ALL +--echo # MONITORS +--echo # +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; + +let $innodb_monitor_enable = `SELECT @@innodb_monitor_enable`; + +--replace_regex /[1-9]/NNNN/ +SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +LIKE 'buffer_page_written_index_leaf'; + +SET GLOBAL innodb_monitor_enable='module_buffer_page'; +INSERT INTO t1 VALUES (1), (2), (3), (4); FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; +--replace_regex /[1-9]/NNNN/ +SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +LIKE 'buffer_page_written_index_leaf'; + +SET GLOBAL innodb_monitor_disable='module_buffer_page'; +SET GLOBAL innodb_monitor_reset_all='module_buffer_page'; +--replace_regex /[1-9]/NNNN/ +SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +LIKE 'buffer_page_written_index_leaf'; + +SET GLOBAL innodb_monitor_enable='%'; +INSERT INTO t1 VALUES (5), (6), (7), (8); FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; +--replace_regex /[1-9]/NNNN/ +SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +LIKE 'buffer_page_written_index_leaf'; + +SET GLOBAL innodb_monitor_disable='%'; +SET GLOBAL innodb_monitor_reset_all='%'; +--replace_regex /[1-9]/NNNN/ +SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +LIKE 'buffer_page_written_index_leaf'; + +SET GLOBAL innodb_monitor_enable='ALL'; +INSERT INTO t1 VALUES (9), (10), (11), (12); FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; +--replace_regex /[1-9]/NNNN/ +SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +LIKE 'buffer_page_written_index_leaf'; + +--disable_warnings +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; +--enable_warnings + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/monitor_debug.test b/mysql-test/suite/innodb/t/monitor_debug.test new file mode 100644 index 00000000000..088dcd7a133 --- /dev/null +++ b/mysql-test/suite/innodb/t/monitor_debug.test @@ -0,0 +1,40 @@ +source include/have_innodb.inc; +source include/have_debug.inc; +source include/not_embedded.inc; + +--echo # +--echo # BUG#20080942 - ADAPTIVE_HASH_SEARCHES_BTREE NOT UPDATED +--echo # + +# To make sure that the change buffer is empty +SET GLOBAL innodb_fast_shutdown=0; +--source include/restart_mysqld.inc + +SET GLOBAL innodb_stats_persistent = OFF; +SET GLOBAL innodb_stats_auto_recalc = OFF; +SET GLOBAL innodb_purge_stop_now = ON; + +CREATE TABLE t1(a INT PRIMARY KEY, b BLOB) STATS_PERSISTENT=0; + +let $start=`SELECT COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE +'adaptive_hash_searches_btree' ORDER BY NAME`; + +INSERT INTO t1 VALUES(1, 'abc'); +INSERT INTO t1 VALUES(2, 'def'); +INSERT INTO t1 VALUES(3, 'ghi'); +SELECT * FROM t1; + +let $end=`SELECT COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE +'adaptive_hash_searches_btree' ORDER BY NAME`; + +let $diff=`SELECT $end-$start`; + +if ($diff != 3) { + echo "Unexpected count: $diff"; +} + +DROP TABLE t1; + +SET GLOBAL innodb_stats_persistent = default; +SET GLOBAL innodb_stats_auto_recalc = default; +SET GLOBAL innodb_purge_run_now = ON; diff --git a/mysql-test/suite/innodb/t/portability_wl5980_linux.zip b/mysql-test/suite/innodb/t/portability_wl5980_linux.zip Binary files differnew file mode 100644 index 00000000000..4a6a5224338 --- /dev/null +++ b/mysql-test/suite/innodb/t/portability_wl5980_linux.zip diff --git a/mysql-test/suite/innodb/t/portability_wl5980_windows.zip b/mysql-test/suite/innodb/t/portability_wl5980_windows.zip Binary files differnew file mode 100644 index 00000000000..997962839c8 --- /dev/null +++ b/mysql-test/suite/innodb/t/portability_wl5980_windows.zip diff --git a/mysql-test/suite/innodb/t/strict_checksum.test b/mysql-test/suite/innodb/t/strict_checksum.test new file mode 100644 index 00000000000..6e3217dd05c --- /dev/null +++ b/mysql-test/suite/innodb/t/strict_checksum.test @@ -0,0 +1,68 @@ +--echo # +--echo # Bug #20031570 INNODB_CHECKSUM_ALGORITHM VARIABLE LEADS TO CRASHING +--echo # + +--source include/have_innodb.inc +--source include/have_debug.inc +# Embedded mode doesn't support restart +--source include/not_embedded.inc + +set global innodb_checksum_algorithm=crc32; + +# Table is created with crc32 checksum algorithm. +# First few pages have crc32 checksum algorithm + +create table t1(f1 int not null primary key)engine=innodb; + +# Restart the server to load the table t1 again. +let SEARCH_FILE = $MYSQLTEST_VARDIR/log/my_restart.err; +--source include/shutdown_mysqld.inc + +--echo # Restart the server with --log-error +--exec echo "restart:--log-error=$MYSQLTEST_VARDIR/log/my_restart.err" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +set global innodb_checksum_algorithm=strict_innodb; +set global innodb_limit_optimistic_insert_debug = 2; + +call mtr.add_suppression("\\[Warning\\] InnoDB: innodb_checksum_algorithm is set to .* but the page .* contains a valid checksum .*."); + +# Load the table t1 content with crc32 checksum pages. +select count(*) from t1; + +let SEARCH_PATTERN=\\[Warning\\] InnoDB: innodb_checksum_algorithm is set to "strict_innodb" but the page \\[page id: space=\d+, page number=\d+\\] contains a valid checksum .*. Accepting the page as valid. Change innodb_checksum_algorithm to .* to silently accept such pages or rewrite all pages so that they contain .* checksum.; + +--source include/search_pattern_in_file.inc + +# Write the records in new pages with innodb checksum format. +insert into t1 values(2),(3),(4); + +# Restart the server to load the table t1 again. +--source include/shutdown_mysqld.inc +let SEARCH_FILE = $MYSQLTEST_VARDIR/log/my_restart.err; + +--echo # Restart the server with --log-error +--exec echo "restart:--log-error=$SEARCH_FILE" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +set global innodb_checksum_algorithm=strict_none; +set global innodb_limit_optimistic_insert_debug = 2; + +# Load the table t1 content with crc32, innodb checksum pages. +select count(*) from t1; + +let SEARCH_PATTERN=\\[Warning\\] InnoDB: innodb_checksum_algorithm is set to "strict_none" but the page \\[page id: space=\d+, page number=\d+\\] contains a valid checksum .*. Accepting the page as valid. Change innodb_checksum_algorithm to .* to silently accept such pages or rewrite all pages so that they contain .* checksum.; + +--source include/search_pattern_in_file.inc + +# Write the records in new pages with none checksum format. +insert into t1 values(5),(6),(7); + +# Restart the server to load the table t1 again. +--source include/restart_mysqld.inc + +# Load the table t1 content with crc32, innodb, none checksum pages. +select count(*) from t1; +drop table t1; +--remove_file $SEARCH_FILE diff --git a/mysql-test/suite/innodb/t/undo_space_id.test b/mysql-test/suite/innodb/t/undo_space_id.test new file mode 100644 index 00000000000..f45a95633ce --- /dev/null +++ b/mysql-test/suite/innodb/t/undo_space_id.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +let bugdir= $MYSQLTEST_VARDIR/tmp/datadir1; +--mkdir $bugdir + +let SEARCH_FILE = $bugdir/my_restart.err; +let $args=--defaults-file=$bugdir/my.cnf --datadir=$bugdir --secure-file-priv="" --loose-console > $SEARCH_FILE 2>&1 ; + +--write_file $bugdir/my.cnf +[mysqld] +EOF + +--exec echo "innodb_data_home_dir = $bugdir" >> $bugdir/my.cnf + +--append_file $bugdir/my.cnf +innodb_data_file_path = ibdata1:10M;ibdata2:10M:autoextend +innodb_undo_tablespaces = 3 +innodb_log_files_in_group = 3 +EOF + +# Innodb creates system tablespaces according to my.cnf and aborts +# after creating undo tablespace. +--echo # Start mysqld to create tablespaces according to my.cnf +--error 2 +--exec $MYSQLD $args --skip-grant-tables --debug=d,innodb_undo_upgrade --innodb-unknown-parameter + +--list_files $bugdir +--remove_files_wildcard $bugdir +--rmdir $bugdir diff --git a/mysql-test/suite/innodb_fts/t/disabled.def b/mysql-test/suite/innodb_fts/t/disabled.def new file mode 100644 index 00000000000..888298bbb09 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/disabled.def @@ -0,0 +1,11 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment> +# +# Do not use any TAB characters for whitespace. +# +############################################################################## diff --git a/mysql-test/suite/innodb_fts/t/fts_compatibility.test b/mysql-test/suite/innodb_fts/t/fts_compatibility.test new file mode 100644 index 00000000000..55acbce34f3 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/fts_compatibility.test @@ -0,0 +1,270 @@ +--source include/not_windows.inc +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/not_valgrind.inc + +--echo # Bug #18285007 COPY OF TABLES WITH INNODB FTS +--echo # FROM WINDOWS TO LINUX CAUSES CRASH + +LET $regexp=/FTS_([0-9a-f_]+)([A-Z_]+)/FTS_AUX_\2/; + +--echo # Simulating old non-windows(< 5.6.16) data directory + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a, b))engine=innodb; +INSERT INTO t1 VALUES('TEST1', 'TEST2'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +--source include/restart_mysqld.inc + +# Set flags2 for all the table. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +DROP TABLE t1; + +--echo # Simulating old windows (< 5.6.16) data directory + +let $MYSQLD_DATADIR= `select @@datadir`; +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +SET GLOBAL DEBUG='+d,innodb_test_wrong_windows_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a, b))engine=innodb; +INSERT INTO t1 VALUES('TEST1', 'TEST2'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +--source include/restart_mysqld.inc + +# Renaming the tables. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +DROP TABLE t1; + +--echo # Simulation current non windows data directory + +CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a, b))engine=innodb; +INSERT INTO t1 VALUES('TEST1', 'TEST2'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +--source include/restart_mysqld.inc + +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +DROP TABLE t1; + +--echo # Non windows aux table flag failure and rebuild the corrupted index. + +# Remove the orphaned table +-- source include/restart_mysqld.inc + +call mtr.add_suppression("\\[Warning\\] InnoDB: Parent table of FTS auxiliary table .* not found."); +call mtr.add_suppression("\\[ERROR] InnoDB: Flagged corruption of .* in table .* in DROP ORPHANED TABLE"); +call mtr.add_suppression("\\[Warning\\] InnoDB: Setting aux table .* to hex format failed."); + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT `AB` (a, b), FULLTEXT `C1` (c)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +SET GLOBAL DEBUG='-d,innodb_test_wrong_fts_sys_table_name'; + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# Request shutdown +-- send_shutdown +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +# Set the flag to force the aux table fail and restart the server + +--exec echo "restart:--debug=d,aux_table_flag_fail" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +--error ER_INNODB_INDEX_CORRUPT +ALTER TABLE t1 ADD FULLTEXT(b); + +--echo # Restart the server +-- source include/restart_mysqld.inc + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +--echo # Drop the corrupted index. +ALTER TABLE t1 DROP INDEX `AB`; +ALTER TABLE t1 DROP INDEX `C1`; + +-- echo # Rebuild the index. +ALTER TABLE t1 ADD FULLTEXT(a, b); +ALTER TABLE t1 ADD FULLTEXT(c); + +--echo # Read the record using fts index. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +DROP TABLE t1; + +--echo # Non windows parent table flag failure. + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT(a, b), FULLTEXT(c)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +SET GLOBAL DEBUG='-d,innodb_test_wrong_fts_sys_table_name'; + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# Request shutdown +-- send_shutdown +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +# Set the flag to force the parent table fail and restart the server + +-- disable_query_log +--error 1 +--exec $MYSQLD_CMD --debug="d,parent_table_flag_fail" +-- enable_query_log + +# Restart the server +--enable_reconnect +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); +DROP TABLE t1; + +--echo # Drop FTS table and rename the common tables. + +# Remove the orphaned table +-- source include/restart_mysqld.inc + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +SET GLOBAL DEBUG='+d,innodb_test_wrong_windows_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT f1(a, b)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +alter table t1 drop index f1; +SET SESSION debug='-d,innodb_test_wrong_fts_sys_table_name'; +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; + +--source include/restart_mysqld.inc +# Renaming the common tables. +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # Rename failure for old windows data directory and rebuild the +--echo # corrupted index + +call mtr.add_suppression("\\[Warning\\] InnoDB: Failed to rename one aux table .* will revert all successful rename operations."); + +call mtr.add_suppression("\\[Warning\\] InnoDB: Rollback operations on all aux tables of table .* All the fts index associated with the table are marked as corrupted. Please rebuild the index again."); + +call mtr.add_suppression("\\[ERROR\\] InnoDB: Flagged corruption of .* in table .* in DROP ORPHANED TABLE"); + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +SET GLOBAL DEBUG='+d,innodb_test_wrong_windows_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT `AB`(a, b), FULLTEXT `C1`(c)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +SET SESSION debug='-d,innodb_test_wrong_fts_sys_table_name'; + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# Request shutdown +-- send_shutdown +#Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +# Set the flag to force the rename fail and restart the server +--exec echo "restart:--debug=d,rename_aux_table_fail" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +# Will fail to alter table +--error ER_INNODB_FT_AUX_NOT_HEX_ID +ALTER TABLE t1 ADD FULLTEXT(b); + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); + +--echo # Restart server. +-- source include/restart_mysqld.inc + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +--echo # Drop the corrupted index. +ALTER TABLE t1 DROP INDEX `AB`; +ALTER TABLE t1 DROP INDEX `C1`; + +-- echo # Rebuild the index. +ALTER TABLE t1 ADD FULLTEXT(a, b); +ALTER TABLE t1 ADD FULLTEXT(c); + +--echo # Read the record using fts index. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +TRUNCATE TABLE t1; +DROP TABLE t1; +-- source include/restart_mysqld.inc +--list_files $MYSQLD_DATADIR/test diff --git a/mysql-test/suite/innodb_fts/t/fts_compatibility_win.test b/mysql-test/suite/innodb_fts/t/fts_compatibility_win.test new file mode 100644 index 00000000000..c016b537808 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/fts_compatibility_win.test @@ -0,0 +1,264 @@ +--source include/windows.inc +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_debug.inc + +--echo # Bug #18285007 COPY OF TABLES WITH INNODB FTS +--echo # FROM WINDOWS TO LINUX CAUSES CRASH + +LET $regexp=/FTS_([0-9a-f_]+)([A-Z_]+)/FTS_AUX_\2/; + +--echo # Simulating old non-windows(< 5.6.16) data directory + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +SET GLOBAL DEBUG='+d,innodb_test_wrong_non_windows_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a, b))engine=innodb; +INSERT INTO t1 VALUES('TEST1', 'TEST2'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +--source include/restart_mysqld.inc + +# Set flags2 for all the table. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +DROP TABLE t1; + +--echo # Simulating old windows (< 5.6.16) data directory + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a, b))engine=innodb; +INSERT INTO t1 VALUES('TEST1', 'TEST2'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +--source include/restart_mysqld.inc + +# Renaming the tables. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +DROP TABLE t1; + +--echo # Simulation current windows data directory + +CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a, b))engine=innodb; +INSERT INTO t1 VALUES('TEST1', 'TEST2'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +--source include/restart_mysqld.inc + +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +DROP TABLE t1; + +--echo # Non windows aux table flag failure and rebuild the corrupted index. + +call mtr.add_suppression("\\[Warning\\] InnoDB: Parent table of FTS auxiliary table .* not found."); +call mtr.add_suppression("\\[ERROR] InnoDB: Flagged corruption of .* in table .* in DROP ORPHANED TABLE"); +call mtr.add_suppression("\\[Warning\\] InnoDB: Setting aux table .* to hex format failed."); + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +SET GLOBAL DEBUG='+d,innodb_test_wrong_non_windows_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT `AB` (a, b), FULLTEXT `C1`(c)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +SET GLOBAL DEBUG='-d,innodb_test_wrong_fts_sys_table_name'; + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# Request shutdown +-- send_shutdown +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +# Set the flag to force the aux table fail and restart the server + +--exec echo "restart:--debug=d,aux_table_flag_fail" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +--error ER_INNODB_INDEX_CORRUPT +ALTER TABLE t1 ADD FULLTEXT(b); + +--echo # Restart the server +-- source include/restart_mysqld.inc + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +--echo # Drop the corrupted index. +ALTER TABLE t1 DROP INDEX `AB`; +ALTER TABLE t1 DROP INDEX `C1`; + +-- echo # Rebuild the index. +ALTER TABLE t1 ADD FULLTEXT(a, b); +ALTER TABLE t1 ADD FULLTEXT(c); + +--echo # Read the record using fts index. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +DROP TABLE t1; + +--echo # Non windows parent table flag failure. + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +SET GLOBAL DEBUG='+d,innodb_test_wrong_non_windows_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT(a, b), FULLTEXT(c)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +SET GLOBAL DEBUG='-d,innodb_test_wrong_fts_sys_table_name'; + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# Request shutdown +-- send_shutdown +# Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +# Set the flag to force the parent table fail and restart the server + +-- disable_query_log +--error 1 +--exec $MYSQLD_CMD --debug="d,parent_table_flag_fail" +-- enable_query_log + +# Restart the server +--enable_reconnect +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); +DROP TABLE t1; + +--echo # Drop FTS table and rename the common tables. + +# Remove the orphaned table +-- source include/restart_mysqld.inc + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT f1(a, b)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +alter table t1 drop index f1; +SET SESSION debug='-d,innodb_test_wrong_fts_sys_table_name'; +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; + +--source include/restart_mysqld.inc +# Renaming the common tables. +--replace_regex $regexp +SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name +FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE name LIKE '%FTS_%' ORDER BY 1, 2; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # Rename failure for old windows data directory and rebuild the +--echo # corrupted index + +call mtr.add_suppression("\\[Warning\\] InnoDB: Failed to rename one aux table .* Will revert all successful rename operations."); + +call mtr.add_suppression("\\[Warning\\] InnoDB: Rollback operations on all aux tables of table .* All the fts index associated with the table are marked as corrupted. Please rebuild the index again."); + +call mtr.add_suppression("\\[ERROR\\] InnoDB: Flagged corruption of .* in table .* in DROP ORPHANED TABLE"); + +SET GLOBAL DEBUG='+d,innodb_test_wrong_fts_aux_table_name'; +CREATE TABLE t1(a TEXT, b TEXT, c TEXT, FULLTEXT `AB`(a, b), FULLTEXT `C1`(c)); +INSERT INTO t1 VALUES('TEST1', 'TEST2', 'TEXT3'); +INSERT INTO t1 VALUES('TEXT1', 'TEXT2', 'TEXT5'); +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +SET SESSION debug='-d,innodb_test_wrong_fts_sys_table_name'; + +# Write file to make mysql-test-run.pl wait for the server to stop +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# Request shutdown +-- send_shutdown +#Call script that will poll the server waiting for it to disapear +-- source include/wait_until_disconnected.inc + +--echo # Restart server. + +# Write file to make mysql-test-run.pl start up the server again, ensure +# that no background threads are started, so that we can check that it +# shuts down properly. +# Set the flag to force the rename fail and restart the server +--exec echo "restart:--debug=d,rename_aux_table_fail" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +# Will fail to alter table +--error ER_INNODB_FT_AUX_NOT_HEX_ID +ALTER TABLE t1 ADD FULLTEXT(b); + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); + +--echo # Restart server. +-- source include/restart_mysqld.inc + +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +--error ER_TABLE_HAS_NO_FT +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +--echo # Drop the corrupted index. +ALTER TABLE t1 DROP INDEX `AB`; +ALTER TABLE t1 DROP INDEX `C1`; + +-- echo # Rebuild the index. +ALTER TABLE t1 ADD FULLTEXT(a, b); +ALTER TABLE t1 ADD FULLTEXT(c); + +--echo # Read the record using fts index. +SELECT * FROM t1 WHERE MATCH(a, b) AGAINST ('TEST2'); +SELECT * FROM t1 WHERE MATCH(c) AGAINST ('TEXT5'); + +TRUNCATE TABLE t1; +DROP TABLE t1; +-- source include/restart_mysqld.inc diff --git a/mysql-test/suite/innodb_fts/t/fulltext_plugin-master.opt b/mysql-test/suite/innodb_fts/t/fulltext_plugin-master.opt new file mode 100644 index 00000000000..a2554caa20b --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/fulltext_plugin-master.opt @@ -0,0 +1 @@ +$SIMPLE_PARSER_OPT diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_index_table.test b/mysql-test/suite/innodb_fts/t/innodb_fts_index_table.test new file mode 100644 index 00000000000..8d37fd8886e --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_index_table.test @@ -0,0 +1,120 @@ +# This is the basic function tests for INNODB_FT_INDEX_TABLE +# and INNODB_FT_INDEX_TABLE in INFORMATION_SCHEMA. + +-- source include/have_innodb.inc + +# Must have debug code to use SET SESSION debug +-- source include/have_debug.inc + +SET GLOBAL INNODB_OPTIMIZE_FULLTEXT_ONLY=1; + +# Test Case 1: Test Result Cache Limit +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + content TEXT + ) ENGINE= InnoDB; + +CREATE FULLTEXT INDEX idx ON articles (title, content); + +INSERT INTO articles (title, content) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','How to use full-text search engine'), + ('Go MySQL Tricks','How to use full text search engine'); + +SET GLOBAL innodb_ft_aux_table="test/articles"; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; + +OPTIMIZE TABLE articles; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; + +SET SESSION debug="+d,fts_instrument_result_cache_limit"; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; + +SET SESSION debug="-d,fts_instrument_result_cache_limit"; + +DROP TABLE articles; + +SET GLOBAL innodb_ft_result_cache_limit=default; + +# Test Case 2: Test Multiple Indexes +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + content TEXT + ) ENGINE= InnoDB; + +CREATE FULLTEXT INDEX idx_t ON articles (title); + +CREATE FULLTEXT INDEX idx_c ON articles (content); + +INSERT INTO articles (title, content) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','How to use full-text search engine'), + ('Go MySQL Tricks','How to use full text search engine'); + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; + +SET GLOBAL innodb_ft_aux_table="test/articles"; + +OPTIMIZE TABLE articles; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; + +DROP TABLE articles; + +SET NAMES utf8; + +# Test Case 3: Test UFT8 Charset +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200) + ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE FULLTEXT INDEX idx ON articles (title); + +INSERT INTO articles (title) VALUES + ('相亲相爱'),('怜香惜爱'),('充满å¯çˆ±'),('爱æ¨äº¤ç»‡'); + +SET GLOBAL innodb_ft_aux_table="test/articles"; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; + +OPTIMIZE TABLE articles; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; + +DROP TABLE articles; + +# Test Case 4: Test GB2312 Charset +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200) + ) ENGINE=InnoDB DEFAULT CHARACTER SET gb2312 COLLATE gb2312_chinese_ci; + +CREATE FULLTEXT INDEX idx ON articles (title); + +INSERT INTO articles (title) VALUES + ('相亲相爱'),('怜香惜爱'),('充满å¯çˆ±'),('爱æ¨äº¤ç»‡'); + +SET GLOBAL innodb_ft_aux_table="test/articles"; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; + +OPTIMIZE TABLE articles; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; + +DROP TABLE articles; + +# Restore global variables +SET GLOBAL innodb_ft_aux_table=default; + +SET GLOBAL INNODB_OPTIMIZE_FULLTEXT_ONLY=default; diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_opt.test b/mysql-test/suite/innodb_fts/t/innodb_fts_opt.test new file mode 100644 index 00000000000..b6a37070d13 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_opt.test @@ -0,0 +1,539 @@ +# +# Tests for optimizations for InnoDB fulltext search (WL#6043) +# + +CREATE TABLE wp( + FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + title VARCHAR(255) NOT NULL DEFAULT '', + text MEDIUMTEXT NOT NULL, + dummy INTEGER, + PRIMARY KEY (FTS_DOC_ID), + UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), + FULLTEXT KEY idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO wp (title, text) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database to database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 SELECT FTS_DOC_ID FROM wp; + +-- disable_result_log +ANALYZE TABLE t1; +ANALYZE TABLE wp; +-- enable_result_log + +# +# Show results of MATCH expressions for reference +# +SELECT FTS_DOC_ID, title, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp; + +# +# Test that filesort is not used if ordering on same match expression +# as where clause +# +--echo No sorting for this query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No sorting for this query even if MATCH is part of an expression +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') > 0.1 +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No sorting even if there are several MATCH expressions as long as the +--echo right one is used in ORDER BY +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score1 DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo Sorting since it is not a single table query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID = t1.i +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since there is no WHERE clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering on multiple columns +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC, FTS_DOC_ID; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering is not descending +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score ASC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting because one is ordering on a different MATCH expression +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('mysql') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +# +# Tests for ORDER BY/LIMIT optimzation +# +--echo No sorting for this query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo Revert to table scan and sorting for this query since not +--echo enough matching rows to satisfy LIMIT clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 3; + +SHOW SESSION STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since no LIMIT clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since there is a WHERE clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE dummy IS NULL +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering is not on a simple MATCH expressions +FLUSH STATUS; + +SELECT title, (MATCH(title, text) AGAINST ('database')) * 100 AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +# +# Test that there is no row accesses if all necessary information is +# available in FTS result +# +--echo No ordinary handler accesses when only accessing FTS_DOC_ID and MATCH +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Still no handler accesses when adding FTS_DOC_ID to WHERE clause +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID > 2; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Still no handler accesses when ordering by MATCH expression +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization is disabled when ordering on FTS_DOC_ID +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY 1 DESC; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization also work with several MATCH expressions +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization does not apply if sorting on a different MATCH expressions +--echo from the one used to access the +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score2 DESC; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +FLUSH STATUS; + +--echo Optimization does not apply for GROUP BY +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +GROUP BY score; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# +# Putting all three optimizations together +# +--echo No sorting and no table access with LIMIT clause and only information +--echo from FTS result +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# +# Count optimization +# +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo If count optimization applies, EXPLAIN shows +--echo "Select tables optimized away." +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +--echo Verify that there was no table access +SHOW STATUS LIKE 'Handler_read%'; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo Optimization applies also to COUNT(expr) as long as expr is not nullable +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT count(*) +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database'); + +--echo Optimization does not apply if not a single table query. +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; + +--echo Optimization does not apply if MATCH is part of an expression +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; + +--echo Optimization does not apply if MATCH is part of an expression +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(dummy) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo Optimization does not apply if COUNT expression is nullable +eval EXPLAIN $query; +eval $query; + +# +# Verify that the queries optimized for InnoDB works with QUERY EXPANSION +# + +# Query will also avoid sorting when query expansion is used +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' WITH QUERY EXPANSION); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + +# +# Verify that the queries optimized for InnoDB works with BOOLEAN MODE +# + +# Query will also avoid sorting when Boolean mode is used +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('+MySQL -database' IN BOOLEAN MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + + +# +# Verify that the queries optimized for InnoDB works with +# BOOLEAN proximity search +# + +# Query will also avoid sorting when Boolean mode is used +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + +# +# Check that nothing goes wrong when combining different modes +# +SELECT title, + MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC; + +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('MySQL database' WITH QUERY EXPANSION) +ORDER BY score DESC; + +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC; + + +# +# Verify that the queries optimized for InnoDB still works with MyISAM +# +ALTER TABLE wp ENGINE=myisam; + +# Check avoid sorting query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + + +DROP TABLE wp, t1; + + diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_savepoint.test b/mysql-test/suite/innodb_fts/t/innodb_fts_savepoint.test new file mode 100644 index 00000000000..09ccb383bb9 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_savepoint.test @@ -0,0 +1,475 @@ +# This is the basic function tests for innodb FTS savepoint + +-- source include/have_innodb.inc + + +CREATE TABLE articles ( + id INT UNSIGNED NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT (title) + ) ENGINE= InnoDB; + +# Test Part 1: ROLLBACK TO SAVEPOINT +# Test rollback to savepoint 1(S1,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 2(S1,RB1,S2,RB2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 3(S1,S2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 4(S1,S2,RB2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 2: RELEASE SAVEPOINT +# Test release savepoint 1(S1,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 2(S1,RL1,S2,RL2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 3(S1,S2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 4(S1,S2,RL2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 3: RELEASE & ROLLBACK TO SAVEPOINT +# Test release & rollback to savepoint 1(S1,RB1,S2,RL2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 2(S1,RL1,S2,RB2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 3(S1,S2,RL2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 4(S1,S2,RB2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 4: ROLLBACK & SAVEPOINT +# Test rollback 1 +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 2(S1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 3(S1,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 4(S1,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 5(S1,S2,RB2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/t/phrase.test b/mysql-test/suite/innodb_fts/t/phrase.test new file mode 100644 index 00000000000..d8052714120 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/phrase.test @@ -0,0 +1,39 @@ +-- source include/have_innodb.inc + +# +# BUG#20465273 - FULLTEXT SEARCH BEHAVIOUR WITH MYISAM VS. INNODB (WRONG RESULT WITH INNODB) +# + +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +) ENGINE=InnoDB; + +INSERT INTO articles (title,body) VALUES + (NULL, 'mysql good database'), + (NULL, ' mysql good database'), + ('', 'mysql good database'), + ('', ' mysql good database'), + (' ', 'mysql good database'), + ('mysql', 'good database'), + ('mysql ', 'good database'), + ('mysql', ' good database'), + ('mysql good database', ''), + ('mysql good database', NULL); + + +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM articles; + +SELECT * FROM articles WHERE MATCH(title, body) + AGAINST('"mysql good database"' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH(title, body) + AGAINST('("mysql good database")' IN BOOLEAN MODE); + +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/t/subexpr.test b/mysql-test/suite/innodb_fts/t/subexpr.test new file mode 100644 index 00000000000..632940661b5 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/subexpr.test @@ -0,0 +1,58 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #20028323 INNODB FULLTEXT BOOLEAN SEARCH INCORRECTLY HANDLES +--echo # PARENTHESES +--echo # + +CREATE TABLE t1 ( + f1 INT NOT NULL AUTO_INCREMENT, + f2 TEXT NOT NULL, + PRIMARY KEY (f1), + FULLTEXT (f2) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO t1 (f2) VALUES +('Pumpkin soup with cheese bread'), +('Yellow chicken curry'), +('Fresh green vegetables with garlic'); + +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+pumpkin' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+cheese' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+(pumpkin cheese)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(>souffle <tart)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); + +INSERT INTO t1 (f2) VALUES +('This row contains only souffle'), +('This row contains only tart'), +('This row contains only pumpkin'), +('This row contains only cheese'), +('This row contains pumpkin and souffle'), +('This row contains pumpkin and tart'), +('This row contains pumpkin and cheese'), +('This row contains both souffle and tart'), +('This row contains both souffle and cheese'), +('This row contains both tart and cheese'), +('This row contains all three souffle, pumpkin and tart'), +('This row contains all four cheese, souffle, pumpkin and tart'); + +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+pumpkin' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+cheese' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+(pumpkin cheese)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(>souffle <tart)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/sync.test b/mysql-test/suite/innodb_fts/t/sync.test new file mode 100644 index 00000000000..9389fd72765 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/sync.test @@ -0,0 +1,170 @@ +# +# BUG#22516559 MYSQL INSTANCE STALLS WHEN SYNCING FTS INDEX +# + +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/not_valgrind.inc +--source include/not_embedded.inc +--source include/not_crashrep.inc +--source include/count_sessions.inc + +connect (con1,localhost,root,,); +connection default; + +--echo # Case 1: Test select and insert(row in both disk and cache) +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +INSERT INTO t1(title) VALUES('mysql'); +INSERT INTO t1(title) VALUES('database'); + +connection con1; + +SET SESSION debug="+d,fts_instrument_sync_debug"; + +SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR selected'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection default; + +SET DEBUG_SYNC= 'now WAIT_FOR written'; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +SET DEBUG_SYNC= 'now SIGNAL selected'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +connection default; + +DROP TABLE t1; + +--echo # Case 2: Test insert and insert(sync) +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +INSERT INTO t1(title) VALUES('mysql'); +INSERT INTO t1(title) VALUES('database'); + +connection con1; + +SET SESSION debug="+d,fts_instrument_sync_debug"; + +SET DEBUG_SYNC= 'fts_write_node SIGNAL written WAIT_FOR inserted'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection default; + +SET DEBUG_SYNC= 'now WAIT_FOR written'; + +INSERT INTO t1(title) VALUES('mysql database'); + +SET DEBUG_SYNC= 'now SIGNAL inserted'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +connection default; +disconnect con1; + +DROP TABLE t1; + +--echo # Case 3: Test insert crash recovery +--let $_expect_file_name=$MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect + +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +INSERT INTO t1(title) VALUES('database'); + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +SET SESSION debug="+d,fts_instrument_sync_debug,fts_write_node_crash"; + +--error 2013 +INSERT INTO t1(title) VALUES('mysql'); + +--source include/start_mysqld.inc + +-- echo After restart +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database'); + +SET SESSION debug="+d,fts_instrument_sync_debug"; + +INSERT INTO t1(title) VALUES('mysql'); + +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database'); + +DROP TABLE t1; + +--echo # Case 4: Test sync commit & rollback in background +CREATE TABLE t1( + id INT AUTO_INCREMENT, + title VARCHAR(100), + FULLTEXT(title), + PRIMARY KEY(id)) ENGINE=InnoDB; + +SET SESSION debug="+d,fts_instrument_sync"; +INSERT INTO t1(title) VALUES('mysql'); +SET SESSION debug="-d,fts_instrument_sync"; + +--source include/restart_mysqld.inc + +SET GLOBAL debug="+d,fts_instrument_sync,fts_instrument_sync_interrupted"; +INSERT INTO t1(title) VALUES('database'); +SET GLOBAL debug="-d,fts_instrument_sync,fts_instrument_sync_interrupted"; + +SET SESSION debug="+d,fts_instrument_sync_debug"; +INSERT INTO t1(title) VALUES('good'); +SET SESSION debug="-d,fts_instrument_sync_debug"; + +SET GLOBAL innodb_ft_aux_table="test/t1"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM t1 WHERE MATCH(title) AGAINST ('mysql database good'); + +DROP TABLE t1; + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb_fts/t/sync_block.test b/mysql-test/suite/innodb_fts/t/sync_block.test new file mode 100644 index 00000000000..adfcb703139 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/sync_block.test @@ -0,0 +1,125 @@ +# +# BUG#22516559 MYSQL INSTANCE STALLS WHEN SYNCING FTS INDEX +# + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_log_bin.inc +--source include/count_sessions.inc + +SET @old_log_output = @@global.log_output; +SET @old_slow_query_log = @@global.slow_query_log; +SET @old_general_log = @@global.general_log; +SET @old_long_query_time = @@global.long_query_time; +SET @old_binlog_order_commits = @@global.binlog_order_commits; + +SET GLOBAL log_output = 'TABLE'; +SET GLOBAL general_log = 1; +SET GLOBAL slow_query_log = 1; +SET GLOBAL long_query_time = 1; +SET GLOBAL binlog_order_commits = 1; + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connection default; + +--echo # Case 1: Sync blocks DML(insert) on the same table. +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +connection con1; + +SET GLOBAL debug="+d,fts_instrument_sync_debug,fts_instrument_sync_sleep"; + +SET DEBUG_SYNC= 'fts_sync_begin SIGNAL begin WAIT_FOR continue'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection con2; + +SET DEBUG_SYNC= 'now WAIT_FOR begin'; + +send SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); + +connection default; +SET DEBUG_SYNC= 'now SIGNAL continue'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +connection con2; +--echo /* conneciton con2 */ SELECT * FROM t1 WHERE MATCH(title) AGAINST('mysql database'); +--reap + +connection default; +-- echo # make con1 & con2 show up in mysql.slow_log +SELECT SLEEP(2); +-- echo # slow log results should only contain INSERT INTO t1. +SELECT sql_text FROM mysql.slow_log WHERE query_time >= '00:00:02'; + +SET GLOBAL debug="-d,fts_instrument_sync_debug,fts_instrument_sync_sleep"; +TRUNCATE TABLE mysql.slow_log; + +DROP TABLE t1; + +--echo # Case 2: Sync blocks DML(insert) on other tables. +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT(title) +) ENGINE = InnoDB; + +CREATE TABLE t2(id INT); + +connection con1; + +SET GLOBAL debug="+d,fts_instrument_sync_request,fts_instrument_sync_sleep"; + +SET DEBUG_SYNC= 'fts_instrument_sync_request SIGNAL begin WAIT_FOR continue'; + +send INSERT INTO t1(title) VALUES('mysql database'); + +connection con2; + +SET DEBUG_SYNC= 'now WAIT_FOR begin'; + +send INSERT INTO t2 VALUES(1); + +connection default; +SET DEBUG_SYNC= 'now SIGNAL continue'; + +connection con1; +--echo /* connection con1 */ INSERT INTO t1(title) VALUES('mysql database'); +--reap + +connection con2; +--echo /* conneciton con2 */ INSERT INTO t2 VALUES(1); +--reap + +connection default; +-- echo # make con1 & con2 show up in mysql.slow_log +SELECT SLEEP(2); +-- echo # slow log results should be empty here. +SELECT sql_text FROM mysql.slow_log WHERE query_time >= '00:00:02'; + +SET GLOBAL debug="-d,fts_instrument_sync_request,fts_instrument_sync_sleep"; +TRUNCATE TABLE mysql.slow_log; + +DROP TABLE t1,t2; + +disconnect con1; +disconnect con2; + +--source include/wait_until_count_sessions.inc + +-- echo # Restore slow log settings. +SET GLOBAL log_output = @old_log_output; +SET GLOBAL general_log = @old_general_log; +SET GLOBAL slow_query_log = @old_slow_query_log; +SET GLOBAL long_query_time = @old_long_query_time; +SET GLOBAL binlog_order_commits = @old_binlog_order_commits; diff --git a/mysql-test/suite/innodb_zip/t/innodb-restart.test b/mysql-test/suite/innodb_zip/t/innodb-restart.test new file mode 100644 index 00000000000..c890da9d3b0 --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb-restart.test @@ -0,0 +1,604 @@ +# +# These test make sure that tables are visible after rebooting +# + +--source include/have_innodb.inc +--source include/have_partition.inc +--source include/not_embedded.inc +SET default_storage_engine=InnoDB; + +--disable_query_log +# This error is expected in the error log for this test. +call mtr.add_suppression("InnoDB: Error number 17 means 'File exists'"); +--enable_query_log + +--echo # +--echo # A series of tests to make sure tables are opened after restart. +--echo # Bug#13357607 Compressed file-per-table tablespaces fail to open +--echo # +# This bug was introduced without a regression test failing since +# there were no tests showing that tablespaces could e created and +# then read after reboot. +# + +--disable_query_log +let $MYSQL_DATA_DIR= `select @@datadir`; +let $data_directory = DATA DIRECTORY='$MYSQL_TMP_DIR/alt_dir'; + +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +let $innodb_file_format_orig=`select @@innodb_file_format`; +--enable_query_log + +set global innodb_file_per_table=on; +set global innodb_file_format='Barracuda'; + +--echo # +--echo # Create and insert records into a DYNAMIC row formatted table. +--echo # +CREATE TABLE t1(c1 DOUBLE AUTO_INCREMENT KEY, c2 CHAR(10), c3 VARCHAR(100), c4 DATE, c5 TEXT) + ROW_FORMAT=REDUNDANT ENGINE=InnoDB; +INSERT INTO t1 VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t1 (SELECT 0, c2, c3, c4, c5 FROM t1); +INSERT INTO t1 (SELECT 0, c2, c3, c4, c5 FROM t1); +INSERT INTO t1 (SELECT 0, c2, c3, c4, c5 FROM t1); +INSERT INTO t1 (SELECT 0, c2, c3, c4, c5 FROM t1); +SHOW CREATE TABLE t1; +SELECT count(*) FROM t1; + +--echo # +--echo # Create and insert records into a COMPACT row formatted table. +--echo # +CREATE TABLE t2(c1 DOUBLE AUTO_INCREMENT KEY, c2 CHAR(10), c3 VARCHAR(100), c4 DATE, c5 TEXT) + ROW_FORMAT=COMPACT ENGINE=InnoDB; +INSERT INTO t2 VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t2 (SELECT 0, c2, c3, c4, c5 FROM t2); +INSERT INTO t2 (SELECT 0, c2, c3, c4, c5 FROM t2); +INSERT INTO t2 (SELECT 0, c2, c3, c4, c5 FROM t2); +INSERT INTO t2 (SELECT 0, c2, c3, c4, c5 FROM t2); +SHOW CREATE TABLE t2; +SELECT count(*) FROM t2; + +--echo # +--echo # Create and insert records into a COMPRESSED row formatted table. +--echo # +CREATE TABLE t3(c1 DOUBLE AUTO_INCREMENT KEY, c2 CHAR(10), c3 VARCHAR(100), c4 DATE, c5 TEXT) + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 ENGINE=InnoDB; +INSERT INTO t3 VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t3 (SELECT 0, c2, c3, c4, c5 FROM t3); +INSERT INTO t3 (SELECT 0, c2, c3, c4, c5 FROM t3); +INSERT INTO t3 (SELECT 0, c2, c3, c4, c5 FROM t3); +INSERT INTO t3 (SELECT 0, c2, c3, c4, c5 FROM t3); +SHOW CREATE TABLE t3; +SELECT count(*) FROM t3; + +--echo # +--echo # Create and insert records into a DYNAMIC row formatted table. +--echo # +CREATE TABLE t4(c1 DOUBLE AUTO_INCREMENT KEY, c2 CHAR(10), c3 VARCHAR(100), c4 DATE, c5 TEXT) + ROW_FORMAT=DYNAMIC ENGINE=InnoDB; +INSERT INTO t4 VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t4 (SELECT 0, c2, c3, c4, c5 FROM t4); +INSERT INTO t4 (SELECT 0, c2, c3, c4, c5 FROM t4); +INSERT INTO t4 (SELECT 0, c2, c3, c4, c5 FROM t4); +INSERT INTO t4 (SELECT 0, c2, c3, c4, c5 FROM t4); +SHOW CREATE TABLE t4; +SELECT count(*) FROM t4; + +--echo # +--echo # Create and insert records into a table that uses a remote DATA DIRECTORY. +--echo # +--mkdir $MYSQL_TMP_DIR/alt_dir +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t5(c1 DOUBLE AUTO_INCREMENT KEY, c2 CHAR(10), c3 VARCHAR(100), c4 DATE, c5 TEXT) + ROW_FORMAT=DYNAMIC ENGINE=InnoDB $data_directory; +INSERT INTO t5 VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5; +SELECT count(*) FROM t5; + +--echo # +--echo # Create and insert records into a partitioned table that uses +--echo # a remote DATA DIRECTORY for each partition. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t6( + c1 INT AUTO_INCREMENT KEY, c2 CHAR(10), c3 VARCHAR(100), c4 DATE, c5 TEXT) + ROW_FORMAT=COMPRESSED ENGINE=InnoDB + PARTITION BY HASH(c1) ( + PARTITION p0 DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir', + PARTITION p1 DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir', + PARTITION p2 DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir'); +INSERT INTO t6 VALUES (0, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t6 (SELECT 0, c2, c3, c4, c5 FROM t6); +INSERT INTO t6 (SELECT 0, c2, c3, c4, c5 FROM t6); +INSERT INTO t6 (SELECT 0, c2, c3, c4, c5 FROM t6); +INSERT INTO t6 (SELECT 0, c2, c3, c4, c5 FROM t6); +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t6; +SELECT count(*) FROM t6; + +--echo # +--echo # Create and insert records into a subpartitioned table that uses +--echo # a remote DATA DIRECTORY for each subpartition. +--echo # +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t7( + c1 INT AUTO_INCREMENT KEY, c2 CHAR(10), c3 VARCHAR(100), c4 DATE, c5 TEXT) + ROW_FORMAT=DYNAMIC ENGINE=InnoDB + PARTITION BY RANGE(c1) SUBPARTITION BY HASH(c1) ( + PARTITION p0 VALUES LESS THAN (10) ( + SUBPARTITION s0 DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir', + SUBPARTITION s1 DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir'), + PARTITION p1 VALUES LESS THAN MAXVALUE ( + SUBPARTITION s2 DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir', + SUBPARTITION s3 DATA DIRECTORY = '$MYSQL_TMP_DIR/alt_dir')); +INSERT INTO t7 VALUES (0, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t7 (SELECT 0, c2, c3, c4, c5 FROM t7); +INSERT INTO t7 (SELECT 0, c2, c3, c4, c5 FROM t7); +INSERT INTO t7 (SELECT 0, c2, c3, c4, c5 FROM t7); +INSERT INTO t7 (SELECT 0, c2, c3, c4, c5 FROM t7); +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t7; +SELECT count(*) FROM t7; + +--echo # +--echo # Show these tables in information_schema. +--echo # +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name like 'test%' ORDER BY name; +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY name; +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +--echo # +--echo # Shutdown the server and list the tablespace OS files +--echo # +--source include/shutdown_mysqld.inc + +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir +--list_files $MYSQL_TMP_DIR/alt_dir +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Start the server and show that tables are still visible and accessible. +--echo # +--source include/start_mysqld.inc + +SHOW VARIABLES LIKE 'innodb_file_per_table'; +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +SHOW CREATE TABLE t4; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t6; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t7; + +INSERT INTO t1 (SELECT 0, c2, c3, c4, c5 FROM t1); +INSERT INTO t2 (SELECT 0, c2, c3, c4, c5 FROM t2); +INSERT INTO t3 (SELECT 0, c2, c3, c4, c5 FROM t3); +INSERT INTO t4 (SELECT 0, c2, c3, c4, c5 FROM t4); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); +INSERT INTO t6 (SELECT 0, c2, c3, c4, c5 FROM t6); +INSERT INTO t7 (SELECT 0, c2, c3, c4, c5 FROM t7); + +SELECT count(*) FROM t1; +SELECT count(*) FROM t2; +SELECT count(*) FROM t3; +SELECT count(*) FROM t4; +SELECT count(*) FROM t5; +SELECT count(*) FROM t6; +SELECT count(*) FROM t7; + +--echo # +--echo # Show these tables in information_schema. +--echo # +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +SELECT name,n_cols,file_format,row_format + FROM information_schema.innodb_sys_tables + WHERE name like 'test%' ORDER BY name; +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +SELECT name,file_format,row_format + FROM information_schema.innodb_sys_tablespaces + WHERE name LIKE 'test%' ORDER BY name; +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result ./ MYSQL_DATA_DIR/ $MYSQL_DATA_DIR MYSQL_DATA_DIR $MYSQL_TMP_DIR MYSQL_TMP_DIR +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +# Tablespace for t4 will be moved later from default directory to a new directory +# and a isl file will be created not using InnoDB. + +--echo # +--echo # Truncate the remote tablespaces. +--echo # +TRUNCATE TABLE t5; +ALTER TABLE t6 TRUNCATE PARTITION p2; +ALTER TABLE t7 TRUNCATE PARTITION p1; + +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +INSERT INTO t5 VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot'); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); +INSERT INTO t5 (SELECT 0, c2, c3, c4, c5 FROM t5); + +SELECT count(*) FROM t5; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5; + +SELECT count(*) FROM t6; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t6; + +SELECT count(*) FROM t7; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t7; + +--echo # +--echo # Shutdown the server and make a backup of a tablespace +--echo # +--source include/shutdown_mysqld.inc + +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5.ibd $MYSQL_TMP_DIR/alt_dir/test/t5.ibd.bak +--copy_file $MYSQL_DATA_DIR/test/t5.isl $MYSQL_DATA_DIR/test/t5.isl.bak +--copy_file $MYSQL_DATA_DIR/test/t5.frm $MYSQL_DATA_DIR/test/t5.frm.bak + +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Start the server and show the tablespaces. +--echo # +--source include/start_mysqld.inc + +SHOW VARIABLES LIKE 'innodb_file_per_table'; + +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +SELECT count(*) FROM t5; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t5; + +SELECT count(*) FROM t6; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t6; + +SELECT count(*) FROM t7; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t7; + +--echo # +--echo # Try to rename a tablespace to a file that already exists +--echo # + +--copy_file $MYSQL_DATA_DIR/test/t5.frm.bak $MYSQL_DATA_DIR/test/t55.frm +--error ER_TABLE_EXISTS_ERROR +RENAME TABLE t5 TO t55; +--remove_file $MYSQL_DATA_DIR/test/t55.frm +--remove_file $MYSQL_DATA_DIR/test/t5.frm.bak + +--copy_file $MYSQL_DATA_DIR/test/t5.isl.bak $MYSQL_DATA_DIR/test/t55.isl +--error ER_ERROR_ON_RENAME +RENAME TABLE t5 TO t55; +--remove_file $MYSQL_DATA_DIR/test/t55.isl +--remove_file $MYSQL_DATA_DIR/test/t5.isl.bak + +#--copy_file $MYSQL_TMP_DIR/alt_dir/test/t5.ibd.bak $MYSQL_TMP_DIR/alt_dir/test/t55.ibd +# This RENAME TABLE works of Linux but gets ER_ERROR_ON_RENAME on Windows +#--error ER_ERROR_ON_RENAME +#RENAME TABLE t5 TO t55; +#--remove_file $MYSQL_TMP_DIR/alt_dir/test/t55.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t5.ibd.bak + +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Rename file table and tablespace +--echo # + +RENAME TABLE t5 TO t55; +RENAME TABLE t6 TO t66; +RENAME TABLE t7 TO t77; + +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +INSERT INTO t55 (SELECT 0, c2, c3, c4, c5 FROM t55); +SELECT count(*) FROM t55; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t55; + +INSERT INTO t66 (SELECT 0, c2, c3, c4, c5 FROM t66); +SELECT count(*) FROM t66; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t66; + +INSERT INTO t77 (SELECT 0, c2, c3, c4, c5 FROM t77); +SELECT count(*) FROM t77; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t77; + +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/alt_dir/test + +--echo # +--echo # Restart the server +--echo # +--source include/restart_mysqld.inc +SHOW VARIABLES LIKE 'innodb_file_per_table'; + +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +INSERT INTO t55 (SELECT 0, c2, c3, c4, c5 FROM t55); +SELECT count(*) FROM t55; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t55; + +INSERT INTO t66 (SELECT 0, c2, c3, c4, c5 FROM t66); +SELECT count(*) FROM t66; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t66; + +INSERT INTO t77 (SELECT 0, c2, c3, c4, c5 FROM t77); +SELECT count(*) FROM t77; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t77; + +--echo # +--echo # Shutdown the server +--echo # +--source include/shutdown_mysqld.inc + +--echo # +--echo # Move the remote tablespaces to a new location and change the ISL files +--echo # +--mkdir $MYSQL_TMP_DIR/new_dir +--mkdir $MYSQL_TMP_DIR/new_dir/test +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # Moving tablespace 't4' from MYSQL_DATA_DIR to MYSQL_TMP_DIR/new_dir +--copy_file $MYSQL_DATA_DIR/test/t4.ibd $MYSQL_TMP_DIR/new_dir/test/t4.ibd +--remove_file $MYSQL_DATA_DIR/test/t4.ibd +--exec echo $MYSQL_TMP_DIR/new_dir/test/t4.ibd > $MYSQL_DATA_DIR/test/t4.isl + +--echo # Moving tablespace 't55' from MYSQL_TMP_DIR/alt_dir to MYSQL_TMP_DIR/new_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t55.ibd $MYSQL_TMP_DIR/new_dir/test/t55.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t55.ibd +--remove_file $MYSQL_DATA_DIR/test/t55.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t55.ibd > $MYSQL_DATA_DIR/test/t55.isl + +--echo # Moving tablespace 't66' from MYSQL_TMP_DIR/alt_dir to MYSQL_TMP_DIR/new_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t66#P#p0.ibd $MYSQL_TMP_DIR/new_dir/test/t66#P#p0.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t66#P#p1.ibd $MYSQL_TMP_DIR/new_dir/test/t66#P#p1.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t66#P#p2.ibd $MYSQL_TMP_DIR/new_dir/test/t66#P#p2.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t66#P#p0.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t66#P#p1.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t66#P#p2.ibd +--remove_file $MYSQL_DATA_DIR/test/t66#P#p0.isl +--remove_file $MYSQL_DATA_DIR/test/t66#P#p1.isl +--remove_file $MYSQL_DATA_DIR/test/t66#P#p2.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t66#P#p0.ibd > $MYSQL_DATA_DIR/test/t66#P#p0.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t66#P#p1.ibd > $MYSQL_DATA_DIR/test/t66#P#p1.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t66#P#p2.ibd > $MYSQL_DATA_DIR/test/t66#P#p2.isl + +--echo # Moving tablespace 't77' from MYSQL_TMP_DIR/alt_dir to MYSQL_TMP_DIR/new_dir +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p0#SP#s0.ibd $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s0.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p0#SP#s1.ibd $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s1.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p1#SP#s2.ibd $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s2.ibd +--copy_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p1#SP#s3.ibd $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s3.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p0#SP#s0.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p0#SP#s1.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p1#SP#s2.ibd +--remove_file $MYSQL_TMP_DIR/alt_dir/test/t77#P#p1#SP#s3.ibd +--remove_file $MYSQL_DATA_DIR/test/t77#P#p0#SP#s0.isl +--remove_file $MYSQL_DATA_DIR/test/t77#P#p0#SP#s1.isl +--remove_file $MYSQL_DATA_DIR/test/t77#P#p1#SP#s2.isl +--remove_file $MYSQL_DATA_DIR/test/t77#P#p1#SP#s3.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s0.ibd > $MYSQL_DATA_DIR/test/t77#P#p0#SP#s0.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s1.ibd > $MYSQL_DATA_DIR/test/t77#P#p0#SP#s1.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s2.ibd > $MYSQL_DATA_DIR/test/t77#P#p1#SP#s2.isl +--exec echo $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s3.ibd > $MYSQL_DATA_DIR/test/t77#P#p1#SP#s3.isl + +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/alt_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/alt_dir/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # +--echo # Start the server and check tablespaces. +--echo # +--source include/start_mysqld.inc + +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +INSERT INTO t4 (SELECT 0, c2, c3, c4, c5 FROM t4); +SELECT count(*) FROM t4; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t4; + +INSERT INTO t55 (SELECT 0, c2, c3, c4, c5 FROM t55); +SELECT count(*) FROM t55; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t55; + +INSERT INTO t66 (SELECT 0, c2, c3, c4, c5 FROM t66); +SELECT count(*) FROM t66; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t66; + +INSERT INTO t77 (SELECT 0, c2, c3, c4, c5 FROM t77); +SELECT count(*) FROM t77; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +SHOW CREATE TABLE t77; + + +--echo # +--echo # Shutdown the server +--echo # +--source include/shutdown_mysqld.inc + +--echo # +--echo # Move the remote tablespaces back to the default datadir and delete the ISL file. +--echo # + +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # Moving 't4' from MYSQL_TMP_DIR/new_dir to MYSQL_DATA_DIR +--copy_file $MYSQL_TMP_DIR/new_dir/test/t4.ibd $MYSQL_DATA_DIR/test/t4.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t4.ibd +--remove_file $MYSQL_DATA_DIR/test/t4.isl + +--echo # Moving 't55' from MYSQL_TMP_DIR/new_dir to MYSQL_DATA_DIR +--copy_file $MYSQL_TMP_DIR/new_dir/test/t55.ibd $MYSQL_DATA_DIR/test/t55.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t55.ibd +--remove_file $MYSQL_DATA_DIR/test/t55.isl + +--echo # Moving 't66' from MYSQL_TMP_DIR/new_dir to MYSQL_DATA_DIR +--copy_file $MYSQL_TMP_DIR/new_dir/test/t66#P#p0.ibd $MYSQL_DATA_DIR/test/t66#P#p0.ibd +--copy_file $MYSQL_TMP_DIR/new_dir/test/t66#P#p1.ibd $MYSQL_DATA_DIR/test/t66#P#p1.ibd +--copy_file $MYSQL_TMP_DIR/new_dir/test/t66#P#p2.ibd $MYSQL_DATA_DIR/test/t66#P#p2.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t66#P#p0.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t66#P#p1.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t66#P#p2.ibd +--remove_file $MYSQL_DATA_DIR/test/t66#P#p0.isl +--remove_file $MYSQL_DATA_DIR/test/t66#P#p1.isl +--remove_file $MYSQL_DATA_DIR/test/t66#P#p2.isl + +--echo # Moving 't77' from MYSQL_TMP_DIR/new_dir to MYSQL_DATA_DIR +--copy_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s0.ibd $MYSQL_DATA_DIR/test/t77#P#p0#SP#s0.ibd +--copy_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s1.ibd $MYSQL_DATA_DIR/test/t77#P#p0#SP#s1.ibd +--copy_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s2.ibd $MYSQL_DATA_DIR/test/t77#P#p1#SP#s2.ibd +--copy_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s3.ibd $MYSQL_DATA_DIR/test/t77#P#p1#SP#s3.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s0.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p0#SP#s1.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s2.ibd +--remove_file $MYSQL_TMP_DIR/new_dir/test/t77#P#p1#SP#s3.ibd +--remove_file $MYSQL_DATA_DIR/test/t77#P#p0#SP#s0.isl +--remove_file $MYSQL_DATA_DIR/test/t77#P#p0#SP#s1.isl +--remove_file $MYSQL_DATA_DIR/test/t77#P#p1#SP#s2.isl +--remove_file $MYSQL_DATA_DIR/test/t77#P#p1#SP#s3.isl + +--echo ---- MYSQL_DATA_DIR/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_DATA_DIR/test +--echo ---- MYSQL_TMP_DIR/new_dir/test +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--list_files $MYSQL_TMP_DIR/new_dir/test + +--echo # +--echo # Start the server and check tablespaces. +--echo # +-- source include/start_mysqld.inc + +--replace_regex /#P#/#p#/ /#SP#/#sp#/ +--replace_result $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SELECT path FROM information_schema.innodb_sys_datafiles + WHERE path LIKE '%test%' ORDER BY space; + +INSERT INTO t4 (SELECT 0, c2, c3, c4, c5 FROM t4); +SELECT count(*) FROM t4; +--replace_result $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SHOW CREATE TABLE t4; + +INSERT INTO t55 (SELECT 0, c2, c3, c4, c5 FROM t55); +SELECT count(*) FROM t55; +--replace_result $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SHOW CREATE TABLE t55; + +INSERT INTO t66 (SELECT 0, c2, c3, c4, c5 FROM t66); +SELECT count(*) FROM t66; +--replace_result $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SHOW CREATE TABLE t66; + +INSERT INTO t77 (SELECT 0, c2, c3, c4, c5 FROM t77); +SELECT count(*) FROM t77; +--replace_result $MYSQL_DATA_DIR MYSQL_DATA_DIR ./ MYSQL_DATA_DIR/ +SHOW CREATE TABLE t77; + + +--echo # +--echo # Cleanup +--echo # + +DROP TABLE t4; +DROP TABLE t55; +DROP TABLE t66; +DROP TABLE t77; + +--rmdir $MYSQL_TMP_DIR/alt_dir/test +--rmdir $MYSQL_TMP_DIR/alt_dir +--rmdir $MYSQL_TMP_DIR/new_dir/test +--rmdir $MYSQL_TMP_DIR/new_dir + +-- disable_query_log +eval set global innodb_file_format=$innodb_file_format_orig; +eval set global innodb_file_per_table=$innodb_file_per_table_orig; +-- enable_query_log + diff --git a/mysql-test/suite/innodb_zip/t/innodb-wl5522-debug-zip.test b/mysql-test/suite/innodb_zip/t/innodb-wl5522-debug-zip.test new file mode 100644 index 00000000000..1d18b2bcdb0 --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb-wl5522-debug-zip.test @@ -0,0 +1,758 @@ +# Not supported in embedded +--source include/not_embedded.inc + +# This test case needs to crash the server. Needs a debug server. +--source include/have_debug.inc + +# Don't test this under valgrind, memory leaks will occur. +--source include/not_valgrind.inc + +# Avoid CrashReporter popup on Mac +--source include/not_crashrep.inc + +-- source include/have_innodb.inc + +# compressed table in tests are with sizes KEY_BLOCK_SIZE 1,2,4,8,16 +# Table creatation fails if KEY_BLOCK_SIZE > innodb-page-size,so +# allow test to run only when innodb-page-size=16 +--source include/have_innodb_16k.inc + + +let MYSQLD_DATADIR =`SELECT @@datadir`; +let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; +let $innodb_file_format = `SELECT @@innodb_file_format`; +let $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; +let $pathfix=/: '.*test_wl5522.*t1.ibd'/: 'test_wl5522\\t1.ibd'/; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +SET GLOBAL innodb_file_format = `Barracuda`; +SELECT @@innodb_file_format; + +SET SESSION innodb_strict_mode=1; +SELECT @@SESSION.innodb_strict_mode; + + + +DROP DATABASE IF EXISTS test_wl5522; +CREATE DATABASE test_wl5522; + +# Create the table that we will use for crash recovery (during IMPORT) +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb +ROW_FORMAT=COMPRESSED; +INSERT INTO test_wl5522.t1 VALUES (1), (2), (3), (4); + +--replace_regex /, .*).*t1.cfg/, Bad file descriptor) t1.cfg/ + +FLUSH TABLES test_wl5522.t1 FOR EXPORT; + +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test_wl5522", "t1"); +EOF +UNLOCK TABLES; + +DROP TABLE test_wl5522.t1; + +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb +ROW_FORMAT=COMPRESSED; +INSERT INTO test_wl5522.t1 VALUES (1); + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test_wl5522", "t1"); +EOF + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +##### Before commit crash +SET SESSION debug="+d,ib_import_before_commit_crash"; + +--error ER_TABLESPACE_DISCARDED +SELECT * FROM test_wl5522.t1; + +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Execute the statement that causes the crash +--error 2013 +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SET SESSION debug="-d,ib_import_before_commit_crash"; +#### Before commit crash + +# Check that the DD is consistent after recovery + +##### Before checkpoint crash +SET SESSION debug="+d,ib_import_before_checkpoint_crash"; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Don't start up the server right away. +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +# Execute the statement that causes the crash +--error 2013 +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +# After the above test the results are non-deterministic, +# delete the old tablespace files and drop the table, +# recreate the table and do a proper import. +-- source include/wait_until_disconnected.inc +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +--echo # Restart and reconnect to the server +--enable_reconnect +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +--disable_reconnect + +SET SESSION debug="-d,ib_import_before_checkpoint_crash"; +#### Before checkpoint crash + +# After the above test the results are non-deterministic, recreate the table +# and do a proper import. + +DROP TABLE test_wl5522.t1; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +SET GLOBAL innodb_file_format = `Barracuda`; +SELECT @@innodb_file_format; + +SET SESSION innodb_strict_mode=1; +SELECT @@SESSION.innodb_strict_mode; + +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb +ROW_FORMAT=COMPRESSED; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; +CHECK TABLE test_wl5522.t1; + +SELECT COUNT(*) FROM test_wl5522.t1; + +INSERT INTO test_wl5522.t1 VALUES(400), (500), (600); + +SELECT * FROM test_wl5522.t1; + +DROP TABLE test_wl5522.t1; + +# Test handling of internal failure error +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb +ROW_FORMAT=COMPRESSED; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +# Test failure after reset of space id and LSN in the tablespace +SET SESSION debug="+d,ib_import_internal_error"; + +--replace_regex /'.*t1.cfg'/'t1.cfg'/ + +--error ER_INTERNAL_ERROR +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_internal_error"; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +DROP TABLE test_wl5522.t1; + + +# Test failure after reset of space id and LSN in the tablespace +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb +ROW_FORMAT=COMPRESSED; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +# Test failure after reset of space id and LSN in the tablespace +SET SESSION debug="+d,ib_import_reset_space_and_lsn_failure"; + +--replace_regex /'.*t1.cfg'/'t1.cfg'/ + +--error ER_INTERNAL_ERROR +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="-d,ib_import_reset_space_and_lsn_failure"; + +# Test failure after attempting a tablespace open +SET SESSION debug="+d,ib_import_open_tablespace_failure"; + +--replace_regex /file: '.*t1.ibd'/'t1.ibd'/ + +--error ER_FILE_NOT_FOUND +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_open_tablespace_failure"; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +# Test failure after ibuf check +SET SESSION debug="+d,ib_import_check_bitmap_failure"; + +# Need proper mapping of error codes :-( +--error ER_NOT_KEYFILE +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_check_bitmap_failure"; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +# Test failure after adjusting the cluster index root page +SET SESSION debug="+d,ib_import_cluster_root_adjust_failure"; + +--error ER_NOT_KEYFILE +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_cluster_root_adjust_failure"; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +# Test failure after importing the cluster index +SET SESSION debug="+d,ib_import_cluster_failure"; + +--error ER_NOT_KEYFILE +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_cluster_failure"; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +# Test failure after importing the secondary index(es) +SET SESSION debug="+d,ib_import_sec_root_adjust_failure"; + +--error ER_NOT_KEYFILE +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_sec_root_adjust_failure"; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +# Test failure after importing the cluster index +SET SESSION debug="+d,ib_import_set_max_rowid_failure"; + +--error ER_NOT_KEYFILE +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_set_max_rowid_failure"; + +# Left over from the failed IMPORT +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +DROP TABLE test_wl5522.t1; + +--disable_query_log +# Enable metrics for the counters we are going to use +set global innodb_monitor_enable = purge_stop_count; +set global innodb_monitor_enable = purge_resume_count; +set global innodb_monitor_enable = ibuf_merges; +set global innodb_monitor_enable = ibuf_merges_insert; +--enable_query_log + +# +# Create a large table with delete marked records, disable purge during +# the update so that we can test the IMPORT purge code. +# +CREATE TABLE test_wl5522.t1 ( + c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 BIGINT, + c3 VARCHAR(2048), + c4 VARCHAR(2048), + INDEX idx1(c2), + INDEX idx2(c3(512)), + INDEX idx3(c4(512))) Engine=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; + +# Stop purge so that it doesn't remove the delete marked entries. +SET GLOBAL INNODB_PURGE_STOP_NOW=ON; + +# Disable change buffer merge from the master thread, additionally +# enable aggressive flushing so that more changes are buffered. +SET GLOBAL innodb_disable_background_merge=ON; +SET GLOBAL innodb_monitor_reset = ibuf_merges; +SET GLOBAL innodb_monitor_reset = ibuf_merges_insert; + +INSERT INTO test_wl5522.t1(c2, c3, c4) VALUES + (1, REPEAT('a', 2048), REPEAT('a', 2048)), + (2, REPEAT('b', 2048), REPEAT('b', 2048)), + (3, REPEAT('c', 2048), REPEAT('c', 2048)), + (4, REPEAT('d', 2048), REPEAT('d', 2048)); + +INSERT INTO test_wl5522.t1(c2, c3, c4) SELECT c2, c3, c4 FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1(c2, c3, c4) SELECT c2, c3, c4 FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1(c2, c3, c4) SELECT c2, c3, c4 FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1(c2, c3, c4) SELECT c2, c3, c4 FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1(c2, c3, c4) SELECT c2, c3, c4 FROM test_wl5522.t1; + +DELETE FROM test_wl5522.t1 WHERE c2 = 1; + +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c2 = c2 + c1; +UPDATE test_wl5522.t1 SET c3 = REPEAT("c2", 1024); +UPDATE test_wl5522.t1 SET c4 = REPEAT("c4", 1024); + +SHOW CREATE TABLE test_wl5522.t1; + +SELECT c1, c2 FROM test_wl5522.t1; +SELECT COUNT(*) FROM test_wl5522.t1; +SELECT SUM(c2) FROM test_wl5522.t1; + +SELECT name + FROM information_schema.innodb_metrics + WHERE name = 'ibuf_merges_insert' AND count = 0; + +FLUSH TABLES test_wl5522.t1 FOR EXPORT; + +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test_wl5522", "t1"); +EOF + +UNLOCK TABLES; + +SELECT name + FROM information_schema.innodb_metrics + WHERE name = 'ibuf_merges' AND count > 0; + +SELECT name + FROM information_schema.innodb_metrics + WHERE name = 'ibuf_merges_inserts' AND count > 0; + +SET GLOBAL innodb_disable_background_merge=OFF; + +# Enable normal operation +SET GLOBAL INNODB_PURGE_RUN_NOW=ON; + +DROP TABLE test_wl5522.t1; + +CREATE TABLE test_wl5522.t1 ( + c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 BIGINT, + c3 VARCHAR(2048), + c4 VARCHAR(2048), + INDEX idx1(c2), + INDEX idx2(c3(512)), + INDEX idx3(c4(512))) Engine=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; + +SELECT c1, c2 FROM test_wl5522.t1; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; +CHECK TABLE test_wl5522.t1; + +SELECT c1,c2 FROM test_wl5522.t1; +SELECT COUNT(*) FROM test_wl5522.t1; +SELECT SUM(c2) FROM test_wl5522.t1; + +SHOW CREATE TABLE test_wl5522.t1; + +DROP TABLE test_wl5522.t1; + +#### +# Create a table and save the tablespace and .cfg file, we need to create +# a Btree that has several levels +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +INSERT INTO test_wl5522.t1 VALUES + (100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200)); + +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; +SELECT COUNT(*) FROM test_wl5522.t1; +FLUSH TABLES test_wl5522.t1 FOR EXPORT; + +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test_wl5522", "t1"); +EOF + +UNLOCK TABLES; + +DROP TABLE test_wl5522.t1; + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="+d,ib_import_trigger_corruption_1"; + +--replace_regex /'.*t1.cfg'/'t1.cfg'/ + +--error ER_INTERNAL_ERROR +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_trigger_corruption_1"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +# + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="+d,buf_page_is_corrupt_failure"; + +--replace_regex /'.*t1.cfg'/'t1.cfg'/ + +# Following alter is not failing +#--error ER_INTERNAL_ERROR +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,buf_page_is_corrupt_failure"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="+d,ib_import_trigger_corruption_2"; + +--replace_regex $pathfix + +--error ER_INNODB_INDEX_CORRUPT +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_trigger_corruption_2"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="+d,ib_import_trigger_corruption_3"; + +--replace_regex /'.*t1.cfg'/'t1.cfg'/ + +--error ER_NOT_KEYFILE +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,ib_import_trigger_corruption_3"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +SET SESSION debug="+d,ib_import_create_index_failure_1"; + +ALTER TABLE test_wl5522.t1 ADD INDEX idx(c1); + +SET SESSION debug="-d,ib_import_create_index_failure_1"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +# + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="+d,fil_space_create_failure"; + +--replace_regex $pathfix + +--error ER_FILE_NOT_FOUND +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,fil_space_create_failure"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +# + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="+d,dict_tf_to_fsp_flags_failure"; + +--replace_regex $pathfix + +--error ER_FILE_NOT_FOUND +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,dict_tf_to_fsp_flags_failure"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + +# + +CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM test_wl5522.t1; + +# Restore files +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test_wl5522", "t1"); +EOF + +SET SESSION debug="+d,fsp_flags_is_valid_failure"; + +--replace_regex /'.*t1.cfg'/'t1.cfg'/ + +--error ER_INTERNAL_ERROR +ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; + +SET SESSION debug="-d,fsp_flags_is_valid_failure"; + +DROP TABLE test_wl5522.t1; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test_wl5522", "t1"); +EOF + + +DROP DATABASE test_wl5522; + +set global innodb_monitor_disable = all; +set global innodb_monitor_reset_all = all; + +-- disable_warnings +set global innodb_monitor_enable = default; +set global innodb_monitor_disable = default; +set global innodb_monitor_reset = default; +set global innodb_monitor_reset_all = default; +-- enable_warnings + +--disable_query_log +call mtr.add_suppression("'Resource temporarily unavailable'"); +call mtr.add_suppression("Monitor ibuf_merges is already enabled"); +call mtr.add_suppression("Monitor ibuf_merges_insert is already enabled"); +call mtr.add_suppression("Got error -1 when reading table '.*'"); +call mtr.add_suppression("InnoDB: Table '.*' tablespace is set as discarded."); +call mtr.add_suppression("InnoDB: Tablespace '.*' exists in the cache.*"); +call mtr.add_suppression("InnoDB: Freeing existing tablespace '.*' entry from the cache with id.*"); +call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); +call mtr.add_suppression(".*There was an error writing to the meta data file.*"); +call mtr.add_suppression("InnoDB: Trying to import a tablespace, but could not open the tablespace file"); +call mtr.add_suppression("Unsupported tablespace format"); +call mtr.add_suppression("Error in page .* of index \"GEN_CLUST_INDEX\" of table \"test_wl5522\".\"t1\""); +call mtr.add_suppression("Page is marked as free"); +call mtr.add_suppression("t1.ibd: Page .* at offset .* looks corrupted"); +call mtr.add_suppression("but tablespace with that id or name does not exist"); +call mtr.add_suppression("Failed to find tablespace for table '\"test_wl5522\".\"t1\"' in the cache"); +call mtr.add_suppression("Could not find a valid tablespace file for 'test_wl5522.*t1'"); +--enable_query_log + +#cleanup +--remove_file $MYSQLTEST_VARDIR/tmp/t1.cfg +--remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd + +eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; +eval SET GLOBAL INNODB_FILE_FORMAT=$innodb_file_format; +eval SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; + diff --git a/mysql-test/suite/innodb_zip/t/innodb-wl5522-zip.test b/mysql-test/suite/innodb_zip/t/innodb-wl5522-zip.test new file mode 100644 index 00000000000..dff54a3f0c9 --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb-wl5522-zip.test @@ -0,0 +1,544 @@ +# Not supported in embedded +--source include/not_embedded.inc + +-- source include/have_innodb.inc +# compressed table in tests are with sizes KEY_BLOCK_SIZE 1,2,4,8,16 +# Table creatation fails if KEY_BLOCK_SIZE > innodb-page-size,so +# allow test to run only when innodb-page-size=16 +--source include/have_innodb_16k.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; +let $innodb_file_format = `SELECT @@innodb_file_format`; +let $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +SET GLOBAL innodb_file_format = `Barracuda`; +SELECT @@innodb_file_format; + +SET SESSION innodb_strict_mode=1; +SELECT @@SESSION.innodb_strict_mode; + +let $MYSQLD_TMPDIR = `SELECT @@tmpdir`; +let $MYSQLD_DATADIR = `SELECT @@datadir`; + +CREATE TABLE t1 +(a INT AUTO_INCREMENT PRIMARY KEY, + b char(22), + c varchar(255), + KEY (b)) +ENGINE = InnoDB ROW_FORMAT=COMPRESSED ; + +insert into t1 (b, c) values ('Apa', 'Filler........'), +('Banan', 'Filler........'), ('Cavalry', '..asdasdfaeraf'), +('Devotion', 'asdfuihknaskdf'), ('Evolution', 'lsjndofiabsoibeg'); + +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t1; +SELECT * FROM t1 ORDER BY b,a DESC LIMIT 3; +SELECT * FROM t1 ORDER BY a DESC LIMIT 3; +--list_files $MYSQLD_DATADIR/test +--echo # Restarting server +-- source include/restart_mysqld.inc +--echo # Done restarting server +FLUSH TABLE t1 FOR EXPORT; +--echo # List before copying files +--list_files $MYSQLD_DATADIR/test +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_TMPDIR/t1.cfg +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_TMPDIR/t1.ibd +UNLOCK TABLES; +INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t1; +SELECT * FROM t1 ORDER BY b,a DESC LIMIT 3; +SELECT * FROM t1 ORDER BY a DESC LIMIT 3; +--echo # Restarting server +-- source include/restart_mysqld.inc +--echo # Done restarting server +--echo # List before t1 DISCARD +--list_files $MYSQLD_DATADIR/test +ALTER TABLE t1 DISCARD TABLESPACE; +--echo # List after t1 DISCARD +--list_files $MYSQLD_DATADIR/test +--copy_file $MYSQLD_TMPDIR/t1.cfg $MYSQLD_DATADIR/test/t1.cfg +--copy_file $MYSQLD_TMPDIR/t1.ibd $MYSQLD_DATADIR/test/t1.ibd +ALTER TABLE t1 IMPORT TABLESPACE; +ALTER TABLE t1 ENGINE InnoDB; +SELECT COUNT(*) FROM t1; +SELECT * FROM t1 ORDER BY b,a DESC LIMIT 3; +SELECT * FROM t1 ORDER BY a DESC LIMIT 3; +--list_files $MYSQLD_DATADIR/test +SELECT COUNT(*) FROM t1; +SELECT * FROM t1 ORDER BY b,a DESC LIMIT 3; +SELECT * FROM t1 ORDER BY a DESC LIMIT 3; +DROP TABLE t1; +--remove_file $MYSQLD_TMPDIR/t1.cfg +--remove_file $MYSQLD_TMPDIR/t1.ibd + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +SET GLOBAL innodb_file_format = `Barracuda`; +SELECT @@innodb_file_format; + +# restore session variable +SET SESSION innodb_strict_mode=1; +SELECT @@SESSION.innodb_strict_mode; + +let MYSQLD_DATADIR =`SELECT @@datadir`; + +# Try importing when tablespace already exists +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; + +INSERT INTO t1(c2) VALUES(1); +--error ER_TABLESPACE_EXISTS +ALTER TABLE t1 IMPORT TABLESPACE; +SELECT * FROM t1; +DROP TABLE t1; + +# Export/import on the same instance, with --innodb-file-per-table=1 +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +--list_files $MYSQLD_DATADIR/test + +FLUSH TABLES t1 FOR EXPORT; +SELECT COUNT(*) FROM t1; +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test", "t1"); +EOF + +--list_files $MYSQLD_DATADIR/test + +UNLOCK TABLES; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--list_files $MYSQLD_DATADIR/test + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +SELECT COUNT(*) FROM t1; + +DROP TABLE t1; + +# Export/import on the same instance, with --innodb-file-per-table=1 +# Insert some more records to move the LSN forward and then drop the +# table and restore +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +--list_files $MYSQLD_DATADIR/test +FLUSH TABLES t1 FOR EXPORT; +SELECT COUNT(*) FROM t1; +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test", "t1"); +EOF +--list_files $MYSQLD_DATADIR/test +UNLOCK TABLES; + +--list_files $MYSQLD_DATADIR/test + +# Move the LSN forward +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--list_files $MYSQLD_DATADIR/test + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +SELECT COUNT(*) FROM t1; + +DROP TABLE t1; + +# Export/import on the same instance, with --innodb-file-per-table=1 +# Insert some more records to move the LSN forward and then drop the +# table and restore, this time the table has a secondary index too. +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +FLUSH TABLES t1 FOR EXPORT; +SELECT COUNT(*) FROM t1 WHERE c2 = 1; +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test", "t1"); +EOF +--list_files $MYSQLD_DATADIR/test +UNLOCK TABLES; + +# Move the LSN forward +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +SELECT COUNT(*) FROM t1 WHERE c2 = 1; + +DROP TABLE t1; + +# Export/import on the same instance, with --innodb-file-per-table=1 +# Insert some more records to move the LSN forward and then drop the +# table and restore, this time the table has a secondary index too. +# Rename the index on the create so that the IMPORT fails, drop index +# Create with proper name and then do an IMPORT. +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +FLUSH TABLES t1 FOR EXPORT; +SELECT COUNT(*) FROM t1 WHERE c2 = 1; +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test", "t1"); +EOF +UNLOCK TABLES; + +# Move the LSN forward +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX x(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +# This is really a name mismatch error, need better error codes. +-- error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +ALTER TABLE t1 DROP INDEX x; +ALTER TABLE t1 ADD INDEX idx(c2); + +perl; +do 'include/innodb-util.inc'; +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_cleanup("test", "t1"); +EOF + +DROP TABLE t1; + +# +# Export/import on the same instance, with --innodb-file-per-table=0 +# This should fail because it is not supported +SET GLOBAL innodb_file_per_table = 0; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT) ENGINE=InnoDB; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +SELECT COUNT(*) FROM t1; + +SHOW CREATE TABLE t1; + +# This should fail, InnoDB should return a warning +FLUSH TABLES t1 FOR EXPORT; + +UNLOCK TABLES; + +DROP TABLE t1; + +# +# Tests that check for schema mismatch during IMPORT +# + +SET GLOBAL innodb_file_per_table = 1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +FLUSH TABLES t1 FOR EXPORT; + +perl; +do 'include/innodb-util.inc'; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; + +DROP TABLE t1; + +# Table without the secondary index +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +# This should fail because of a missing secondary index +-- error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +# Table with an additional column +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, + c3 INT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +# This should fail because the table has an additional column +-- error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +# Change the column type of c2 +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 BIGINT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +# This should fail because c2 is now a BIGINT and not INT +-- error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +# This should fail because KEY_BLOCK_SIZE is different +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +# This should fail because is KEY_BLOCK_SIZE=4 +# but KEY_BLOCK_SIZE=8 is exported table +# Need better error message for following +--replace_regex /\(.*\)// +-- error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do 'include/innodb-util.inc'; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + + +# This should be OK. +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do 'include/innodb-util.inc'; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +perl; +do 'include/innodb-util.inc'; +ib_cleanup("test", "t1"); +EOF + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +DROP TABLE t1; + +call mtr.add_suppression("Got error -1 when reading table '.*'"); +call mtr.add_suppression("InnoDB: Error: tablespace id and flags in file '.*'.*"); +call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); + +# cleanup +--remove_file $MYSQLTEST_VARDIR/tmp/t1.cfg +--remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd + +eval SET GLOBAL INNODB_FILE_FORMAT=$innodb_file_format; +eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; +eval SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; diff --git a/mysql-test/suite/innodb_zip/t/innodb_16k.test b/mysql-test/suite/innodb_zip/t/innodb_16k.test new file mode 100644 index 00000000000..d66849af68a --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb_16k.test @@ -0,0 +1,735 @@ +#Want to skip this test from daily Valgrind execution +--source include/no_valgrind_without_big.inc +# Tests for setting innodb-page-size=16k; default value + +--source include/have_innodb.inc +--source include/have_innodb_16k.inc +SET default_storage_engine=InnoDB; + +--disable_query_log +let $MYSQLD_DATADIR= `select @@datadir`; + +# These values can change during the test +let $innodb_file_format_orig = `SELECT @@innodb_file_format`; +let $innodb_file_format_max_orig = `SELECT @@innodb_file_format_max`; +let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`; +let $innodb_large_prefix_orig = `SELECT @@innodb_large_prefix`; +let $innodb_strict_mode_orig = `SELECT @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format = `Barracuda`; +SET GLOBAL innodb_file_per_table = ON; + +--echo # Test 1) Show the page size from Information Schema +SELECT variable_value FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_page_size'; + +--echo # Test 2) The number of buffer pool pages is dependent upon the page size. +--replace_result 511 {511_or_512} 512 {511_or_512} +SELECT variable_value FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total'; + +--echo # Test 3) Query some information_shema tables that are dependent upon +--echo # the page size. +# Pulled from innodb-system-table-view.test +# The IDs of mysql.innodb_table_stats and mysql.innodb_index_stats are +# unpredictable, probably they on whether mtr has created the database for +# this test from scratch or is using a previously created database where +# those tables have been dropped and recreated. If we can force mtr to +# use a freshly created database for this test then the following +# complications can be removed and the test be reverted to the version +# it was before the patch that adds this comment. +--disable_query_log +--let table_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_table_stats'` +--let index_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_index_stats'` +--let $rep_table_1 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_master_info'` +--let $rep_table_2 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_relay_log_info'` +--let $rep_table_3 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_worker_info'` +--eval SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE table_id NOT IN ($table_stats_id, $index_stats_id, $rep_table_1, $rep_table_2, $rep_table_3) +--enable_query_log +CREATE TABLE t1 (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; +CREATE TABLE t2 (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; +CREATE TABLE t3 (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb; +CREATE TABLE t4 (a INT KEY, b TEXT) ROW_FORMAT=DYNAMIC ENGINE=innodb; +--replace_column 1 {id} 5 {id} +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES + WHERE name LIKE 'test%' ORDER BY table_id; +--replace_column 1 {id} +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES + WHERE name LIKE 'test%' ORDER BY space; +--replace_column 1 {id} +--replace_result ./ MYSQLD_DATADIR/ $MYSQLD_DATADIR MYSQLD_DATADIR +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES + WHERE path LIKE '%test%' ORDER BY space; +DROP TABLE t1, t2, t3, t4; + +--echo # Test 4) The maximum row size is dependent upon the page size. +--echo # Redundant: 8123, Compact: 8126. +--echo # Compressed: 8126, Dynamic: 8126. +--echo # Each row format has its own amount of overhead that +--echo # varies depending on number of fields and other overhead. + +SET SESSION innodb_strict_mode = ON; + +# Redundant table; 8011 bytes with 40 char fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(200), c40 char(211) +) ROW_FORMAT=redundant; +DROP TABLE t1; +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(200), c40 char(212) +) ROW_FORMAT=redundant; + +# Compact table; 8096 bytes with 40 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(250), c40 char(246) +) ROW_FORMAT=compact; +DROP TABLE t1; +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(250), c40 char(247) +) ROW_FORMAT=compact; + +# Compressed table; 7959 bytes with 40 CHAR fields +# Bug#13391353 Limit is 7957 on 32-Linux only +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(200), c40 char(157) +) ROW_FORMAT=compressed; +DROP TABLE t1; +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(200), c40 char(160) +) ROW_FORMAT=compressed; + +# Dynamic table; 8096 bytes with 40 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(250), c40 char(246) +) ROW_FORMAT=dynamic; +DROP TABLE t1; +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(200), +c21 char(200), c22 char(200), c23 char(200), c24 char(200), c25 char(200), +c26 char(200), c27 char(200), c28 char(200), c29 char(200), c30 char(200), +c31 char(200), c32 char(200), c33 char(200), c34 char(200), c35 char(200), +c36 char(200), c37 char(200), c38 char(200), c39 char(250), c40 char(247) +) ROW_FORMAT=dynamic; + +# +# Test the maximum key length +# Moved from innodb-index.test since each page size has its own max key length. +# Max Key Length is 3072 for 16k pages. +# Max key Part length is 767 +# InnoDB assumes 3 bytes for each UTF8 character. +# +CREATE TABLE t1 (a varchar(255) character set utf8, + b varchar(255) character set utf8, + c varchar(255) character set utf8, + d varchar(255) character set utf8, + e varchar(4) character set utf8, + PRIMARY KEY (a,b,c,d,e)) + ENGINE=innodb; +DROP TABLE t1; +--error ER_TOO_LONG_KEY +CREATE TABLE t1 (a varchar(255) character set utf8, + b varchar(255) character set utf8, + c varchar(255) character set utf8, + d varchar(255) character set utf8, + e varchar(5) character set utf8, + PRIMARY KEY (a,b,c,d,e)) + ENGINE=innodb; +CREATE TABLE t1 (a varchar(255) character set utf8, + b varchar(255) character set utf8, + c varchar(255) character set utf8, + d varchar(255) character set utf8, + e varchar(255) character set utf8, + f varchar(4) character set utf8, + PRIMARY KEY (a), KEY (b,c,d,e,f)) + ENGINE=innodb; +DROP TABLE t1; +--error ER_TOO_LONG_KEY +CREATE TABLE t1 (a varchar(255) character set utf8, + b varchar(255) character set utf8, + c varchar(255) character set utf8, + d varchar(255) character set utf8, + e varchar(255) character set utf8, + f varchar(5) character set utf8, + PRIMARY KEY (a), KEY (b,c,d,e,f)) + ENGINE=innodb; + +--echo # Test 5) Make sure that KEY_BLOCK_SIZE=16, 8, 4, 2 & 1 +--echo # are all accepted. + +SET SESSION innodb_strict_mode = ON; + +CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + +SET SESSION innodb_strict_mode = OFF; + +CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + + +--echo # Test 6) Make sure that KEY_BLOCK_SIZE = 8 and 16 +--echo # are rejected when innodb_file_per_table=OFF +# Moved from innodb-zip.test +SET SESSION innodb_strict_mode = ON; +SET GLOBAL innodb_file_per_table = OFF; +SHOW VARIABLES LIKE 'innodb_file_per_table'; +--error ER_ILLEGAL_HA +CREATE TABLE t4 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +--error ER_ILLEGAL_HA +CREATE TABLE t5 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SET GLOBAL innodb_file_per_table = ON; +SET GLOBAL innodb_file_format = `Antelope`; +SHOW VARIABLES LIKE 'innodb_file%'; +--error ER_ILLEGAL_HA +CREATE TABLE t4 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +--error ER_ILLEGAL_HA +CREATE TABLE t5 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SET GLOBAL innodb_file_format = `Barracuda`; + + +--echo # Test 7) This series of tests were moved from innodb-index to here +--echo # because the second alter table t1 assumes a 16k page size. +--echo # Moving the test allows the rest of innodb-index to be run on all +--echo # page sizes. The previously disabled portions of this test were +--echo # moved as well. + +CREATE TABLE t2(d varchar(17) PRIMARY KEY) ENGINE=innodb DEFAULT CHARSET=utf8; +CREATE TABLE t3(a int PRIMARY KEY) ENGINE=innodb; + +INSERT INTO t3 VALUES (22),(44),(33),(55),(66); + +INSERT INTO t2 VALUES ('jejdkrun87'),('adfd72nh9k'), +('adfdpplkeock'),('adfdijnmnb78k'),('adfdijn0loKNHJik'); + +CREATE TABLE t1(a int, b blob, c text, d text NOT NULL) +ENGINE=innodb DEFAULT CHARSET=utf8 STATS_PERSISTENT=0; + +INSERT INTO t1 +SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3 order by a, d; +DROP TABLE t2, t3; +SELECT COUNT(*) FROM t1 WHERE a=44; +SELECT a, +LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1; +# in-place alter table should trigger ER_PRIMARY_CANT_HAVE_NULL +--error ER_DUP_ENTRY +ALTER TABLE t1 ADD PRIMARY KEY (a), ADD KEY (b(20)); +DELETE FROM t1 WHERE d='null'; +--error ER_DUP_ENTRY +ALTER TABLE t1 ADD PRIMARY KEY (a), ADD KEY (b(20)); +DELETE FROM t1 WHERE a%2; +CHECK TABLE t1; +# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on. +# And adding a PRIMARY KEY will also add NOT NULL implicitly! +SET @old_sql_mode = @@sql_mode; +SET @@sql_mode = 'STRICT_TRANS_TABLES'; +ALTER TABLE t1 ADD PRIMARY KEY (a,b(255),c(255)), ADD KEY (b(767)); +SET @@sql_mode = @old_sql_mode; +SELECT COUNT(*) FROM t1 WHERE a=44; +SELECT a, +LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1; +SHOW CREATE TABLE t1; +CHECK TABLE t1; +EXPLAIN SELECT * FROM t1 WHERE b LIKE 'adfd%'; + +# The following tests are disabled because of the introduced timeouts for +# metadata locks at the MySQL level as part of the fix for +# Bug#45225 Locking: hang if drop table with no timeout +# The following commands now play with MySQL metadata locks instead of +# InnoDB locks +# start disabled45225_1 +## +## Test locking +## +# +#CREATE TABLE t2(a int, b varchar(255), PRIMARY KEY(a,b)) ENGINE=innodb; +#INSERT INTO t2 SELECT a,LEFT(b,255) FROM t1; +#DROP TABLE t1; +#RENAME TABLE t2 to t1; +# +#connect (a,localhost,root,,); +#connect (b,localhost,root,,); +#connection a; +#SET innodb_lock_wait_timeout=1; +#begin; +## Obtain an IX lock on the table +#SELECT a FROM t1 limit 1 FOR UPDATE; +#connection b; +#SET innodb_lock_wait_timeout=1; +## This would require an S lock on the table, conflicting with the IX lock. +#--error ER_LOCK_WAIT_TIMEOUT +#CREATE INDEX t1ba ON t1 (b,a); +#connection a; +#commit; +#begin; +## Obtain an IS lock on the table +#SELECT a FROM t1 limit 1 lock in share mode; +#connection b; +## This will require an S lock on the table. No conflict with the IS lock. +#CREATE INDEX t1ba ON t1 (b,a); +## This would require an X lock on the table, conflicting with the IS lock. +#--error ER_LOCK_WAIT_TIMEOUT +#DROP INDEX t1ba ON t1; +#connection a; +#commit; +#EXPLAIN SELECT a FROM t1 ORDER BY b; +#--send +#SELECT a,sleep(2+a/100) FROM t1 ORDER BY b limit 3; +# +## The following DROP INDEX will succeed, altough the SELECT above has +## opened a read view. However, during the execution of the SELECT, +## MySQL should hold a table lock that should block the execution +## of the DROP INDEX below. +# +#connection b; +#SELECT sleep(1); +#DROP INDEX t1ba ON t1; +# +## After the index was dropped, subsequent SELECTs will use the same +## read view, but they should not be accessing the dropped index any more. +# +#connection a; +#reap; +#EXPLAIN SELECT a FROM t1 ORDER BY b; +#SELECT a FROM t1 ORDER BY b limit 3; +#commit; +# +#connection default; +#disconnect a; +#disconnect b; +# +# end disabled45225_1 +DROP TABLE t1; + +--echo # Test 8) Test creating a table that could lead to undo log overflow. +CREATE TABLE t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob, + h blob,i blob,j blob,k blob,l blob,m blob,n blob, + o blob,p blob,q blob,r blob,s blob,t blob,u blob) + ENGINE=InnoDB ROW_FORMAT=dynamic; +SET @a = repeat('a', 767); +SET @b = repeat('b', 767); +SET @c = repeat('c', 767); +SET @d = repeat('d', 767); +SET @e = repeat('e', 767); + +# With no indexes defined, we can update all columns to max key part length. +INSERT INTO t1 VALUES (@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a); +UPDATE t1 SET a=@b,b=@b,c=@b,d=@b,e=@b,f=@b,g=@b,h=@b,i=@b,j=@b, + k=@b,l=@b,m=@b,n=@b,o=@b,p=@b,q=@b,r=@b,s=@b,t=@b,u=@b; + +# With this many indexes defined, we can still update all fields. +CREATE INDEX t1a ON t1 (a(767)); +CREATE INDEX t1b ON t1 (b(767)); +CREATE INDEX t1c ON t1 (c(767)); +CREATE INDEX t1d ON t1 (d(767)); +CREATE INDEX t1e ON t1 (e(767)); +UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c, + k=@c,l=@c,m=@c,n=@c,o=@c,p=@c,q=@c,r=@c,s=@c,t=@c,u=@c; + +# Add one more index and the UNDO record becomes too big to update all columns. +# But a single transaction can update the columns in separate statements. +# because the UNDO records will be smaller. +CREATE INDEX t1f ON t1 (f(767)); +--error ER_UNDO_RECORD_TOO_BIG +UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d, + k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d; +BEGIN; +UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d; +UPDATE t1 SET f=@d,g=@d,h=@d,i=@d,j=@d,k=@d,l=@d,m=@d, + n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d; +COMMIT; + +# More indexes can still be added and a single field can still be updated +CREATE INDEX t1g ON t1 (g(767)); +UPDATE t1 SET g=@e; +CREATE INDEX t1h ON t1 (h(767)); +UPDATE t1 SET h=@e; +CREATE INDEX t1i ON t1 (i(767)); +UPDATE t1 SET i=@e; +CREATE INDEX t1j ON t1 (j(767)); +UPDATE t1 SET j=@e; +CREATE INDEX t1k ON t1 (k(767)); +UPDATE t1 SET k=@e; +CREATE INDEX t1l ON t1 (l(767)); +UPDATE t1 SET l=@e; +CREATE INDEX t1m ON t1 (m(767)); +UPDATE t1 SET m=@e; +CREATE INDEX t1n ON t1 (n(767)); +UPDATE t1 SET n=@e; +CREATE INDEX t1o ON t1 (o(767)); +UPDATE t1 SET o=@e; +CREATE INDEX t1p ON t1 (p(767)); +UPDATE t1 SET p=@e; +CREATE INDEX t1q ON t1 (q(767)); +UPDATE t1 SET q=@e; +CREATE INDEX t1r ON t1 (r(767)); +UPDATE t1 SET r=@e; +CREATE INDEX t1s ON t1 (s(767)); +UPDATE t1 SET s=@e; + +# Add one more index and we cannot update a column to its defined index length. +# This is a problem. It means that the DDL is allowed to create a table +# that CANNOT be updated. See bug#12953735. +CREATE INDEX t1t ON t1 (t(767)); +--error ER_UNDO_RECORD_TOO_BIG +UPDATE t1 SET t=@e; + +# The function dict_index_too_big_for_undo() prevents us from adding +# one more index. But it is too late. The record is already too big. +# See bug#12953735 +--error ER_TOO_BIG_ROWSIZE +CREATE INDEX t1u ON t1 (u(767)); +--error ER_TOO_BIG_ROWSIZE +CREATE INDEX t1ut ON t1 (u(767), t(767)); +CREATE INDEX t1st ON t1 (s(767), t(767)); + +SHOW CREATE TABLE t1; +DROP TABLE t1; + +SET GLOBAL innodb_file_format = `Barracuda`; +SET GLOBAL innodb_file_per_table = ON; + +--echo # Bug #12429576 - Test an assertion failure on purge. +# This test is not in innodb_8k or innodb_4k since the bug is not about +# page size. It just tests the condition that caused the assertion. +CREATE TABLE t1_purge ( +A int, +B blob, C blob, D blob, E blob, +F blob, G blob, H blob, +PRIMARY KEY (B(767), C(767), D(767), E(767), A), +INDEX (A) +) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; + +INSERT INTO t1_purge VALUES (1, +REPEAT('b', 766), REPEAT('c', 766), REPEAT('d', 766), REPEAT('e', 766), +REPEAT('f', 766), REPEAT('g', 766), REPEAT('h', 766)); + +CREATE TABLE t2_purge ( +A int PRIMARY KEY, +B blob, C blob, D blob, E blob, +F blob, G blob, H blob, I blob, +J blob, K blob, L blob, +INDEX (B(767))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; + +INSERT INTO t2_purge VALUES (1, +REPEAT('b', 766), REPEAT('c', 766), REPEAT('d', 766), REPEAT('e', 766), +REPEAT('f', 766), REPEAT('g', 766), REPEAT('h', 766), REPEAT('i', 766), +REPEAT('j', 766), REPEAT('k', 766), REPEAT('l', 766)); + +CREATE TABLE t3_purge ( +A int, +B varchar(800), C varchar(800), D varchar(800), E varchar(800), +F varchar(800), G varchar(800), H varchar(800), +PRIMARY KEY (B(767), C(767), D(767), E(767), A), +INDEX (A) +) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; + +INSERT INTO t3_purge SELECT * FROM t1_purge; + +CREATE TABLE t4_purge ( +A int PRIMARY KEY, +B varchar(800), C varchar(800), D varchar(800), E varchar(800), +F varchar(800), G varchar(800), H varchar(800), I varchar(800), +J varchar(800), K varchar(800), L varchar(800), +INDEX (B(767))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; + +INSERT INTO t4_purge SELECT * FROM t2_purge; + +# This would trigger the failure (Bug #12429576) +# if purge gets a chance to run before DROP TABLE t1_purge, .... +DELETE FROM t1_purge; +DELETE FROM t2_purge; +DELETE FROM t3_purge; +DELETE FROM t4_purge; +# We need to activate the purge thread. +# Instead of doing a --sleep 10 now, do it once at the end. + +# Bug#12637786 - Assertion hit; ut_ad(dict_index_is_clust(index)); +# A secondary index tuple is found to be too long to fit into a page. +# This test is not in innodb_8k or innodb_4k since the bug is not about +# page size. It just tests the condition that caused the assertion. +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='Barracuda'; +SET @r=REPEAT('a',500); +CREATE TABLE t12637786(a int, + v1 varchar(500), v2 varchar(500), v3 varchar(500), + v4 varchar(500), v5 varchar(500), v6 varchar(500), + v7 varchar(500), v8 varchar(500), v9 varchar(500), + v10 varchar(500), v11 varchar(500), v12 varchar(500), + v13 varchar(500), v14 varchar(500), v15 varchar(500), + v16 varchar(500), v17 varchar(500), v18 varchar(500) +) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +CREATE INDEX idx1 ON t12637786(a,v1); +INSERT INTO t12637786 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +UPDATE t12637786 SET a=1000; +DELETE FROM t12637786; +# We need to activate the purge thread to make sure it does not assert and +# is able to clean up the old versions of secondary index entries. +# Instead of doing a --sleep 10 now for each test, do it once at the end. + +--echo # Bug#12963823 - Test that the purge thread does not crash when +# the number of indexes has changed since the UNDO record was logged. +# This test is not in innodb_8k or innodb_4k since the bug is not about +# page size. It just tests the condition that caused the crash. +CREATE TABLE t12963823(a blob,b blob,c blob,d blob,e blob,f blob,g blob,h blob, + i blob,j blob,k blob,l blob,m blob,n blob,o blob,p blob) + ENGINE=innodb ROW_FORMAT=dynamic; +SET @r = REPEAT('a', 767); +INSERT INTO t12963823 VALUES (@r,@r,@r,@r, @r,@r,@r,@r, @r,@r,@r,@r, @r,@r,@r,@r); +CREATE INDEX ndx_a ON t12963823 (a(500)); +CREATE INDEX ndx_b ON t12963823 (b(500)); +CREATE INDEX ndx_c ON t12963823 (c(500)); +CREATE INDEX ndx_d ON t12963823 (d(500)); +CREATE INDEX ndx_e ON t12963823 (e(500)); +CREATE INDEX ndx_f ON t12963823 (f(500)); +CREATE INDEX ndx_k ON t12963823 (k(500)); +CREATE INDEX ndx_l ON t12963823 (l(500)); + +SET @r = REPEAT('b', 500); +UPDATE t12963823 set a=@r,b=@r,c=@r,d=@r; +UPDATE t12963823 set e=@r,f=@r,g=@r,h=@r; +UPDATE t12963823 set i=@r,j=@r,k=@r,l=@r; +UPDATE t12963823 set m=@r,n=@r,o=@r,p=@r; +ALTER TABLE t12963823 DROP INDEX ndx_a; +ALTER TABLE t12963823 DROP INDEX ndx_b; +CREATE INDEX ndx_g ON t12963823 (g(500)); +CREATE INDEX ndx_h ON t12963823 (h(500)); +CREATE INDEX ndx_i ON t12963823 (i(500)); +CREATE INDEX ndx_j ON t12963823 (j(500)); +CREATE INDEX ndx_m ON t12963823 (m(500)); +CREATE INDEX ndx_n ON t12963823 (n(500)); +CREATE INDEX ndx_o ON t12963823 (o(500)); +CREATE INDEX ndx_p ON t12963823 (p(500)); +SHOW CREATE TABLE t12963823; +# We need to activate the purge thread at this point to see if it crashes. +# Instead of doing a --sleep 10 now for each test, do it once at the end. + +--echo # Bug#12547647 UPDATE LOGGING COULD EXCEED LOG PAGE SIZE +# InnoDB cannot know that this undo record would be too big for the undo +# page. Too much of text field is stored in the clustered record in this +# DYNAMIC row formatted record. +# This test is not in innodb_8k or innodb_4k since the bug is not about +# page size. It just tests the condition that caused the hang. + +SET SESSION innodb_strict_mode = ON; +CREATE TABLE bug12547647( +a int NOT NULL, b blob NOT NULL, c text, +PRIMARY KEY (b(10), a), INDEX (c(767)), INDEX(b(767)) +) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +INSERT INTO bug12547647 VALUES (5,REPEAT('khdfo5AlOq',1900),REPEAT('g',7751)); +COMMIT; +# The following used to cause a hang while doing infinite undo log allocation. +--error ER_UNDO_RECORD_TOO_BIG +UPDATE bug12547647 SET c = REPEAT('b',16928); +SHOW WARNINGS; +DROP TABLE bug12547647; + +# The following should fail in non-strict mode too. +# (The fix of Bug #50945 only affects REDUNDANT and COMPACT tables.) +SET SESSION innodb_strict_mode = off; +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767),d(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767),d(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII; +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767),d(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII; +drop table t1; +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1(c text, PRIMARY KEY (c(440))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +CREATE TABLE t1(c text, PRIMARY KEY (c(438))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); +DROP TABLE t1; + + +--echo # +--echo # Bug#56862 Execution of a query that uses index merge returns a wrong result +--echo # + +# Moved to here from innodb_mysql.test. Some PB3 systems sporadically +# had timeouts doing this with smaller page sizes. + +CREATE TABLE t1 ( + pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, + a int, + b int, + INDEX idx(a)) +ENGINE=INNODB; + +INSERT INTO t1(a,b) VALUES + (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500), + (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800), + (6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700), + (13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000); +INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1; +INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1; +INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1(a,b) SELECT a,b FROM t1; +INSERT INTO t1 VALUES (1000000, 0, 0); + +SET SESSION sort_buffer_size = 1024*36; + +EXPLAIN +SELECT COUNT(*) FROM + (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY) + WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; + +SELECT COUNT(*) FROM + (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY) + WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; + +SET SESSION sort_buffer_size = DEFAULT; + +DROP TABLE t1; + + +# The tests that uses these tables required the purge thread to run. +# Just in case it has not by now, provide a 10 second wait. +--sleep 10 +DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; +DROP TABLE t12637786; +DROP TABLE t12963823; + +# +# restore environment to the state it was before this test execution +# + +--disable_query_log +EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_format_max = $innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig; +EVAL SET GLOBAL innodb_large_prefix = $innodb_large_prefix_orig; +EVAL SET SESSION innodb_strict_mode = $innodb_strict_mode_orig; +--enable_query_log diff --git a/mysql-test/suite/innodb_zip/t/innodb_4k.test b/mysql-test/suite/innodb_zip/t/innodb_4k.test new file mode 100644 index 00000000000..3ce4bf16b0e --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb_4k.test @@ -0,0 +1,455 @@ +# Tests for setting innodb-page-size=4k + +--source include/have_innodb.inc +--source include/have_innodb_4k.inc +SET default_storage_engine=InnoDB; + +--disable_query_log +let $MYSQLD_DATADIR= `select @@datadir`; + +# These values can change during the test +let $innodb_file_format_orig = `SELECT @@innodb_file_format`; +let $innodb_file_format_max_orig = `SELECT @@innodb_file_format_max`; +let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`; +let $innodb_large_prefix_orig = `SELECT @@innodb_large_prefix`; +let $innodb_strict_mode_orig = `SELECT @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format = `Barracuda`; +SET GLOBAL innodb_file_per_table = ON; + +--echo # Test 1) Show the page size from Information Schema +SELECT variable_value FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_page_size'; + +--echo # Test 2) The number of buffer pool pages is dependent upon the page size. +SELECT variable_value FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total'; + +--echo # Test 3) Query some information_shema tables that are dependent upon +--echo # the page size. +# Pulled from innodb-system-table-view.test +# The IDs of mysql.innodb_table_stats and mysql.innodb_index_stats are +# unpredictable, probably they on whether mtr has created the database for +# this test from scratch or is using a previously created database where +# those tables have been dropped and recreated. If we can force mtr to +# use a freshly created database for this test then the following +# complications can be removed and the test be reverted to the version +# it was before the patch that adds this comment. +--disable_query_log +--let table_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_table_stats'` +--let index_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_index_stats'` +--let $rep_table_1 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_master_info'` +--let $rep_table_2 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_relay_log_info'` +--let $rep_table_3 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_worker_info'` +--eval SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE table_id NOT IN ($table_stats_id, $index_stats_id, $rep_table_1, $rep_table_2, $rep_table_3) +--enable_query_log +CREATE TABLE t1 (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; +CREATE TABLE t2 (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; +CREATE TABLE t3 (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb; +CREATE TABLE t4 (a INT KEY, b TEXT) ROW_FORMAT=DYNAMIC ENGINE=innodb; +--replace_column 1 {id} 5 {id} +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES + WHERE name LIKE 'test%' ORDER BY table_id; +--replace_column 1 {id} +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES + WHERE name LIKE 'test%' ORDER BY space; +--replace_column 1 {id} +--replace_result ./ MYSQLD_DATADIR/ $MYSQLD_DATADIR MYSQLD_DATADIR +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES + WHERE path LIKE '%test%' ORDER BY space; +DROP TABLE t1, t2, t3, t4; + +--echo # Test 4) The maximum row size is dependent upon the page size. +--echo # Redundant: 1979, Compact: 1982. +--echo # Compressed: 1982, Dynamic: 1982. +--echo # Each row format has its own amount of overhead that +--echo # varies depending on number of fields and other overhead. + +SET SESSION innodb_strict_mode = ON; + +# Redundant table; 1927 bytes with 10 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(127) +) ROW_FORMAT=redundant; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(128) +) ROW_FORMAT=redundant; + +# Compact table; 1955 bytes with 10 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(155) +) ROW_FORMAT=compact; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(156) +) ROW_FORMAT=compact; + +# Compressed table; 1878 bytes with 10 CHAR fields +# Bug#13391353 Limit is 1876 on 32-Linux only +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(76) +) ROW_FORMAT=compressed; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(79) +) ROW_FORMAT=compressed; + +# Dynamic table; 1955 bytes with 10 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(155) +) ROW_FORMAT=dynamic; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(156) +) ROW_FORMAT=dynamic; + +# +# Test the maximum key length +# Moved from innodb-index.test since each page size has its own max key length. +# Max Key Length is 768 for 4k pages. +# +# InnoDB assumes 3 bytes for each UTF8 character. +# +CREATE TABLE t1 (a varchar(64) character set utf8, + b varchar(64) character set utf8, + c varchar(64) character set utf8, + d varchar(64) character set utf8, + PRIMARY KEY (a,b,c,d)) + ENGINE=innodb; +DROP TABLE t1; +--error ER_TOO_LONG_KEY +CREATE TABLE t1 (a varchar(64) character set utf8, + b varchar(64) character set utf8, + c varchar(64) character set utf8, + d varchar(65) character set utf8, + PRIMARY KEY (a,b,c,d)) + ENGINE=innodb; +CREATE TABLE t1 (a varchar(64) character set utf8, + b varchar(64) character set utf8, + c varchar(64) character set utf8, + d varchar(64) character set utf8, + e varchar(64) character set utf8, + PRIMARY KEY (a), KEY (b,c,d,e)) + ENGINE=innodb; +DROP TABLE t1; +--error ER_TOO_LONG_KEY +CREATE TABLE t1 (a varchar(64) character set utf8, + b varchar(64) character set utf8, + c varchar(64) character set utf8, + d varchar(64) character set utf8, + e varchar(65) character set utf8, + PRIMARY KEY (a), KEY (b,c,d,e)) + ENGINE=innodb; + +--echo # Test 5) Make sure that KEY_BLOCK_SIZE=4, 2 & 1 are all +--echo # accepted and that KEY_BLOCK_SIZE=16 & 8 are rejected +--echo # in strict mode and converted to 4 in non-strict mode. + +SET SESSION innodb_strict_mode = ON; + +--error ER_ILLEGAL_HA +CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; +SHOW WARNINGS; + +--error ER_ILLEGAL_HA +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; + +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + +SET SESSION innodb_strict_mode = OFF; + +CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + + +--echo # Test 6) Make sure that KEY_BLOCK_SIZE = 8 and 16 +--echo # are both rejected when innodb_file_per_table=OFF +# Moved from innodb-zip.test +SET SESSION innodb_strict_mode = ON; +SET GLOBAL innodb_file_per_table = OFF; +SHOW VARIABLES LIKE 'innodb_file_per_table'; +--error ER_ILLEGAL_HA +CREATE TABLE t4 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +--error ER_ILLEGAL_HA +CREATE TABLE t5 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SET GLOBAL innodb_file_per_table = ON; +SET GLOBAL innodb_file_format = `Antelope`; +SHOW VARIABLES LIKE 'innodb_file%'; +--error ER_ILLEGAL_HA +CREATE TABLE t4 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +--error ER_ILLEGAL_HA +CREATE TABLE t5 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SET GLOBAL innodb_file_format = `Barracuda`; + + +--echo # Test 7) Not included here; 16k only + + +--echo # Test 8) Test creating a table that could lead to undo log overflow. +CREATE TABLE t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob, + h blob,i blob,j blob,k blob,l blob,m blob,n blob, + o blob,p blob,q blob,r blob,s blob,t blob,u blob) + ENGINE=InnoDB ROW_FORMAT=dynamic; +SET @a = repeat('a', 767); +SET @b = repeat('b', 767); +SET @c = repeat('c', 767); +SET @d = repeat('d', 767); +SET @e = repeat('e', 767); + +# With no indexes defined, we can update all columns to max key part length. +INSERT INTO t1 VALUES (@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a); +UPDATE t1 SET a=@b,b=@b,c=@b,d=@b,e=@b,f=@b,g=@b,h=@b,i=@b,j=@b, + k=@b,l=@b,m=@b,n=@b,o=@b,p=@b,q=@b,r=@b,s=@b,t=@b,u=@b; + +# With one index defined, we can still update all fields. +CREATE INDEX t1a ON t1 (a(767)); +UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c, + k=@c,l=@c,m=@c,n=@c,o=@c,p=@c,q=@c,r=@c,s=@c,t=@c,u=@c; + +# Add one more index and the UNDO record becomes too big to update all columns. +# But a single transaction can update the columns in separate statements. +# because the UNDO records will be smaller. +CREATE INDEX t1b ON t1 (b(767)); +--error ER_UNDO_RECORD_TOO_BIG +UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d, + k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d; +BEGIN; +UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d; +UPDATE t1 SET f=@d,g=@d,h=@d,i=@d,j=@d,k=@d,l=@d,m=@d, + n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d; +COMMIT; + +# Another index can still be added and a single field can still be updated +CREATE INDEX t1c ON t1 (c(767)); +UPDATE t1 SET c=@e; + +# Add one more index and we cannot update a column to its defined index length. +# This is a problem. It means that the DDL is allowed to create a table +# that CANNOT be updated. See bug#12953735. +CREATE INDEX t1d ON t1 (d(767)); +--error ER_UNDO_RECORD_TOO_BIG +UPDATE t1 SET d=@e; + +# The function dict_index_too_big_for_undo() prevents us from adding +# one more index. But it is too late. The record is already too big. +# See bug#12953735 +--replace_regex /> [0-9]*/> max_row_size/ +-- error ER_TOO_BIG_ROWSIZE +CREATE INDEX t1e ON t1 (e(767)); + +SHOW CREATE TABLE t1; +DROP TABLE t1; + +# +# Bug #13336585 - INNODB: CHANGE BUFFERING WITH 4K PAGES CAN ASSERT +# IF SECONDARY KEY IS NEAR MAX +# If the secondary index tuple is close to half the page size, +# ibuf_insert_low() could return DB_TOO_BIG_RECORD, which is not expected +# in ibuf_insert(). In order to insure this does not happen, WL5756 +# imposes a maximum key length of 768 for 4k pages and 1536 for 8k pages. +# The existing max key Size for 16k pages is 3072. +# + +#-- disable_query_log +# The flag innodb_change_buffering_debug is only available in debug builds. +# It instructs InnoDB to try to evict pages from the buffer pool when +# change buffering is possible, so that the change buffer will be used +# whenever possible. +# This flag is not used currently since it exposes valgrind error in ibuf +# code with the following SQL +#-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +#SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; +#-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +#SET GLOBAL innodb_change_buffering_debug = 1; +#-- enable_query_log + +# make sure the largest possible key entry can be added to the insert buffer. +# Make enough records so that the root page is not a leaf page. +SET SESSION innodb_strict_mode = OFF; +CREATE TABLE t1( + pk01 varchar(48), pk02 varchar(48), pk03 varchar(48), pk04 varchar(48), + pk05 varchar(48), pk06 varchar(48), pk07 varchar(48), pk08 varchar(48), + pk09 varchar(48), pk10 varchar(48), pk11 varchar(48), pk12 varchar(48), + pk13 varchar(48), pk14 varchar(48), pk15 varchar(48), pk16 varchar(48), + sk01 varchar(48), sk02 varchar(48), sk03 varchar(48), sk04 varchar(48), + sk05 varchar(48), sk06 varchar(48), sk07 varchar(48), sk08 varchar(48), + sk09 varchar(48), sk10 varchar(48), sk11 varchar(48), sk12 varchar(48), + sk13 varchar(48), sk14 varchar(48), sk15 varchar(48), sk16 varchar(48), + PRIMARY KEY pk(pk01,pk02,pk03,pk04,pk05,pk06,pk07,pk08, + pk09,pk10,pk11,pk12,pk13,pk14,pk15,pk16), + KEY pk(sk01,sk02,sk03,sk04,sk05,sk06,sk07,sk08, + sk09,sk10,sk11,sk12,sk13,sk14,sk15,sk16)) + ROW_FORMAT=Redundant ENGINE=InnoDB; +SET @r = repeat('a', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('b', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('c', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('d', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('e', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +DELETE from t1; +DROP TABLE t1; + +# Compressed tables do not compress parent pages. So the whole uncompressed +# secondary tuple including the primary key must be able to fit in half the +# compressed page size. This record length is enforced at index creation. +# So the only way to get an ibuf tuple too big is to make the KEY_BLOCK_SIZE +# the same as the page size. +CREATE TABLE t1( + pk01 varchar(48), pk02 varchar(48), pk03 varchar(48), pk04 varchar(48), + pk05 varchar(48), pk06 varchar(48), pk07 varchar(48), pk08 varchar(48), + pk09 varchar(48), pk10 varchar(48), pk11 varchar(48), pk12 varchar(48), + pk13 varchar(48), pk14 varchar(48), pk15 varchar(48), pk16 varchar(48), + sk01 varchar(48), sk02 varchar(48), sk03 varchar(48), sk04 varchar(48), + sk05 varchar(48), sk06 varchar(48), sk07 varchar(48), sk08 varchar(48), + sk09 varchar(48), sk10 varchar(48), sk11 varchar(48), sk12 varchar(48), + sk13 varchar(48), sk14 varchar(48), sk15 varchar(48), sk16 varchar(48), + PRIMARY KEY pk(pk01,pk02,pk03,pk04,pk05,pk06,pk07,pk08, + pk09,pk10,pk11,pk12,pk13,pk14,pk15,pk16), + KEY pk(sk01,sk02,sk03,sk04,sk05,sk06,sk07,sk08, + sk09,sk10,sk11,sk12,sk13,sk14,sk15,sk16)) + ROW_FORMAT=Compressed KEY_BLOCK_SIZE=4 ENGINE=InnoDB; +SET @r = repeat('a', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('b', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('c', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('d', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('e', 48); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +DELETE from t1; +DROP TABLE t1; + +#-- disable_query_log +#-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +#SET GLOBAL innodb_change_buffering_debug = 0; +#-- enable_query_log + +# The following should fail in non-strict mode too. +# (The fix of Bug #50945 only affects REDUNDANT and COMPACT tables.) +SET SESSION innodb_strict_mode = off; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII; +drop table t1; +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII; +drop table t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1(c text, PRIMARY KEY (c(440))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +CREATE TABLE t1(c text, PRIMARY KEY (c(438))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); +DROP TABLE t1; + +# +# restore environment to the state it was before this test execution +# + +--disable_query_log +EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_format_max = $innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig; +EVAL SET GLOBAL innodb_large_prefix = $innodb_large_prefix_orig; +EVAL SET SESSION innodb_strict_mode = $innodb_strict_mode_orig; +#-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE +#EVAL SET GLOBAL innodb_change_buffering_debug = @innodb_change_buffering_debug_orig; +--enable_query_log diff --git a/mysql-test/suite/innodb_zip/t/innodb_8k.test b/mysql-test/suite/innodb_zip/t/innodb_8k.test new file mode 100644 index 00000000000..33cc09244aa --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb_8k.test @@ -0,0 +1,482 @@ +# Tests for setting innodb-page-size=8k + +--source include/have_innodb.inc +--source include/have_innodb_8k.inc +SET default_storage_engine=InnoDB; + +--disable_query_log +let $MYSQLD_DATADIR= `select @@datadir`; + +# These values can change during the test +let $innodb_file_format_orig = `SELECT @@innodb_file_format`; +let $innodb_file_format_max_orig = `SELECT @@innodb_file_format_max`; +let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`; +let $innodb_large_prefix_orig = `SELECT @@innodb_large_prefix`; +let $innodb_strict_mode_orig = `SELECT @@session.innodb_strict_mode`; +--enable_query_log + +SET GLOBAL innodb_file_format = `Barracuda`; +SET GLOBAL innodb_file_per_table = ON; + +--echo # Test 1) Show the page size from Information Schema +SELECT variable_value FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_page_size'; + +--echo # Test 2) The number of buffer pool pages is dependent upon the page size. +--replace_result 1023 {1023_or_1024} 1024 {1023_or_1024} +SELECT variable_value FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total'; + +--echo # Test 3) Query some information_shema tables that are dependent upon +--echo # the page size. +# Pulled from innodb-system-table-view.test +# The IDs of mysql.innodb_table_stats and mysql.innodb_index_stats are +# unpredictable, probably they on whether mtr has created the database for +# this test from scratch or is using a previously created database where +# those tables have been dropped and recreated. If we can force mtr to +# use a freshly created database for this test then the following +# complications can be removed and the test be reverted to the version +# it was before the patch that adds this comment. +--disable_query_log +--let table_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_table_stats'` +--let index_stats_id = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/innodb_index_stats'` +--let $rep_table_1 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_master_info'` +--let $rep_table_2 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_relay_log_info'` +--let $rep_table_3 = `SELECT table_id FROM information_schema.innodb_sys_tables WHERE name = 'mysql/slave_worker_info'` +--eval SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE table_id NOT IN ($table_stats_id, $index_stats_id, $rep_table_1, $rep_table_2, $rep_table_3) +--enable_query_log +CREATE TABLE t1 (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; +CREATE TABLE t2 (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; +CREATE TABLE t3 (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb; +CREATE TABLE t4 (a INT KEY, b TEXT) ROW_FORMAT=DYNAMIC ENGINE=innodb; +--replace_column 1 {id} 5 {id} +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES + WHERE name LIKE 'test%' ORDER BY table_id; +--replace_column 1 {id} +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES + WHERE name LIKE 'test%' ORDER BY space; +--replace_column 1 {id} +--replace_result ./ MYSQLD_DATADIR/ $MYSQLD_DATADIR MYSQLD_DATADIR +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES + WHERE path LIKE '%test%' ORDER BY space; +DROP TABLE t1, t2, t3, t4; + +--echo # Test 4) The maximum row size is dependent upon the page size. +--echo # Redundant: 4027, Compact: 4030. +--echo # Compressed: 4030, Dynamic: 4030. +--echo # Each row format has its own amount of overhead that +--echo # varies depending on number of fields and other overhead. + +SET SESSION innodb_strict_mode = ON; + +# Redundant table; 3955 bytes with 20 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(155) +) ROW_FORMAT=redundant; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(156) +) ROW_FORMAT=redundant; + +# Compact table; 4002 bytes with 20 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(202) +) ROW_FORMAT=compact; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(203) +) ROW_FORMAT=compact; + +# Compressed table; 3905 bytes with 20 CHAR fields +# Bug#13391353 Limit is 3903 on 32-Linux only +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(103) +) ROW_FORMAT=compressed; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(106) +) ROW_FORMAT=compressed; + +# Dynamic table; 4002 bytes with 20 CHAR fields +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(202) +) ROW_FORMAT=dynamic; +DROP TABLE t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1 ( +c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200), +c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200), +c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200), +c16 char(200), c17 char(200), c18 char(200), c19 char(200), c20 char(203) +) ROW_FORMAT=dynamic; + +# +# Test the maximum key length +# Moved from innodb-index.test since each page size has its own max key length. +# Max Key Length is 1536 for 8k pages. +# +# InnoDB assumes 3 bytes for each UTF8 character. +# +CREATE TABLE t1 (a varchar(128) character set utf8, + b varchar(128) character set utf8, + c varchar(128) character set utf8, + d varchar(128) character set utf8, + PRIMARY KEY (a,b,c,d)) + ENGINE=innodb; +DROP TABLE t1; +--error ER_TOO_LONG_KEY +CREATE TABLE t1 (a varchar(128) character set utf8, + b varchar(128) character set utf8, + c varchar(128) character set utf8, + d varchar(129) character set utf8, + PRIMARY KEY (a,b,c,d)) + ENGINE=innodb; +CREATE TABLE t1 (a varchar(128) character set utf8, + b varchar(128) character set utf8, + c varchar(128) character set utf8, + d varchar(128) character set utf8, + e varchar(128) character set utf8, + PRIMARY KEY (a), KEY (b,c,d,e)) + ENGINE=innodb; +DROP TABLE t1; +--error ER_TOO_LONG_KEY +CREATE TABLE t1 (a varchar(128) character set utf8, + b varchar(128) character set utf8, + c varchar(128) character set utf8, + d varchar(128) character set utf8, + e varchar(129) character set utf8, + PRIMARY KEY (a), KEY (b,c,d,e)) + ENGINE=innodb; + +--echo # Test 5) Make sure that KEY_BLOCK_SIZE=8, 4, 2 & 1 are all +--echo # accepted and that KEY_BLOCK_SIZE=16 is rejected in +--echo # strict mode and converted to 8 in non-strict mode. + +SET SESSION innodb_strict_mode = ON; + +--error ER_ILLEGAL_HA +CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; +SHOW WARNINGS; + +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + +SET SESSION innodb_strict_mode = OFF; + +CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + +CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=2; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=1; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; + +ALTER TABLE t1 KEY_BLOCK_SIZE=0; +SHOW WARNINGS; +SELECT table_name, row_format, create_options + FROM information_schema.tables WHERE table_name = 't1'; +DROP TABLE t1; + + +--echo # Test 6) Make sure that KEY_BLOCK_SIZE = 8 and 16 +--echo # are rejected when innodb_file_per_table=OFF +# Moved from innodb-zip.test +SET SESSION innodb_strict_mode = ON; +SET GLOBAL innodb_file_per_table = OFF; +SHOW VARIABLES LIKE 'innodb_file_per_table'; +--error ER_ILLEGAL_HA +CREATE TABLE t4 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +--error ER_ILLEGAL_HA +CREATE TABLE t5 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SET GLOBAL innodb_file_per_table = ON; +SET GLOBAL innodb_file_format = `Antelope`; +SHOW VARIABLES LIKE 'innodb_file%'; +--error ER_ILLEGAL_HA +CREATE TABLE t4 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=8; +SHOW WARNINGS; +--error ER_ILLEGAL_HA +CREATE TABLE t5 (id int PRIMARY KEY) ENGINE=innodb KEY_BLOCK_SIZE=16; +SHOW WARNINGS; +SET GLOBAL innodb_file_format = `Barracuda`; + + +--echo # Test 7) Not included here; 16k only + + +--echo # Test 8) Test creating a table that could lead to undo log overflow. +CREATE TABLE t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob, + h blob,i blob,j blob,k blob,l blob,m blob,n blob, + o blob,p blob,q blob,r blob,s blob,t blob,u blob) + ENGINE=InnoDB ROW_FORMAT=dynamic; +SET @a = repeat('a', 767); +SET @b = repeat('b', 767); +SET @c = repeat('c', 767); +SET @d = repeat('d', 767); +SET @e = repeat('e', 767); + +# With no indexes defined, we can update all columns to max key part length. +INSERT INTO t1 VALUES (@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a,@a); +UPDATE t1 SET a=@b,b=@b,c=@b,d=@b,e=@b,f=@b,g=@b,h=@b,i=@b,j=@b, + k=@b,l=@b,m=@b,n=@b,o=@b,p=@b,q=@b,r=@b,s=@b,t=@b,u=@b; + +# With this many indexes defined, we can still update all fields. +CREATE INDEX t1a ON t1 (a(767)); +CREATE INDEX t1b ON t1 (b(767)); +UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c, + k=@c,l=@c,m=@c,n=@c,o=@c,p=@c,q=@c,r=@c,s=@c,t=@c,u=@c; + +# Add one more index and the UNDO record becomes too big to update all columns. +# But a single transaction can update the columns in separate statements. +# because the UNDO records will be smaller. +CREATE INDEX t1c ON t1 (c(767)); +--error ER_UNDO_RECORD_TOO_BIG +UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d, + k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d; +BEGIN; +UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d; +UPDATE t1 SET f=@d,g=@d,h=@d,i=@d,j=@d,k=@d,l=@d,m=@d, + n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d; +COMMIT; + +# More indexes can still be added and a single field can still be updated +CREATE INDEX t1d ON t1 (d(767)); +UPDATE t1 SET d=@e; +CREATE INDEX t1e ON t1 (e(767)); +UPDATE t1 SET e=@e; +CREATE INDEX t1f ON t1 (f(767)); +UPDATE t1 SET f=@e; +CREATE INDEX t1g ON t1 (g(767)); +UPDATE t1 SET g=@e; +CREATE INDEX t1h ON t1 (h(767)); +UPDATE t1 SET h=@e; +CREATE INDEX t1i ON t1 (i(767)); +UPDATE t1 SET i=@e; + +# The function dict_index_too_big_for_undo() prevents us from adding +# one more index that is 767 bytes long. +--replace_regex /> [0-9]*/> max_row_size/ +-- error ER_TOO_BIG_ROWSIZE +CREATE INDEX t1j ON t1 (j(767)); + +# But it does allow a 500 byte index. And with this, we cannot +# update the record. This is a problem. It means that the DDL is +# allowed to create a table and a record that CANNOT be updated. +# See bug#12953735 +CREATE INDEX t1j ON t1 (j(500)); +--error ER_UNDO_RECORD_TOO_BIG +UPDATE t1 SET j=@e; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +# +# Bug #13336585 - INNODB: CHANGE BUFFERING WITH 4K PAGES CAN ASSERT +# IF SECONDARY KEY IS NEAR MAX +# If the secondary index tuple is close to half the page size, +# ibuf_insert_low() could return DB_TOO_BIG_RECORD, which is not expected +# in ibuf_insert(). In order to insure this does not happen, WL5756 +# imposes a maximum key length of 768 for 4k pages and 1536 for 8k pages. +# The existing max key Size for 16k pages is 3072. +# + +#-- disable_query_log +# The flag innodb_change_buffering_debug is only available in debug builds. +# It instructs InnoDB to try to evict pages from the buffer pool when +# change buffering is possible, so that the change buffer will be used +# whenever possible. +#-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +#SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; +#-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +#SET GLOBAL innodb_change_buffering_debug = 1; +#-- enable_query_log + +# make sure the largest possible key entry can be added to the insert buffer. +# Make enough records so that the root page is not a leaf page. +SET SESSION innodb_strict_mode = OFF; +CREATE TABLE t1( + pk01 varchar(96), pk02 varchar(96), pk03 varchar(96), pk04 varchar(96), + pk05 varchar(96), pk06 varchar(96), pk07 varchar(96), pk08 varchar(96), + pk09 varchar(96), pk10 varchar(96), pk11 varchar(96), pk12 varchar(96), + pk13 varchar(96), pk14 varchar(96), pk15 varchar(96), pk16 varchar(96), + sk01 varchar(96), sk02 varchar(96), sk03 varchar(96), sk04 varchar(96), + sk05 varchar(96), sk06 varchar(96), sk07 varchar(96), sk08 varchar(96), + sk09 varchar(96), sk10 varchar(96), sk11 varchar(96), sk12 varchar(96), + sk13 varchar(96), sk14 varchar(96), sk15 varchar(96), sk16 varchar(96), + PRIMARY KEY pk(pk01,pk02,pk03,pk04,pk05,pk06,pk07,pk08, + pk09,pk10,pk11,pk12,pk13,pk14,pk15,pk16), + KEY pk(sk01,sk02,sk03,sk04,sk05,sk06,sk07,sk08, + sk09,sk10,sk11,sk12,sk13,sk14,sk15,sk16)) + ROW_FORMAT=Redundant ENGINE=InnoDB; +SET @r = repeat('a', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('b', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('c', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('d', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('e', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +DELETE from t1; +DROP TABLE t1; + +# Compressed tables do not compress parent pages. So the whole uncompressed +# secondary tuple including the primary key must be able to fit in half the +# compressed page size. This record length is enforced at index creation. +# So the only way to get an ibuf tuple too big is to make the KEY_BLOCK_SIZE +# the same as the page size. +CREATE TABLE t1( + pk01 varchar(96), pk02 varchar(96), pk03 varchar(96), pk04 varchar(96), + pk05 varchar(96), pk06 varchar(96), pk07 varchar(96), pk08 varchar(96), + pk09 varchar(96), pk10 varchar(96), pk11 varchar(96), pk12 varchar(96), + pk13 varchar(96), pk14 varchar(96), pk15 varchar(96), pk16 varchar(96), + sk01 varchar(96), sk02 varchar(96), sk03 varchar(96), sk04 varchar(96), + sk05 varchar(96), sk06 varchar(96), sk07 varchar(96), sk08 varchar(96), + sk09 varchar(96), sk10 varchar(96), sk11 varchar(96), sk12 varchar(96), + sk13 varchar(96), sk14 varchar(96), sk15 varchar(96), sk16 varchar(96), + PRIMARY KEY pk(pk01,pk02,pk03,pk04,pk05,pk06,pk07,pk08, + pk09,pk10,pk11,pk12,pk13,pk14,pk15,pk16), + KEY pk(sk01,sk02,sk03,sk04,sk05,sk06,sk07,sk08, + sk09,sk10,sk11,sk12,sk13,sk14,sk15,sk16)) + ROW_FORMAT=Compressed KEY_BLOCK_SIZE=8 ENGINE=InnoDB; +SET @r = repeat('a', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('b', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('c', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('d', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +SET @r = repeat('e', 96); +INSERT INTO t1 VALUES(@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r, + @r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); +DELETE from t1; +DROP TABLE t1; + +#-- disable_query_log +#-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE +#SET GLOBAL innodb_change_buffering_debug = 0; +#-- enable_query_log + +# The following should fail in non-strict mode too. +# (The fix of Bug #50945 only affects REDUNDANT and COMPACT tables.) +SET SESSION innodb_strict_mode = off; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767),d(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767),d(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII; +CREATE TABLE t1( + c text NOT NULL, d text NOT NULL, + PRIMARY KEY (c(767),d(767))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII; +drop table t1; +--replace_regex /> [0-9]*/> max_row_size/ +--error ER_TOO_BIG_ROWSIZE +CREATE TABLE t1(c text, PRIMARY KEY (c(440))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +CREATE TABLE t1(c text, PRIMARY KEY (c(438))) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; +INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); +DROP TABLE t1; + +# +# restore environment to the state it was before this test execution +# + +--disable_query_log +EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig; +EVAL SET GLOBAL innodb_file_format_max = $innodb_file_format_max_orig; +EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig; +EVAL SET GLOBAL innodb_large_prefix = $innodb_large_prefix_orig; +EVAL SET SESSION innodb_strict_mode = $innodb_strict_mode_orig; +#-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE +#EVAL SET GLOBAL innodb_change_buffering_debug = @innodb_change_buffering_debug_orig; +--enable_query_log diff --git a/mysql-test/suite/innodb_zip/t/innodb_cmp_per_index.test b/mysql-test/suite/innodb_zip/t/innodb_cmp_per_index.test new file mode 100644 index 00000000000..7a14b9d2102 --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb_cmp_per_index.test @@ -0,0 +1,120 @@ +# +# Test information_schema.innodb_cmp_per_index +# + +-- source include/have_innodb.inc + +# Using innodb_log_compressed=0 leads to a larger number of page +# compressions, because page_cur_insert_rec_zip() will reorganize the +# page before attempting an insert followed by page compression and +# page_zip_compress_write_log_no_data(). + +if (`SELECT @@innodb_log_compressed_pages = 0`) +{ + --skip Needs innodb_log_compressed_pages +} + +# numbers read in this test depend on the page size +-- source include/have_innodb_16k.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- vertical_results + +SET GLOBAL innodb_cmp_per_index_enabled=ON; +SET GLOBAL innodb_file_format=Barracuda; + +# reset any leftover stats from previous tests +-- disable_query_log +-- disable_result_log +SELECT * FROM information_schema.innodb_cmp_per_index_reset; +-- enable_result_log +-- enable_query_log + +# see that the table is empty +SELECT * FROM information_schema.innodb_cmp_per_index; + +# create a table that uses compression +CREATE TABLE t ( + a INT, + b VARCHAR(512), + c VARCHAR(16), + PRIMARY KEY (a), + INDEX (b(512)), + INDEX (c(16)) +) ENGINE=INNODB KEY_BLOCK_SIZE=2; + +SELECT +database_name, +table_name, +index_name, +compress_ops, +compress_ops_ok, +uncompress_ops +FROM information_schema.innodb_cmp_per_index +ORDER BY 1, 2, 3; + +# insert some data into it +BEGIN; +-- disable_query_log +let $i=128; +while ($i) +{ + -- eval INSERT INTO t VALUES ($i, REPEAT('x', 512), NULL); + dec $i; +} +-- enable_query_log +COMMIT; + +ALTER TABLE t DROP INDEX c; + +GRANT USAGE ON *.* TO 'tuser01'@'localhost' IDENTIFIED BY 'cDJvI9s_Uq'; +FLUSH PRIVILEGES; + +-- connect (con1,localhost,tuser01,cDJvI9s_Uq,) +-- connection con1 + +-- error ER_SPECIFIC_ACCESS_DENIED_ERROR +SELECT * FROM information_schema.innodb_cmp_per_index; + +-- connection default +-- disconnect con1 + +DROP USER 'tuser01'@'localhost'; + +-- replace_regex /index_id:[0-9]+/index_id:idisnondeterministic/ +SELECT +database_name, +table_name, +index_name, +CASE WHEN compress_ops=47 and @@innodb_compression_level IN (4,8,9) THEN 65 +ELSE compress_ops END as compress_ops, +CASE WHEN compress_ops_ok=47 and @@innodb_compression_level IN (4,8,9) THEN 65 +ELSE compress_ops_ok END as compress_ops_ok, +uncompress_ops +FROM information_schema.innodb_cmp_per_index +ORDER BY 1, 2, 3; + +# restart mysqld and see that uncompress ops also gets increased when +# selecting from the table again + +-- source include/restart_mysqld.inc + +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +SELECT COUNT(*) FROM t; + +SELECT +database_name, +table_name, +index_name, +compress_ops, +compress_ops_ok, +uncompress_ops +FROM information_schema.innodb_cmp_per_index +ORDER BY 1, 2, 3; + +DROP TABLE t; + +SET GLOBAL innodb_cmp_per_index_enabled=default; +SET GLOBAL innodb_file_format=default; diff --git a/mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_4k.test b/mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_4k.test new file mode 100644 index 00000000000..5360daf884f --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_4k.test @@ -0,0 +1,405 @@ +# Testcase for worklog #5743: Lift the limit of index key prefixes + +--source include/have_innodb.inc +--source include/have_innodb_4k.inc +SET default_storage_engine=InnoDB; + +let $innodb_file_format_orig=`select @@innodb_file_format`; +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +let $innodb_large_prefix_orig=`select @@innodb_large_prefix`; + +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; + +-- echo ### Test 1 ### +# Create a table of DYNAMIC format, with a primary index of 768 bytes in +# size +create table worklog5743(a TEXT not null, primary key (a(768))) ROW_FORMAT=DYNAMIC; +show warnings; + +# Do some insertion and update to excercise the external cache +# code path +insert into worklog5743 values(repeat("a", 20000)); + +# default session, update the table +update worklog5743 set a = (repeat("b", 16000)); + +# Create a secondary index +create index idx on worklog5743(a(900)); +show warnings; + +# Start a few sessions to do selections on table being updated in default +# session, so it would rebuild the previous version from undo log. +# 1) Default session: Initiate an update on the externally stored column +# 2) Session con1: Select from table with repeated read +# 3) Session con2: Select from table with read uncommitted +# 4) Default session: rollback updates + +begin; +update worklog5743 set a = (repeat("x", 17000)); + +# Start a new session to select the column to force it build +# an earlier version of the clustered index through undo log. So it should +# just see the result of repeat("b", 16000) +select @@session.tx_isolation; +--connect (con1,localhost,root,,) +select a = repeat("x", 17000) from worklog5743; +select a = repeat("b", 16000) from worklog5743; + +# Start another session doing "read uncommitted" query, it +# should see the uncommitted update +--connect (con2,localhost,root,,) +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a = repeat("x", 17000) from worklog5743; + +# Roll back the transaction +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 2 ### +# Create a table with only a secondary index has large prefix column +create table worklog5743(a1 int, a2 TEXT not null) ROW_FORMAT=DYNAMIC; +show warnings; +create index idx on worklog5743(a1, a2(750)); +show warnings; + +insert into worklog5743 values(9, repeat("a", 10000)); + +begin; + +update worklog5743 set a1 = 1111; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 3 ### +# Create a table with a secondary index has small (50 bytes) prefix column +create table worklog5743(a1 int, a2 TEXT not null) ROW_FORMAT=DYNAMIC; + +create index idx on worklog5743(a1, a2(50)); + +insert into worklog5743 values(9, repeat("a", 10000)); + +begin; + +update worklog5743 set a1 = 2222; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 4 ### +# Create compressed tables with each KEY_BLOCK_SIZE. +create table worklog5743_1(a1 int, a2 TEXT not null) KEY_BLOCK_SIZE=1; +create table worklog5743_2(a1 int, a2 TEXT not null) KEY_BLOCK_SIZE=2; +create table worklog5743_4(a1 int, a2 TEXT not null) KEY_BLOCK_SIZE=4; + +# The maximum overall index record (not prefix) length of a +# compressed table is dependent on innodb-page-size (IPS), +# key_block_size (KBS) and the number of fields (NF). +# "Too big row" error (HA_ERR_TO_BIG_ROW) will be returned if this +# limit is exceeded. +# See page_zip_empty_size() and Bug #47495 for more detail. + +# Test edge cases for indexes using key_block_size=1 +set global innodb_large_prefix=0; +-- error ER_TOO_BIG_ROWSIZE +create index idx1 on worklog5743_1(a2(4000)); +show warnings; +-- error ER_TOO_BIG_ROWSIZE +create index idx3 on worklog5743_1(a2(436)); +show warnings; +# Bug#13391353 Limit is one byte less on on 32bit-Linux only +create index idx4 on worklog5743_1(a2(434)); +show warnings; +-- error ER_TOO_BIG_ROWSIZE +create index idx5 on worklog5743_1(a1, a2(430)); +show warnings; +# Bug#13391353 Limit is one byte less on on 32bit-Linux only +create index idx6 on worklog5743_1(a1, a2(428)); +show warnings; + +# Test edge cases for indexes using key_block_size=2 +set global innodb_large_prefix=1; +create index idx1 on worklog5743_2(a2(4000)); +show warnings; +show create table worklog5743_2; +create index idx3 on worklog5743_2(a2(769)); +show warnings; +create index idx4 on worklog5743_2(a2(768)); +show warnings; +-- error ER_TOO_LONG_KEY +create index idx5 on worklog5743_2(a1, a2(765)); +show warnings; +create index idx6 on worklog5743_2(a1, a2(764)); +show warnings; + +# Test edge cases for indexes using key_block_size=4 +set global innodb_large_prefix=0; +create index idx1 on worklog5743_4(a2(4000)); +show warnings; +show create table worklog5743_4; +create index idx3 on worklog5743_4(a2(769)); +show warnings; +create index idx4 on worklog5743_4(a2(768)); +show warnings; +-- error ER_TOO_LONG_KEY +create index idx5 on worklog5743_4(a1, a2(765)); +show warnings; +create index idx6 on worklog5743_4(a1, a2(764)); +show warnings; + +# Insert a large record into each of these tables. +insert into worklog5743_1 values(9, repeat("a", 10000)); +insert into worklog5743_2 values(9, repeat("a", 10000)); +insert into worklog5743_4 values(9, repeat("a", 10000)); + +# Now if we change the global innodb_large_prefix back to 767, +# updates to these indexes should still be allowed. +set global innodb_large_prefix=0; +insert into worklog5743_1 values(2, repeat("b", 10000)); +insert into worklog5743_2 values(2, repeat("b", 10000)); +insert into worklog5743_4 values(2, repeat("b", 10000)); +set global innodb_large_prefix=1; + +select a1, left(a2, 20) from worklog5743_1; +select a1, left(a2, 20) from worklog5743_2; +select a1, left(a2, 20) from worklog5743_4; + +begin; + +update worklog5743_1 set a1 = 1000; +update worklog5743_2 set a1 = 1000; +update worklog5743_4 set a1 = 1000; +select a1, left(a2, 20) from worklog5743_1; +select a1, left(a2, 20) from worklog5743_2; +select a1, left(a2, 20) from worklog5743_4; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, left(a2, 20) from worklog5743_1 where a1 = 9; +explain select a1, left(a2, 20) from worklog5743_2 where a1 = 9; +explain select a1, left(a2, 20) from worklog5743_4 where a1 = 9; +select a1, left(a2, 20) from worklog5743_1 where a1 = 9; +select a1, left(a2, 20) from worklog5743_2 where a1 = 9; +select a1, left(a2, 20) from worklog5743_4 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, left(a2, 20) from worklog5743_1 where a1 = 9; +select a1, left(a2, 20) from worklog5743_2 where a1 = 9; +select a1, left(a2, 20) from worklog5743_4 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743_1; +drop table worklog5743_2; +drop table worklog5743_4; + +-- echo ### Test 5 ### +# Create a table with large varchar columns and create indexes +# directly on these large columns to show that prefix limit is +# automatically applied and to show that limit. + +# This commented form of the test causes an unlimited page split +# on update of the int field - Bug 12636590 - INNODB; UPDATE OF +# LARGE RECORD CAUSES UNLIMITED PAGE SPLITS IN 8K PAGE SIZE +#create table worklog5743(a1 int, +# a2 varchar(20000), +# a3 varchar(3073), +# a4 varchar(3072), +# a5 varchar(3069), +# a6 varchar(3068)) +# ROW_FORMAT=DYNAMIC; +#create index idx1 on worklog5743(a2); +#create index idx2 on worklog5743(a3); +#create index idx3 on worklog5743(a4); +#show warnings; +#-- error ER_TOO_LONG_KEY +#create index idx4 on worklog5743(a1, a2); +#show warnings; +#-- error ER_TOO_LONG_KEY +#create index idx5 on worklog5743(a1, a5); +#show warnings; +#create index idx6 on worklog5743(a1, a6); +#show warnings; +#show create table worklog5743; +# +#insert into worklog5743 values(9, +# repeat("a", 20000), repeat("a", 3073), +# repeat("a", 3072), repeat("a", 3069), +# repeat("a", 3068)); +# + +create table worklog5743(a1 int, a2 varchar(20000)) ROW_FORMAT=DYNAMIC; +-- error ER_TOO_LONG_KEY +create index idx1 on worklog5743(a2); +show warnings; +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(3072)) ROW_FORMAT=DYNAMIC; +-- error ER_TOO_LONG_KEY +create index idx1 on worklog5743(a2); +show warnings; +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(769)) ROW_FORMAT=DYNAMIC; +-- error ER_TOO_LONG_KEY +create index idx1 on worklog5743(a2); +show warnings; +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(768)) ROW_FORMAT=DYNAMIC; +create index idx1 on worklog5743(a2); +show warnings; +insert into worklog5743 values(9, repeat("a", 768)); +update worklog5743 set a1 = 3333; +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(765)) ROW_FORMAT=DYNAMIC; +-- error ER_TOO_LONG_KEY +create index idx1 on worklog5743(a1, a2); +show warnings; +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(764)) ROW_FORMAT=DYNAMIC; +create index idx1 on worklog5743(a1, a2); +show warnings; +insert into worklog5743 values(9, repeat("a", 764)); + +begin; +update worklog5743 set a1 = 4444; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1 from worklog5743 where a1 = 9; +select a1 from worklog5743 where a1 = 9; + +# Do read uncommitted, it would show there is no row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1 from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 6 ### +# Create a table with old format, and the limit is 768 bytes. +-- error ER_TOO_LONG_KEY +create table worklog5743(a TEXT not null, primary key (a(1000))); + +create table worklog5743(a TEXT); + +# Excercise the column length check in ha_innobase::add_index() +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(768)); + +# This should be successful +create index idx on worklog5743(a(767)); + +# Perform some DMLs +insert into worklog5743 values(repeat("a", 20000)); + +begin; +insert into worklog5743 values(repeat("b", 20000)); +update worklog5743 set a = (repeat("x", 25000)); + +# Start a new session to select the table to force it build +# an earlier version of the cluster index through undo log +select @@session.tx_isolation; +--connection con1 +select a = repeat("a", 20000) from worklog5743; + +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a = repeat("x", 25000) from worklog5743; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 7 ### +# Some border line tests on the column length. +# We have a limit of 3072 bytes for Barracuda table +create table worklog5743(a TEXT not null) ROW_FORMAT=DYNAMIC; + +# Length exceeds maximum supported key length +# It will be auto-truncated to 3072 if the page size were not 4k. +# With this page size, the prefix length is less. +create index idx1 on worklog5743(a(769)); +show warnings; +create index idx2 on worklog5743(a(768)); +show warnings; +show create table worklog5743; +insert into worklog5743 values(repeat("a", 768)); +drop table worklog5743; + +# We have a limit of 767 bytes for Antelope tables +create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(768)); +create index idx2 on worklog5743(a(767)); +drop table worklog5743; + +create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(768)); +create index idx2 on worklog5743(a(767)); +drop table worklog5743; + + +eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; +eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +eval SET GLOBAL innodb_large_prefix=$innodb_large_prefix_orig; +--connection con1 +--disconnect con1 +--source include/wait_until_disconnected.inc +--connection con2 +--disconnect con2 +--source include/wait_until_disconnected.inc +--connection default + diff --git a/mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_8k.test b/mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_8k.test new file mode 100644 index 00000000000..06debf10464 --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_8k.test @@ -0,0 +1,430 @@ +# Testcase for worklog #5743: Lift the limit of index key prefixes + +--source include/have_innodb.inc +--source include/have_innodb_8k.inc +SET default_storage_engine=InnoDB; + +let $innodb_file_format_orig=`select @@innodb_file_format`; +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; +let $innodb_large_prefix_orig=`select @@innodb_large_prefix`; + +set global innodb_file_format="Barracuda"; +set global innodb_file_per_table=1; +set global innodb_large_prefix=1; + +-- echo ### Test 1 ### +# Create a table of DYNAMIC format, with a primary index of 1000 bytes in +# size +create table worklog5743(a TEXT not null, primary key (a(1000))) ROW_FORMAT=DYNAMIC; +show warnings; + +# Do some insertion and update to excercise the external cache +# code path +insert into worklog5743 values(repeat("a", 20000)); + +# default session, update the table +update worklog5743 set a = (repeat("b", 16000)); + +# Create a secondary index +create index idx on worklog5743(a(2000)); +show warnings; + +# Start a few sessions to do selections on table being updated in default +# session, so it would rebuild the previous version from undo log. +# 1) Default session: Initiate an update on the externally stored column +# 2) Session con1: Select from table with repeated read +# 3) Session con2: Select from table with read uncommitted +# 4) Default session: rollback updates + +begin; +update worklog5743 set a = (repeat("x", 17000)); + +# Start a new session to select the column to force it build +# an earlier version of the clustered index through undo log. So it should +# just see the result of repeat("b", 16000) +select @@session.tx_isolation; +--connect (con1,localhost,root,,) +select a = repeat("x", 17000) from worklog5743; +select a = repeat("b", 16000) from worklog5743; + +# Start another session doing "read uncommitted" query, it +# should see the uncommitted update +--connect (con2,localhost,root,,) +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a = repeat("x", 17000) from worklog5743; + +# Roll back the transaction +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 2 ### +# Create a table with only a secondary index has large prefix column +create table worklog5743(a1 int, a2 TEXT not null) ROW_FORMAT=DYNAMIC; +show warnings; +create index idx on worklog5743(a1, a2(1250)); +show warnings; + +insert into worklog5743 values(9, repeat("a", 10000)); + +begin; + +update worklog5743 set a1 = 1000; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 3 ### +# Create a table with a secondary index has small (50 bytes) prefix column +create table worklog5743(a1 int, a2 TEXT not null) ROW_FORMAT=DYNAMIC; + +create index idx on worklog5743(a1, a2(50)); + +insert into worklog5743 values(9, repeat("a", 10000)); + +begin; + +update worklog5743 set a1 = 1000; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, a2 = repeat("a", 10000) from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 4 ### +# Create compressed tables with each KEY_BLOCK_SIZE. +create table worklog5743_1(a1 int, a2 TEXT not null) KEY_BLOCK_SIZE=1; +create table worklog5743_2(a1 int, a2 TEXT not null) KEY_BLOCK_SIZE=2; +create table worklog5743_4(a1 int, a2 TEXT not null) KEY_BLOCK_SIZE=4; +create table worklog5743_8(a1 int, a2 TEXT, a3 TEXT) KEY_BLOCK_SIZE=8; + +# The maximum overall index record (not prefix) length of a +# compressed table is dependent on innodb-page-size (IPS), +# key_block_size (KBS) and the number of fields (NF). +# "Too big row" error (HA_ERR_TO_BIG_ROW) will be returned if this +# limit is exceeded. +# See page_zip_empty_size() and Bug #47495 for more detail. + +# Test edge cases for indexes using key_block_size=1 +set global innodb_large_prefix=0; +-- error ER_TOO_BIG_ROWSIZE +create index idx1 on worklog5743_1(a2(4000)); +show warnings; +set global innodb_large_prefix=1; +-- error ER_TOO_BIG_ROWSIZE +create index idx2 on worklog5743_1(a2(4000)); +show warnings; +-- error ER_TOO_BIG_ROWSIZE +create index idx3 on worklog5743_1(a2(436)); +show warnings; +# Bug#13391353 Limit is one byte less on on 32bit-Linux only +create index idx4 on worklog5743_1(a2(434)); +show warnings; +-- error ER_TOO_BIG_ROWSIZE +create index idx5 on worklog5743_1(a1, a2(430)); +show warnings; +# Bug#13391353 Limit is one byte less on on 32bit-Linux only +create index idx6 on worklog5743_1(a1, a2(428)); +show warnings; + +# Test edge cases for indexes using key_block_size=2 +set global innodb_large_prefix=0; +create index idx1 on worklog5743_2(a2(4000)); +show warnings; +set global innodb_large_prefix=1; +-- error ER_TOO_BIG_ROWSIZE +create index idx2 on worklog5743_2(a2(4000)); +show warnings; +-- error ER_TOO_BIG_ROWSIZE +create index idx3 on worklog5743_2(a2(948)); +show warnings; +# Bug#13391353 Limit is one byte less on on 32bit-Linux only +create index idx4 on worklog5743_2(a2(946)); +show warnings; +-- error ER_TOO_BIG_ROWSIZE +create index idx5 on worklog5743_2(a1, a2(942)); +show warnings; +# Bug#13391353 Limit is one byte less on on 32bit-Linux only +create index idx6 on worklog5743_2(a1, a2(940)); +show warnings; + +# Test edge cases for indexes using key_block_size=4 +set global innodb_large_prefix=0; +create index idx1 on worklog5743_4(a2(4000)); +show warnings; +set global innodb_large_prefix=1; +create index idx3 on worklog5743_4(a2(1537)); +show warnings; +create index idx4 on worklog5743_4(a2(1536)); +show warnings; +-- error ER_TOO_LONG_KEY +create index idx5 on worklog5743_4(a1, a2(1533)); +show warnings; +create index idx6 on worklog5743_4(a1, a2(1532)); +show warnings; + +# Test edge cases for indexes using key_block_size=8 +set global innodb_large_prefix=0; +create index idx1 on worklog5743_8(a2(1000)); +show warnings; +set global innodb_large_prefix=1; +create index idx2 on worklog5743_8(a2(3073)); +show warnings; +create index idx3 on worklog5743_8(a2(3072)); +show warnings; +-- error ER_TOO_LONG_KEY +create index idx4 on worklog5743_8(a1, a2(1533)); +show warnings; +create index idx5 on worklog5743_8(a1, a2(1532)); +show warnings; + +# Insert a large record into each of these tables. +insert into worklog5743_1 values(9, repeat("a", 10000)); +insert into worklog5743_2 values(9, repeat("a", 10000)); +insert into worklog5743_4 values(9, repeat("a", 10000)); +insert into worklog5743_8 values(9, repeat("a", 10000), repeat("a", 10000)); + +# Now if we change the global innodb_large_prefix back to 767, +# updates to these indexes should still be allowed. +set global innodb_large_prefix=0; +insert into worklog5743_1 values(2, repeat("b", 10000)); +insert into worklog5743_2 values(2, repeat("b", 10000)); +insert into worklog5743_4 values(2, repeat("b", 10000)); +insert into worklog5743_8 values(2, repeat("b", 10000), repeat("b", 10000)); +set global innodb_large_prefix=1; + +select a1, left(a2, 20) from worklog5743_1; +select a1, left(a2, 20) from worklog5743_2; +select a1, left(a2, 20) from worklog5743_4; +select a1, left(a2, 20) from worklog5743_8; + +begin; + +update worklog5743_1 set a1 = 1000; +update worklog5743_2 set a1 = 1000; +update worklog5743_4 set a1 = 1000; +update worklog5743_8 set a1 = 1000; +select a1, left(a2, 20) from worklog5743_1; +select a1, left(a2, 20) from worklog5743_2; +select a1, left(a2, 20) from worklog5743_4; +select a1, left(a2, 20) from worklog5743_8; + + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1, left(a2, 20) from worklog5743_1 where a1 = 9; +explain select a1, left(a2, 20) from worklog5743_2 where a1 = 9; +explain select a1, left(a2, 20) from worklog5743_4 where a1 = 9; +explain select a1, left(a2, 20) from worklog5743_8 where a1 = 9; +select a1, left(a2, 20) from worklog5743_1 where a1 = 9; +select a1, left(a2, 20) from worklog5743_2 where a1 = 9; +select a1, left(a2, 20) from worklog5743_4 where a1 = 9; +select a1, left(a2, 20) from worklog5743_8 where a1 = 9; + +# Do read uncommitted in another session, it would show there is no +# row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1, left(a2, 20) from worklog5743_1 where a1 = 9; +select a1, left(a2, 20) from worklog5743_2 where a1 = 9; +select a1, left(a2, 20) from worklog5743_4 where a1 = 9; +select a1, left(a2, 20) from worklog5743_8 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743_1; +drop table worklog5743_2; +drop table worklog5743_4; +drop table worklog5743_8; + +-- echo ### Test 5 ### +# Create a table with large varchar columns and create indexes +# directly on these large columns to show that prefix limit is +# automatically applied and to show that limit. + +# This commented form of the test causes an unlimited page split +# on update of the int field - Bug 12636590 - INNODB; UPDATE OF +# LARGE RECORD CAUSES UNLIMITED PAGE SPLITS IN 8K PAGE SIZE +#create table worklog5743(a1 int, +# a2 varchar(20000), +# a3 varchar(3073), +# a4 varchar(3072), +# a5 varchar(3069), +# a6 varchar(3068)) +# ROW_FORMAT=DYNAMIC; +#create index idx1 on worklog5743(a2); +#create index idx2 on worklog5743(a3); +#create index idx3 on worklog5743(a4); +#show warnings; +#-- error ER_TOO_LONG_KEY +#create index idx4 on worklog5743(a1, a2); +#show warnings; +#-- error ER_TOO_LONG_KEY +#create index idx5 on worklog5743(a1, a5); +#show warnings; +#create index idx6 on worklog5743(a1, a6); +#show warnings; +#show create table worklog5743; +# +#insert into worklog5743 values(9, +# repeat("a", 20000), repeat("a", 3073), +# repeat("a", 3072), repeat("a", 3069), +# repeat("a", 3068)); +# + +create table worklog5743(a1 int, a2 varchar(20000)) ROW_FORMAT=DYNAMIC; +-- error ER_TOO_LONG_KEY +create index idx1 on worklog5743(a2); +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(1537)) ROW_FORMAT=DYNAMIC; +-- error ER_TOO_LONG_KEY +create index idx1 on worklog5743(a2); +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(1536)) ROW_FORMAT=DYNAMIC; +create index idx1 on worklog5743(a2); +show warnings; +insert into worklog5743 values(9, repeat("a", 1536)); +update worklog5743 set a1 = 1000; +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(1533)) ROW_FORMAT=DYNAMIC; +-- error ER_TOO_LONG_KEY +create index idx1 on worklog5743(a1, a2); +show warnings; +drop table worklog5743; + +create table worklog5743(a1 int, a2 varchar(1532)) ROW_FORMAT=DYNAMIC; +create index idx1 on worklog5743(a1, a2); +show warnings; +insert into worklog5743 values(9, repeat("a", 1532)); +update worklog5743 set a1 = 1000; + +begin; +update worklog5743 set a1 = 1000; + +# Do a select from another connection that would use the secondary index +--connection con1 +select @@session.tx_isolation; +explain select a1 from worklog5743 where a1 = 9; +select a1 from worklog5743 where a1 = 9; + +# Do read uncommitted, it would show there is no row with a1 = 9 +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a1 from worklog5743 where a1 = 9; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 6 ### +# Create a table with old format, and the limit is 768 bytes. +-- error ER_INDEX_COLUMN_TOO_LONG +create table worklog5743(a TEXT not null, primary key (a(1000))); + +create table worklog5743(a TEXT); + +# Excercise the column length check in ha_innobase::add_index() +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(768)); + +# This should be successful +create index idx on worklog5743(a(767)); + +# Perform some DMLs +insert into worklog5743 values(repeat("a", 20000)); + +begin; +insert into worklog5743 values(repeat("b", 20000)); +update worklog5743 set a = (repeat("x", 25000)); + +# Start a new session to select the table to force it build +# an earlier version of the cluster index through undo log +select @@session.tx_isolation; +--connection con1 +select a = repeat("a", 20000) from worklog5743; + +--connection con2 +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +select @@session.tx_isolation; +select a = repeat("x", 25000) from worklog5743; + +--connection default +rollback; + +drop table worklog5743; + +-- echo ### Test 7 ### +# Some border line tests on the column length. +# We have a limit of 3072 bytes for Barracuda table +create table worklog5743(a TEXT not null) ROW_FORMAT=DYNAMIC; + +# Length exceeds maximum supported key length +# It will be auto-truncated to 3072 +create index idx1 on worklog5743(a(3073)); +create index idx2 on worklog5743(a(3072)); +show create table worklog5743; +drop table worklog5743; + +# We have a limit of 767 bytes for Antelope tables +create table worklog5743(a TEXT not null) ROW_FORMAT=REDUNDANT; +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(768)); +create index idx2 on worklog5743(a(767)); +drop table worklog5743; + +create table worklog5743(a TEXT not null) ROW_FORMAT=COMPACT; +-- error ER_INDEX_COLUMN_TOO_LONG +create index idx on worklog5743(a(768)); +create index idx2 on worklog5743(a(767)); +drop table worklog5743; + + +eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; +eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; +eval SET GLOBAL innodb_large_prefix=$innodb_large_prefix_orig; +--connection con1 +--disconnect con1 +--source include/wait_until_disconnected.inc +--connection con2 +--disconnect con2 +--source include/wait_until_disconnected.inc +--connection default + diff --git a/mysql-test/suite/innodb_zip/t/innodb_wl6347_comp_indx_stat.test b/mysql-test/suite/innodb_zip/t/innodb_wl6347_comp_indx_stat.test new file mode 100644 index 00000000000..3e4466d1b28 --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/innodb_wl6347_comp_indx_stat.test @@ -0,0 +1,1342 @@ +#****************************************************************** +# test the interaction between wl6347 & wl6344 (2.1) +# This testcase is to verify the table/idex level comoression stats +# When the flags are set as follows +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=0 +# page size 1K,2K,4K,8K,16K +# check the size and compression stats of the table tab5 +#****************************************************************** + +# This test case needs InnoDB. +-- source include/have_innodb.inc +-- source include/not_embedded.inc +-- source include/have_innodb_16k.inc +-- source include/not_valgrind.inc + +-- vertical_results + +let MYSQLD_DATADIR=`SELECT @@datadir`; +let $innodb_compression_level = `SELECT @@global.innodb_compression_level`; + +--echo # set the flags +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_cmp_per_index_enabled=ON; +SET GLOBAL innodb_compression_level=0; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=0 +# with page size 1K +#****************************************************************** + +--echo # create a table with page size=1K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=1; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for deterministic reasons simple data should be inserted. +--echo # insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # Restarting server +-- source include/restart_mysqld.inc + +--echo # set the flag on (default off) +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_compression_level=0; + +--echo # fetch the compressed page and check the stats +--echo # The stats figure may be different/same for each restart. +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table +-- echo # testcase : pass = 1 fail = 0 +SET @comp_val=0; +SET @uncomp_val=1; +--source suite/innodb_zip/include/innodb_stats_restart.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=0 +# with page size 2K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=0; +SET GLOBAL innodb_cmp_per_index_enabled=1; + +--echo # create a table with page size=2K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=2; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # Restarting server +-- source include/restart_mysqld.inc + +--echo # set the flag on (default off) +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_compression_level=0; + +--echo # fetch the compressed page and check the stats +--echo # The stats figure may be different/same for each restart. +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table +-- echo # testcase : pass = 1 fail = 0 +SET @comp_val=0; +SET @uncomp_val=2; +--source suite/innodb_zip/include/innodb_stats_restart.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=0 +# with page size 4K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=0; +SET GLOBAL innodb_cmp_per_index_enabled=1; + +--echo # create a table with page size=4K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=4; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=0 +# with page size 8K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=0; +SET GLOBAL innodb_cmp_per_index_enabled=1; + +--echo # create a table with page size=8K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=8; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=0 +# with page size 16K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=0; +SET GLOBAL innodb_cmp_per_index_enabled=1; + +--echo # create a table with page size=16K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=16; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# test the interaction between wl6347 & wl6344 (2.2) +# This testcase is to verify the table/idex level comoression stats +# When the flags are set as follows +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=9 +# page size 1K,2K,4K,8K,16K +# check the size and compression stats of the table tab5 +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=0; +SET GLOBAL innodb_cmp_per_index_enabled=1; + +--echo # set the flags +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_compression_level=9; + + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=9 +# with page size 1K +#****************************************************************** + +--echo # create a table with page size=1K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=1; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 65536 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 2097152 +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # Restarting server +-- source include/restart_mysqld.inc + +--echo # set the flag on (default off) +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_compression_level=9; + + +--echo # fetch the compressed page and check the stats +--echo # The stats figure may be different/same for each restart. +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table +-- echo # testcase : pass = 1 fail = 0 +SET @comp_val=0; +SET @uncomp_val=1; +--source suite/innodb_zip/include/innodb_stats_restart.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=9 +# with page size 2K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=2K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=2; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 65536 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 2097152 +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # Restarting server +-- source include/restart_mysqld.inc + +--echo # set the flag on (default off) +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_compression_level=9; + + +--echo # fetch the compressed page and check the stats +--echo # The stats figure may be different/same for each restart. +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table +-- echo # testcase : pass = 1 fail = 0 +SET @comp_val=0; +SET @uncomp_val=1; +--source suite/innodb_zip/include/innodb_stats_restart.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=9 +# with page size 4K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=4K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=4; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 65536 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 159744 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=9 +# with page size 8K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=8K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=8; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 122880 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 212992 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=9 +# with page size 16K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=16K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=16; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 245760 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 344064 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# test the interaction between wl6347 & wl6344 (2.3) +# This testcase is to verify the table/idex level comoression stats +# When the flags are set as follows +# innodb_cmp_per_index_enabled=ON and +# innodb_compression_level=6 (default) +# page size 1K,2K,4K,8K,16K +# check the size and compression stats of the table tab5 +#****************************************************************** + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=Def +# with page size 1K +#****************************************************************** + + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +SET GLOBAL innodb_compression_level=default; + +--echo # create a table with page size=1K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=1; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 65536 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 65536 +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=Def +# with page size 4K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +SET GLOBAL innodb_compression_level=default; + +--echo # create a table with page size=4K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=4; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 65536 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 86016 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=Def +# with page size 8K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +SET GLOBAL innodb_compression_level=default; + +--echo # create a table with page size=8K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=8; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 122880 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 172032 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and innodb_compression_level=Def +# with page size 16K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +SET GLOBAL innodb_compression_level=default; + +--echo # create a table with page size=16K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=16; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 245760 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +--echo # The size of the file with 0 compress = 344064 +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# Test the interaction between wl6347 & wl6344 (2.5 & 2.6) +# This testcase is to verify the table/idex level comoression stats +# When the flags are set as follows +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=0 +# page size 1K,2K,4K,8K,16K +# check the size and compression stats of the table tab5 +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_compression_failure_threshold_pct=0; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # check the flags +SELECT @@innodb_cmp_per_index_enabled; +SELECT @@innodb_compression_failure_threshold_pct; +SELECT @@innodb_file_format; +SELECT @@innodb_file_per_table; +SELECT @@innodb_compression_level; + + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=0 with page size 1K +#****************************************************************** + +--echo # create a table with page size=1K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=1; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # Restarting server +-- source include/restart_mysqld.inc + +--echo # set the flag on (default off) +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_compression_failure_threshold_pct=0; +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; + + +--echo # fetch the compressed page and check the stats +--echo # The stats figure may be different/same for each restart. +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table +-- echo # testcase : pass = 1 fail = 0 +SET @comp_val=0; +SET @uncomp_val=1; +--source suite/innodb_zip/include/innodb_stats_restart.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=0 with page size 2K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=2K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=2; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=0 with page size 4K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=4K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=4; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=0 with page size 8K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=8K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=8; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=0 with page size 16K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=16K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=16; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# Test the interaction between wl6347 & wl6344 (2.7) +# This testcase is to verify the table/idex level comoression stats +# When the flags are set as follows +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=10 +# page size 1K,2K,4K,8K,16K +# check the size and compression stats of the table tab5 +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_cmp_per_index_enabled=ON; +SET GLOBAL innodb_compression_failure_threshold_pct=10; +SET GLOBAL innodb_compression_level=Default; + + +--echo # check the flags +SELECT @@innodb_cmp_per_index_enabled; +SELECT @@innodb_compression_failure_threshold_pct; +SELECT @@innodb_file_format; +SELECT @@innodb_file_per_table; +SELECT @@innodb_compression_level; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=10 with page size 1K +#****************************************************************** + +--echo # create a table with page size=1K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=1; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # Restarting server +-- source include/restart_mysqld.inc + +--echo # set the flag on (default off) +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # set the flags +SET GLOBAL innodb_compression_failure_threshold_pct=10; +SET GLOBAL innodb_file_per_table=on; +SET GLOBAL innodb_file_format='barracuda'; +SET GLOBAL innodb_compression_failure_threshold_pct=10; + + +--echo # fetch the compressed page and check the stats +--echo # The stats figure may be different/same for each restart. +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table +-- echo # testcase : pass = 1 fail = 0 +SET @comp_val=0; +SET @uncomp_val=1; +--source suite/innodb_zip/include/innodb_stats_restart.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=10 with page size 2K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; +SET GLOBAL innodb_compression_failure_threshold_pct=10; + +--echo # create a table with page size=2K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=2; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=2; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=10 with page size 4K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=4K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=4; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=10 with page size 8K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; +SET GLOBAL innodb_compression_failure_threshold_pct=10; + +--echo # create a table with page size=8K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=8; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# innodb_cmp_per_index_enabled=ON and +# Innodb_compression_failure_threshold_pct=10 with page size 16K +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=OFF; +SET GLOBAL innodb_cmp_per_index_enabled=ON; + +--echo # create a table with page size=16K +--echo # create indexes on each column.(total 9 indexes) +let $block_size=16; +--source suite/innodb_zip/include/innodb_create_tab_indx.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # for determintic resons simple data should be inserted. +--echo #insert some 100 records +let $i = 100; +--source suite/innodb_zip/include/innodb_load_data.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed page and check the stats +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +--echo # fetch the compressed same page once again and check the stats +--echo # the stat figures should be same as above query +--source suite/innodb_zip/include/innodb_fetch_records.inc + +--echo # check the stats of the table & size of the table +SET @inl_val=1; +--source suite/innodb_zip/include/innodb_stats_comp_index.inc + +DROP TABLE tab5; + +#****************************************************************** +# Create multiple tables & indexes having same name in 2 diff DB's +# Check the stats of the table. (1.1) +#****************************************************************** + +--echo #reset the stat table before starting next testcase +SET GLOBAL innodb_cmp_per_index_enabled=0; +SET GLOBAL innodb_cmp_per_index_enabled=1; + +SET GLOBAL innodb_file_per_table=ON; +SET GLOBAL innodb_file_format='Barracuda'; +SET GLOBAL innodb_compression_level=default; +SET GLOBAL innodb_compression_failure_threshold_pct=default; + + +--echo #create a table page size=1K +CREATE TABLE tab5(col_1 TINYBLOB, col_2 TINYTEXT,col_3 BLOB, +col_4 TEXT,col_5 MEDIUMBLOB,col_6 MEDIUMTEXT, +col_7 LONGBLOB,col_8 LONGTEXT,col_9 VARCHAR(255)) +ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; + +CREATE INDEX idx1 ON tab5(col_1(10)); + +--echo #check the stats of the table +SELECT database_name,table_name,index_name,compress_ops,compress_ops_ok +FROM information_schema.innodb_cmp_per_index +WHERE database_name='test' and table_name='tab5' +ORDER BY index_name,table_name,database_name ; + +CREATE DATABASE sb; +USE sb; + +--echo #create a table page size=1K (testcase-1) +CREATE TABLE tab5(col_1 TINYBLOB, col_2 TINYTEXT,col_3 BLOB, +col_4 TEXT,col_5 MEDIUMBLOB,col_6 MEDIUMTEXT, +col_7 LONGBLOB,col_8 LONGTEXT,col_9 VARCHAR(255)) +ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; + +CREATE INDEX idx1 ON tab5(col_1(10)); + +SELECT database_name,table_name,index_name,compress_ops,compress_ops_ok +FROM information_schema.innodb_cmp_per_index +WHERE database_name='sb' and table_name='tab5' +ORDER BY index_name,table_name,database_name ; + +DROP TABLE tab5, test.tab5; +DROP DATABASE sb; + +--echo # reset the flags +eval SET GLOBAL innodb_file_per_table=default; +eval SET GLOBAL innodb_file_format=default; +eval SET GLOBAL innodb_cmp_per_index_enabled=default; +--disable_query_log +eval SET GLOBAL innodb_compression_level=$innodb_compression_level; +--enable_query_log +eval SET GLOBAL innodb_compression_failure_threshold_pct=default; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index e252b606860..616a981906d 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1,3 +1,4 @@ +# if (`select plugin_auth_version < "5.6.26" from information_schema.plugins where plugin_name='innodb'`) { --skip Not fixed in XtraDB below 5.6.26 @@ -172,7 +173,7 @@ drop table t1; # Test of ALTER TABLE DELAYED # -CREATE TABLE t1 (i int(10), index(i) ) ENGINE=MyISAM; +CREATE TABLE t1 (i int(10), index(i) ); ALTER TABLE t1 DISABLE KEYS; INSERT DELAYED INTO t1 VALUES(1),(2),(3); ALTER TABLE t1 ENABLE KEYS; @@ -287,7 +288,7 @@ drop table t1; # set names koi8r; create table t1 (a char(10) character set koi8r); -insert into t1 values ('ÔÅÓÔ'); +insert into t1 values ('ÔÅÓÔ'); select a,hex(a) from t1; alter table t1 change a a char(10) character set cp1251; select a,hex(a) from t1; @@ -367,7 +368,7 @@ DROP TABLE T12207; # modified. In other words, the values were reinterpreted # as UTF8 instead of being converted. create table t1 (a text) character set koi8r; -insert into t1 values (_koi8r'ÔÅÓÔ'); +insert into t1 values (_koi8r'ÔÅÓÔ'); select hex(a) from t1; alter table t1 convert to character set cp1251; select hex(a) from t1; @@ -1809,3 +1810,546 @@ ALTER COLUMN `consultant_id` DROP DEFAULT, MODIFY COLUMN `consultant_id` BIGINT; SHOW CREATE TABLE t1; DROP TABLE t1; + + + + +--echo # +--echo # BUG#17246318 - ALTER TABLE SHOULD NOT ALLOW CREATION OF TABLES +--echo # WITH BOTH 5.5 AND 5.6 TEMPORALS +--echo # + +--echo # BUG 18985760 -"FAST" ALTER TABLE CHANGE ON ENUM COLUMN +--echo # TRIGGERS FULL TABLE REBUILD. +--echo # Test for the case where 'avoid_temporal_upgrade' is set +--echo # to the DEFAULT value(OFF). + +let $MYSQLD_DATADIR= `select @@datadir`; +--copy_file std_data/55_temporal.frm $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/55_temporal.MYD $MYSQLD_DATADIR/test/t1.MYD +--copy_file std_data/55_temporal.MYI $MYSQLD_DATADIR/test/t1.MYI + +ALTER TABLE t1 ENGINE= INNODB; + +--echo #ALTER operations using INPLACE algorithm is disallowed +--echo #since the table contains old temporal type. + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD COLUMN fld4 TIMESTAMP, ALGORITHM= INPLACE; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD COLUMN fld4 TIMESTAMP FIRST, ALGORITHM= INPLACE; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD COLUMN fld4 TIMESTAMP AFTER f_timestamp, ALGORITHM= INPLACE; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 CHANGE COLUMN f_time fld4 TIMESTAMP, ALGORITHM= INPLACE; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 MODIFY f_datetime TIME, ALGORITHM= INPLACE; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD INDEX index1(f_datetime), ALGORITHM= INPLACE; + +--echo #ALTER operations using COPY algorithm is allowed +--echo #when the table contains old temporal type. + +--echo #Note: Timestamp encoding remains the same for the non-fractional part +--echo #even in the 5.6 format. Hence there is no change in the display before +--echo #and after upgrade. + +--echo #ADD COLUMN upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP, ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ADD COLUMN FIRST upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP FIRST, ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ADD COLUMN AFTER upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP AFTER f_timestamp, ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #CHANGE COLUMN upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 CHANGE COLUMN f_timestamp fld4 TIMESTAMP, ALGORITHM= COPY; +SELECT f_time, f_datetime, fld4, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(fld4)) FROM t2; +DROP TABLE t2; + +--echo #MODIFY COLUMN upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 MODIFY f_timestamp TIME, ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ADD INDEX upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD INDEX index1(f_timestamp), ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ALTER operations using DEFAULT algorithm is allowed +--echo #when the table contains old temporal type. + +--echo #ADD COLUMN upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ADD COLUMN FIRST upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP FIRST, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ADD COLUMN AFTER upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP AFTER f_timestamp, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #CHANGE COLUMN upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 CHANGE COLUMN f_timestamp fld4 DATETIME, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, fld4, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(fld4)) FROM t2; +DROP TABLE t2; + +--echo #MODIFY COLUMN upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 MODIFY f_timestamp TIME, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ADD INDEX upgrades the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD INDEX index1(f_timestamp), ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ALTER TABLE FORCE upgrades the old temporal types. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 FORCE; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #Examples where the NOT NULL/NULL FLAG and DEFAULT values are retained +--echo #after upgrade. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +--echo #Before upgrade. +SHOW CREATE TABLE t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP, ALGORITHM= COPY; +--echo #After upgrade. +SHOW CREATE TABLE t2; + +--echo #Examples of the Alter operation which does not upgrade +--echo #the temporal formats. + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t1; + +ALTER TABLE t1 DROP COLUMN f_timestamp; +SELECT f_time, f_datetime, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)) FROM t1; + +RENAME TABLE t1 to t3; +SELECT f_time, f_datetime, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)) FROM t3; + +--echo #Once the old temporal type is upgraded to new temporal type, +--echo #ADD/CHANGE COLUMN, ADD INDEX operations succeed using INPLACE +--echo #ALGORITHM. + +ALTER TABLE t2 ADD COLUMN fld5 INT, ALGORITHM= INPLACE; + +ALTER TABLE t2 ADD INDEX index2(fld5), ALGORITHM= INPLACE; + +ALTER TABLE t2 CHANGE fld5 fld6 INT, ALGORITHM= INPLACE; + +ALTER TABLE t2 MODIFY fld6 INT, ALGORITHM= INPLACE; + +--echo #Cleanup +DROP TABLE t2, t3; + + +--echo # +--echo # BUG 18985760 -"FAST" ALTER TABLE CHANGE ON ENUM COLUMN +--echo # TRIGGERS FULL TABLE REBUILD. +--echo # + + +let $MYSQLD_DATADIR= `select @@datadir`; +--copy_file std_data/55_temporal.frm $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/55_temporal.MYD $MYSQLD_DATADIR/test/t1.MYD +--copy_file std_data/55_temporal.MYI $MYSQLD_DATADIR/test/t1.MYI + +--echo # To support INPLACE ALTER table operations later in the test. +ALTER TABLE t1 ENGINE= INNODB; + +--echo #Test cases with the global variable 'avoid_temporal_upgrade' +--echo #enabled. + +SET @save_avoid_temporal_upgrade= @@global.avoid_temporal_upgrade; +SET GLOBAL avoid_temporal_upgrade= ON; + +--echo #ALTER operations using INPLACE algorithm are allowed +--echo #when the table contains old temporal type since +--echo #the global variable 'avoid_temporal_upgrade' is +--echo #enabled. The old temporal types are not upgraded. + +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP, ALGORITHM= INPLACE; +SELECT f_time, f_datetime, f_timestamp, fld4, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)), + HEX(WEIGHT_STRING(fld4)) FROM t2; + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld5 TIME DEFAULT '101010' FIRST, ALGORITHM= INPLACE; +SELECT f_time, f_datetime, f_timestamp, fld5, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)), + HEX(WEIGHT_STRING(fld5)) FROM t2; + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld6 TIMESTAMP AFTER f_timestamp, ALGORITHM= INPLACE; +SELECT f_time, f_datetime, f_timestamp, fld6, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)), + HEX(WEIGHT_STRING(fld6)) FROM t2; + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD INDEX index1(f_datetime), ALGORITHM= INPLACE; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ALTER operations using COPY algorithm are allowed +--echo #when the table contains old temporal type and +--echo #does not upgrade the old temporal types. + +--echo #ADD COLUMN does not upgrade the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP, ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #ADD COLUMN FIRST does not upgrade the old temporal type. +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld5 TIMESTAMP FIRST, ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #ADD COLUMN AFTER does not upgrade the old temporal type. +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld6 TIMESTAMP AFTER f_timestamp, ALGORITHM= COPY; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #CHANGE COLUMN upgrades the old temporal type only for the column which +--echo #is changed. +#Setup table having old temporal type. +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 CHANGE COLUMN f_datetime fld7 DATETIME, ALGORITHM= COPY; +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #MODIFY COLUMN upgrades the old temporal type only for the column +--echo #modified. +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 MODIFY f_timestamp DATETIME, ALGORITHM= COPY; +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #ADD INDEX does not upgrade the old temporal type. +#Setup table having old temporal type. +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD INDEX index1(f_time), ALGORITHM= COPY; +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ALTER operations using DEFAULT algorithm are allowed +--echo #when the table contains old temporal type and does not +--echo #upgrade the old temporal types. + +--echo #ADD COLUMN does not upgrade the old temporal type. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld4 TIMESTAMP, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #ADD COLUMN FIRST does not upgrade the old temporal type. +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld5 TIMESTAMP FIRST, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #ADD COLUMN AFTER does not upgrade the old temporal type. +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD COLUMN fld6 TIMESTAMP AFTER f_timestamp, ALGORITHM= DEFAULT; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #CHANGE COLUMN upgrades the old temporal type only for the column which +--echo #is changed. +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 CHANGE COLUMN f_datetime fld7 DATETIME, ALGORITHM= DEFAULT; +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #MODIFY COLUMN upgrades the old temporal type only for the column +--echo #modified. +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 MODIFY f_timestamp DATETIME, ALGORITHM= DEFAULT; +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; + +--echo #ADD INDEX does not upgrade the old temporal type. +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 ADD INDEX index1(f_time), ALGORITHM= DEFAULT; +SELECT f_time, fld7, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(fld7)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +--echo #ALTER TABLE FORCE does not upgrade the old temporal types. +#Setup table having old temporal type. +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES ('22:22:22','2011-11-21 22:22:22','2011-11-21 22:22:22'); + +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +ALTER TABLE t2 FORCE; +SELECT f_time, f_datetime, f_timestamp, HEX(WEIGHT_STRING(f_time)), + HEX(WEIGHT_STRING(f_datetime)), HEX(WEIGHT_STRING(f_timestamp)) FROM t2; +DROP TABLE t2; + +SET @@global.avoid_temporal_upgrade= @save_avoid_temporal_upgrade; + +--echo #Test cases with the session variable 'show_old_temporals' +--echo #enabled. + +--echo #Setup +CREATE TABLE t2(fld1 time, fld2 datetime, fld3 timestamp); +SET @save_show_old_temporals= @@session.show_old_temporals; +SET SESSION show_old_temporals= ON; + +--echo #Displays a comment to indicate that the columns are of 5.5 +--echo #binary format +SHOW CREATE TABLE t1; +SELECT COLUMN_TYPE FROM information_schema.columns WHERE table_name='t1'; + +--echo #Since the temporal types are in new format, no comment is +--echo #displayed +SHOW CREATE TABLE t2; +SELECT COLUMN_TYPE FROM information_schema.columns WHERE table_name='t2'; + +--echo #Does not display the comment for table with old temporal types +--echo #since the session variable 'show_old_temporals' is OFF. +SET SESSION show_old_temporals= OFF; +SHOW CREATE TABLE t1; +SELECT COLUMN_TYPE FROM information_schema.columns WHERE table_name='t1'; + +--echo #Cleanup +SET @@session.show_old_temporals= @save_show_old_temporals; +DROP TABLE t1, t2; + + +--echo # +--echo # Bug#21345391: ALTER TABLE ... CONVERT TO CHARACTER SET NOT EFFECT +--echo # AND REMAIN A TEMP TABLE + +CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE = INNODB CHARACTER SET gbk; +ALTER TABLE t1 CONVERT TO CHARACTER SET UTF8, ALGORITHM = INPLACE; + +--echo # Without fix, the CHARSET SET for table remains gbk. +SHOW CREATE TABLE t1; + +let $test_dir = + `SELECT CONCAT(variable_value, 'test/') FROM + INFORMATION_SCHEMA.GLOBAL_VARIABLES + WHERE LOWER(variable_name) = 'datadir'`; + +--echo # Without fix, the temporary .frm file is not cleaned up. +--list_files $test_dir `#sql-*.frm` + +DROP TABLE t1; + +--echo # Test cases added for coverage. + +--echo # Reports an error for tables containing datatypes supporting +--echo # characters. + +CREATE TABLE t1 (fld1 CHAR(10) PRIMARY KEY) ENGINE = INNODB CHARACTER SET gbk; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 CONVERT TO CHARACTER SET UTF8, ALGORITHM = INPLACE; + +DROP TABLE t1; + +--echo # ALTER TABLE, CHARACTER SET operation. + +CREATE TABLE t1 (fld1 INT PRIMARY KEY, fld2 CHAR(10)) ENGINE = INNODB +CHARACTER SET gbk; +ALTER TABLE t1 CHARACTER SET UTF8, ALGORITHM = INPLACE; + +SHOW CREATE TABLE t1; + +let $test_dir = + `SELECT CONCAT(variable_value, 'test/') FROM + INFORMATION_SCHEMA.GLOBAL_VARIABLES + WHERE LOWER(variable_name) = 'datadir'`; + +--list_files $test_dir `#sql-*.frm` + +DROP TABLE t1; + + +--echo # +--echo # Bug#19635706 +--echo # Verify that it is possible to add a unique key to a not-NULL POINT +--echo # column and that this key is promoted to primary key +--echo # + +CREATE TABLE t1(a INT NOT NULL, b POINT NOT NULL) ENGINE=INNODB; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD UNIQUE INDEX (b); + +--echo # Note that SHOW CREATE TABLE does not list b as a primary key, +--echo # even though it was promoted. This appears to be the case also +--echo # for other column types. +SHOW CREATE TABLE t1; + +ALTER TABLE t1 ADD UNIQUE INDEX (a); +SHOW CREATE TABLE t1; + +--echo # Verify that the expected indices have been created by Innodb +SELECT T.NAME AS TABLE_NAME, I.NAME AS INDEX_NAME, + CASE I.TYPE + WHEN 0 THEN 'Secondary' + WHEN 1 THEN 'Clustered' + WHEN 2 THEN 'Unique' + WHEN 3 THEN 'Primary' + WHEN 32 THEN 'Full text' + WHEN 64 THEN 'Spatial' + ELSE 'Unknown' + END AS INDEX_TYPE, + F.NAME AS FIELD_NAME, F.POS AS FIELD_POS FROM + INFORMATION_SCHEMA.INNODB_SYS_TABLES AS T JOIN + INFORMATION_SCHEMA.INNODB_SYS_INDEXES AS I JOIN + INFORMATION_SCHEMA.INNODB_SYS_FIELDS AS F + ON I.INDEX_ID = F.INDEX_ID AND I.TABLE_ID = T.TABLE_ID + WHERE T.NAME = 'test/t1'; + +DROP TABLE t1; |