summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlice Sherepa <alice.sherepa@gmail.com>2017-09-27 11:25:44 +0200
committerAlice Sherepa <alice.sherepa@gmail.com>2017-09-27 11:25:44 +0200
commitdbaa8dda56519891811f331a031e76ed26d36334 (patch)
tree53ccf6537e708e09d7d0f778218700ff7da19388
parent19d21b9366c1eb5c1c1e822a09969e9a23bfe2c3 (diff)
downloadmariadb-git-bb-10.0-alice13625.tar.gz
tests merged 10.0 with mysql 5.6.37bb-10.0-alice13625
-rw-r--r--mysql-test/suite/innodb/t/add_foreign_key.test38
-rw-r--r--mysql-test/suite/innodb/t/analyze_table.test42
-rw-r--r--mysql-test/suite/innodb/t/blob_redo-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/blob_redo.test92
-rw-r--r--mysql-test/suite/innodb/t/checksum.test15
-rw-r--r--mysql-test/suite/innodb/t/create_isl_with_direct-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/create_isl_with_direct.test27
-rw-r--r--mysql-test/suite/innodb/t/disabled.def11
-rw-r--r--mysql-test/suite/innodb/t/end_range_check.test77
-rw-r--r--mysql-test/suite/innodb/t/flush-hang.test50
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test87
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty.test102
-rw-r--r--mysql-test/suite/innodb/t/import.test25
-rw-r--r--mysql-test/suite/innodb/t/import_update_stats.test78
-rw-r--r--mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb-2byte-collation.test88
-rw-r--r--mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test123
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc-master.opt3
-rw-r--r--mysql-test/suite/innodb/t/innodb-bug12552164.test50
-rw-r--r--mysql-test/suite/innodb/t/innodb-bug14219515.test19
-rw-r--r--mysql-test/suite/innodb/t/innodb-double-write.test388
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-debug-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test115
-rw-r--r--mysql-test/suite/innodb/t/innodb-log-file-size-1.test300
-rw-r--r--mysql-test/suite/innodb/t/innodb-log-file-size.test213
-rw-r--r--mysql-test/suite/innodb/t/innodb-multiple-tablespaces.test538
-rw-r--r--mysql-test/suite/innodb/t/innodb-read-view.test176
-rw-r--r--mysql-test/suite/innodb/t/innodb-status-output.test108
-rw-r--r--mysql-test/suite/innodb/t/innodb-system-table-view.test171
-rw-r--r--mysql-test/suite/innodb/t/innodb-tablespace.test473
-rw-r--r--mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb-use-sys-malloc.test45
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5980-debug.test91
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5980-discard.test750
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5980-linux.test191
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5980-windows.test237
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl6445-1.test758
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl6445-2.test245
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl6445.test103
-rw-r--r--mysql-test/suite/innodb/t/innodb_autoinc_reset.test25
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_load-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_load.test115
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug-13628249.test125
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug11766634-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug11766634.test76
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug11789106.test17
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug11933790.test42
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug12429573.test42
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug13635833.test64
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug13867871.test199
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14006907.test56
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14007109.test38
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14169459.test64
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug47167-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug59307.test32
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug70867.test53
-rw-r--r--mysql-test/suite/innodb/t/innodb_copy_col_in_partition.test21
-rw-r--r--mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_deadlock_with_autoinc.test47
-rw-r--r--mysql-test/suite/innodb/t/innodb_file_format-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_file_limit_check-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_file_limit_check.test31
-rw-r--r--mysql-test/suite/innodb/t/innodb_force_recovery.test228
-rw-r--r--mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test174
-rw-r--r--mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test100
-rw-r--r--mysql-test/suite/innodb/t/innodb_io_pf.test15
-rw-r--r--mysql-test/suite/innodb/t/innodb_misc1-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_misc1.test1171
-rw-r--r--mysql-test/suite/innodb/t/innodb_page_size_func.test296
-rw-r--r--mysql-test/suite/innodb/t/innodb_replace.test186
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test48
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test49
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test44
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test85
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_del_mark-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_del_mark.test130
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_external_pages.test83
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_flag_global_off-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_flag_global_off.test10
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_flag_global_on-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_flag_global_on.test10
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_sample_pages.test53
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test83
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test103
-rw-r--r--mysql-test/suite/innodb/t/innodb_upd_stats_if_needed_not_inited.test38
-rw-r--r--mysql-test/suite/innodb/t/innodb_ut_format_name.test16
-rw-r--r--mysql-test/suite/innodb/t/monitor.test440
-rw-r--r--mysql-test/suite/innodb/t/monitor_debug.test40
-rw-r--r--mysql-test/suite/innodb/t/portability_wl5980_linux.zipbin0 -> 484373 bytes
-rw-r--r--mysql-test/suite/innodb/t/portability_wl5980_windows.zipbin0 -> 526578 bytes
-rw-r--r--mysql-test/suite/innodb/t/strict_checksum.test68
-rw-r--r--mysql-test/suite/innodb/t/undo_space_id.test30
-rw-r--r--mysql-test/suite/innodb_fts/t/disabled.def11
-rw-r--r--mysql-test/suite/innodb_fts/t/fts_compatibility.test270
-rw-r--r--mysql-test/suite/innodb_fts/t/fts_compatibility_win.test264
-rw-r--r--mysql-test/suite/innodb_fts/t/fulltext_plugin-master.opt1
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb_fts_index_table.test120
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb_fts_opt.test539
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb_fts_savepoint.test475
-rw-r--r--mysql-test/suite/innodb_fts/t/phrase.test39
-rw-r--r--mysql-test/suite/innodb_fts/t/subexpr.test58
-rw-r--r--mysql-test/suite/innodb_fts/t/sync.test170
-rw-r--r--mysql-test/suite/innodb_fts/t/sync_block.test125
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb-restart.test604
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb-wl5522-debug-zip.test758
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb-wl5522-zip.test544
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_16k.test735
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_4k.test455
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_8k.test482
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_cmp_per_index.test120
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_4k.test405
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_index_large_prefix_8k.test430
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_wl6347_comp_indx_stat.test1342
-rw-r--r--mysql-test/t/alter_table.test550
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
new file mode 100644
index 00000000000..4a6a5224338
--- /dev/null
+++ b/mysql-test/suite/innodb/t/portability_wl5980_linux.zip
Binary files differ
diff --git a/mysql-test/suite/innodb/t/portability_wl5980_windows.zip b/mysql-test/suite/innodb/t/portability_wl5980_windows.zip
new file mode 100644
index 00000000000..997962839c8
--- /dev/null
+++ b/mysql-test/suite/innodb/t/portability_wl5980_windows.zip
Binary files differ
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;