summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/innodb/t
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 13:39:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 13:39:13 +0000
commit86fbb58c3ac0865482819c10a3e81f2eea001c36 (patch)
tree28c9e526ea739c6f9b89e36115e1e2698bddf981 /mysql-test/suite/innodb/t
parentReleasing progress-linux version 1:10.11.6-2~progress7.99u1. (diff)
downloadmariadb-86fbb58c3ac0865482819c10a3e81f2eea001c36.tar.xz
mariadb-86fbb58c3ac0865482819c10a3e81f2eea001c36.zip
Merging upstream version 1:10.11.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--mysql-test/suite/innodb/t/add_foreign_key.test38
-rw-r--r--mysql-test/suite/innodb/t/alter_kill.test1
-rw-r--r--mysql-test/suite/innodb/t/alter_table.test15
-rw-r--r--mysql-test/suite/innodb/t/cascade_lock_wait.test45
-rw-r--r--mysql-test/suite/innodb/t/corrupted_during_recovery.test2
-rw-r--r--mysql-test/suite/innodb/t/dml_purge.test5
-rw-r--r--mysql-test/suite/innodb/t/doublewrite.test429
-rw-r--r--mysql-test/suite/innodb/t/doublewrite_debug.combinations7
-rw-r--r--mysql-test/suite/innodb/t/doublewrite_debug.test170
-rw-r--r--mysql-test/suite/innodb/t/fk_col_alter.test14
-rw-r--r--mysql-test/suite/innodb/t/fk_drop_alter.test35
-rw-r--r--mysql-test/suite/innodb/t/foreign-keys.test4
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test41
-rw-r--r--mysql-test/suite/innodb/t/full_crc32_import.test4
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty.test1
-rw-r--r--mysql-test/suite/innodb/t/import_update_stats.test80
-rw-r--r--mysql-test/suite/innodb/t/index_length.test23
-rw-r--r--mysql-test/suite/innodb/t/index_merge_threshold.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-16k.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb-32k.test14
-rw-r--r--mysql-test/suite/innodb/t/innodb-64k.test13
-rw-r--r--mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test117
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-tempfile.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter.test26
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online-fk.test45
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online.test33
-rw-r--r--mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test110
-rw-r--r--mysql-test/suite/innodb/t/innodb-read-view.test48
-rw-r--r--mysql-test/suite/innodb/t/innodb-system-table-view.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-table-online.test32
-rw-r--r--mysql-test/suite/innodb/t/innodb-truncate.test8
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5522-1.test21
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test47
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug12902967.test25
-rw-r--r--mysql-test/suite/innodb/t/innodb_force_recovery.test10
-rw-r--r--mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test169
-rw-r--r--mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test95
-rw-r--r--mysql-test/suite/innodb/t/innodb_information_schema_tables.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_information_schema_tables.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test14
-rw-r--r--mysql-test/suite/innodb/t/innodb_scrub.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt1
-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.opt1
-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.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test45
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test88
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_external_pages.test79
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_fetch.opt7
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_fetch.test15
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations4
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_flag_global.test91
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc13
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_persistent.test41
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt1
-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_ut_format_name.test17
-rw-r--r--mysql-test/suite/innodb/t/instant_alter.test4
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_bugs.test32
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_crash.test2
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_debug.test7
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_purge.test2
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_rollback.test2
-rw-r--r--mysql-test/suite/innodb/t/lock_move_wait_lock_race.test3
-rw-r--r--mysql-test/suite/innodb/t/log_file_name.test5
-rw-r--r--mysql-test/suite/innodb/t/mdev-14846.test2
-rw-r--r--mysql-test/suite/innodb/t/mem_pressure.test44
-rw-r--r--mysql-test/suite/innodb/t/no_pad.test46
-rw-r--r--mysql-test/suite/innodb/t/page_id_innochecksum.test2
-rw-r--r--mysql-test/suite/innodb/t/purge.test5
-rw-r--r--mysql-test/suite/innodb/t/purge_secondary.test7
-rw-r--r--mysql-test/suite/innodb/t/purge_thread_shutdown.test43
-rw-r--r--mysql-test/suite/innodb/t/read_only_recovery.test2
-rw-r--r--mysql-test/suite/innodb/t/records_in_range.test432
-rw-r--r--mysql-test/suite/innodb/t/row_format_redundant.opt2
-rw-r--r--mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test2
-rw-r--r--mysql-test/suite/innodb/t/scrub_debug.test2
-rw-r--r--mysql-test/suite/innodb/t/table_flags.opt1
-rw-r--r--mysql-test/suite/innodb/t/table_flags.test2
-rw-r--r--mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt1
-rw-r--r--mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test162
-rw-r--r--mysql-test/suite/innodb/t/tablespace_per_table_windows.opt1
-rw-r--r--mysql-test/suite/innodb/t/tablespace_per_table_windows.test77
-rw-r--r--mysql-test/suite/innodb/t/truncate_crash.test2
-rw-r--r--mysql-test/suite/innodb/t/truncate_foreign.test10
-rw-r--r--mysql-test/suite/innodb/t/trx_id_future.test2
-rw-r--r--mysql-test/suite/innodb/t/undo_log.test5
-rw-r--r--mysql-test/suite/innodb/t/undo_space_dblwr.opt1
92 files changed, 2854 insertions, 564 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 00000000..d0febfd6
--- /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/alter_kill.test b/mysql-test/suite/innodb/t/alter_kill.test
index 461e1f47..7d83e7e3 100644
--- a/mysql-test/suite/innodb/t/alter_kill.test
+++ b/mysql-test/suite/innodb/t/alter_kill.test
@@ -26,6 +26,7 @@ call mtr.add_suppression("Table .*bug16720368.* is corrupted");
-- echo #
SET GLOBAL innodb_file_per_table=1;
+SET GLOBAL innodb_stats_persistent=0;
CREATE TABLE bug16720368_1 (a INT PRIMARY KEY) ENGINE=InnoDB;
diff --git a/mysql-test/suite/innodb/t/alter_table.test b/mysql-test/suite/innodb/t/alter_table.test
index 67ada081..d293d3a4 100644
--- a/mysql-test/suite/innodb/t/alter_table.test
+++ b/mysql-test/suite/innodb/t/alter_table.test
@@ -121,9 +121,20 @@ CREATE TABLE t1 (c TIMESTAMP AUTO_INCREMENT UNIQUE) ENGINE=InnoDB;
CREATE TABLE t1 (c DATETIME AUTO_INCREMENT UNIQUE) ENGINE=InnoDB;
--echo #
---echo # End of 10.4 tests
+--echo # MDEV-31000 Assertion failed on ALTER TABLE...page_compressed=1
--echo #
+SET @save_file_per_table=@@GLOBAL.innodb_file_per_table;
+SET GLOBAL innodb_file_per_table=0;
+CREATE TABLE t (c INT PRIMARY KEY) ENGINE=INNODB;
+SET GLOBAL innodb_file_per_table=1;
+ALTER TABLE t page_compressed=1;
+SET GLOBAL innodb_file_per_table=@save_file_per_table;
+SELECT space>0 FROM information_schema.innodb_sys_tables WHERE name='test/t';
+DROP TABLE t;
+
+--echo # End of 10.4 tests
+
--echo #
--echo # MDEV-21748 ASAN use-after-poison in PageBulk::insertPage()
--echo #
@@ -141,3 +152,5 @@ CREATE TABLE t1 (id INT PRIMARY KEY, a YEAR, INDEX(id,a)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,NULL),(2,NULL);
UPDATE t1 SET a=0;
DROP TABLE t1;
+
+--echo # End of 10.5 tests
diff --git a/mysql-test/suite/innodb/t/cascade_lock_wait.test b/mysql-test/suite/innodb/t/cascade_lock_wait.test
new file mode 100644
index 00000000..4489c9ae
--- /dev/null
+++ b/mysql-test/suite/innodb/t/cascade_lock_wait.test
@@ -0,0 +1,45 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+create table t1 (f1 int primary key) engine=innodb;
+create table t2 (f1 int primary key,
+ constraint c1 foreign key (f1) references t1(f1)
+ on update cascade
+ on delete cascade) engine=innodb;
+create table t3 (f1 int primary key,
+ constraint c2 foreign key (f1) references t1(f1)
+ on update cascade
+ on delete cascade) engine=innodb;
+show create table t1;
+show create table t2;
+show create table t3;
+
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+
+insert into t2 values (1);
+insert into t2 values (2);
+insert into t2 values (3);
+
+insert into t3 values (1);
+insert into t3 values (2);
+insert into t3 values (3);
+
+select f1 from t1;
+select f1 from t2;
+select f1 from t3;
+
+set @save_dbug = @@debug_dbug;
+set debug_dbug = '+d,dml_cascade_only_once';
+set debug_dbug = '+d,row_upd_cascade_lock_wait_err';
+update t1 set f1 = 100 where f1 = 2;
+
+select f1 from t1;
+select f1 from t2;
+select f1 from t3;
+
+set debug_dbug = @save_dbug;
+drop table t2;
+drop table t3;
+drop table t1;
diff --git a/mysql-test/suite/innodb/t/corrupted_during_recovery.test b/mysql-test/suite/innodb/t/corrupted_during_recovery.test
index f383d9ab..1f410246 100644
--- a/mysql-test/suite/innodb/t/corrupted_during_recovery.test
+++ b/mysql-test/suite/innodb/t/corrupted_during_recovery.test
@@ -59,7 +59,7 @@ SELECT * FROM t1;
let $restart_parameters=--innodb_force_recovery=1;
--source include/restart_mysqld.inc
---error ER_TABLE_CORRUPT
+--error ER_NO_SUCH_TABLE_IN_ENGINE,ER_TABLE_CORRUPT
SELECT * FROM t1;
SELECT * FROM t2;
CHECK TABLE t2;
diff --git a/mysql-test/suite/innodb/t/dml_purge.test b/mysql-test/suite/innodb/t/dml_purge.test
index 463ae390..78c6c50a 100644
--- a/mysql-test/suite/innodb/t/dml_purge.test
+++ b/mysql-test/suite/innodb/t/dml_purge.test
@@ -1,5 +1,8 @@
--source include/innodb_page_size.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`;
@@ -76,3 +79,5 @@ EOF
UNLOCK TABLES;
SELECT * FROM t1;
DROP TABLE t1;
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test
index d8dac955..d7300990 100644
--- a/mysql-test/suite/innodb/t/doublewrite.test
+++ b/mysql-test/suite/innodb/t/doublewrite.test
@@ -1,17 +1,11 @@
+
--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 # MDEV-32242 innodb.doublewrite test case always is skipped
--echo #
--source include/innodb_page_size.inc
---source include/have_debug.inc
--source include/not_embedded.inc
-# This test is slow on buildbot.
---source include/big_test.inc
-# Slow shutdown and restart to make sure ibuf merge is finished
-SET GLOBAL innodb_fast_shutdown = 0;
--disable_query_log
call mtr.add_suppression("InnoDB: Data file .* uses page size .* but the innodb_page_size start-up parameter is");
call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS");
@@ -22,23 +16,16 @@ call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registra
call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile");
call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: ");
call mtr.add_suppression("InnoDB: Inconsistent tablespace ID in .*t1\\.ibd");
+call mtr.add_suppression("\\[Warning\\] Found 1 prepared XA transactions");
+call mtr.add_suppression("InnoDB: Header page consists of zero bytes in datafile:");
--enable_query_log
---source include/restart_mysqld.inc
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`;
let ALGO=`select @@innodb_checksum_algorithm`;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
-show variables like 'innodb_doublewrite';
-show variables like 'innodb_fil_make_page_dirty_debug';
-show variables like 'innodb_saved_page_number_debug';
-
-connect (stop_purge,localhost,root,,);
-START TRANSACTION WITH CONSISTENT SNAPSHOT;
-connection default;
-
-create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0;
+create table t1 (f1 int primary key, f2 blob) stats_persistent=0, engine=innodb;
start transaction;
insert into t1 values(1, repeat('#',12));
@@ -48,35 +35,24 @@ 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 into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
-begin;
-insert into t1 values (6, repeat('%', 12));
---echo # Ensure that dirty pages of table t1 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
+# Slow shutdown and restart to make sure ibuf merge is finished
+SET GLOBAL innodb_fast_shutdown = 0;
+let $shutdown_timeout=;
+--source include/restart_mysqld.inc
--source ../include/no_checkpoint_start.inc
+connect (dml,localhost,root,,);
+XA START 'x';
+insert into t1 values (6, repeat('%', @@innodb_page_size/2));
+XA END 'x';
+XA PREPARE 'x';
+disconnect dml;
+connection default;
---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 are flushed.
-set global innodb_buf_flush_list_now = 1;
+flush table t1 for export;
---let CLEANUP_IF_CHECKPOINT=drop table t1;
+let $restart_parameters=;
+--let CLEANUP_IF_CHECKPOINT=XA COMMIT 'x';drop table t1;
--source ../include/no_checkpoint_end.inc
-disconnect stop_purge;
-
---echo # Make the first page (page_no=0) of the user tablespace
---echo # full of zeroes.
---echo #
---echo # MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer.
perl;
use IO::Handle;
@@ -90,16 +66,15 @@ my $page_size = $ENV{INNODB_PAGE_SIZE};
my $page;
do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
open(FILE, "+<", $fname) or die;
+sysseek(FILE, ($page_size/2), 0);
+syswrite(FILE, chr(0) x ($page_size/2));
+sysseek(FILE, 3*$page_size, 0);
sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
-my $page1 = $page;
-substr($page1, 34, 4) = pack("N", 0);
-my $polynomial0 = 0x82f63b78; # CRC-32C
-my $ck0 = mycrc32(substr($page1, 0, ($page_size-4)), 0, $polynomial0);
-substr($page1, ($page_size - 4), 4) = pack("N", $ck0);
-sysseek(FILE, 0, 0)||die "Unable to seek $fname\n";
-die unless syswrite(FILE, $page1, $page_size) == $page_size;
+sysseek(FILE, 3*$page_size, 0)||die "Unable to seek $fname\n";
+syswrite(FILE, chr(0) x ($page_size/2));
close FILE;
+# Change the flag offset of page 0 in doublewrite buffer
open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n";
sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n";
sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n";
@@ -112,28 +87,23 @@ for (my $d = $d1; $d < $d2 + 64; $d++)
sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
next unless $_ eq $page;
sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n";
- # Write buggy MariaDB 10.1.x FSP_SPACE_FLAGS to the doublewrite buffer
- my($flags) = unpack "x[54]N", $_;
- my $badflags = ($flags & 0x3f);
- my $compression_level=6;
- $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16);
- $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE
-
+ # Write buggy FSP_SPACE_FLAGS to the doublewrite buffer for page
+ my $badflags = 0x0006FFFF;
substr ($_, 54, 4) = pack("N", $badflags);
if ($algo =~ /full_crc32/)
{
- my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial);
- substr($_, $page_size - 4, 4) = pack("N", $ck);
+ my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial);
+ substr($_, $page_size - 4, 4) = pack("N", $ck);
}
else
{
- # Replace the innodb_checksum_algorithm=crc32 checksum
- my $ck= pack("N",
- mycrc32(substr($_, 4, 22), 0, $polynomial) ^
- mycrc32(substr($_, 38, $page_size - 38 - 8), 0,
- $polynomial));
- substr ($_, 0, 4) = $ck;
- substr ($_, $page_size - 8, 4) = $ck;
+ # Replace the innodb_checksum_algorithm=crc32 checksum
+ my $ck= pack("N",
+ mycrc32(substr($_, 4, 22), 0, $polynomial) ^
+ mycrc32(substr($_, 38, $page_size - 38 - 8), 0,
+ $polynomial));
+ substr ($_, 0, 4) = $ck;
+ substr ($_, $page_size - 8, 4) = $ck;
}
syswrite(FILE, $_, $page_size)==$page_size||die;
close(FILE);
@@ -143,325 +113,42 @@ die "Did not find the page in the doublewrite buffer ($d1,$d2)\n";
EOF
--source include/start_mysqld.inc
-
-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 into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
---echo # Ensure that dirty pages of table t1 is flushed.
-flush tables t1 for export;
-unlock tables;
-
-set global innodb_log_checkpoint_now=1;
-
-begin;
-insert into t1 values (6, repeat('%', 12));
-
---source ../include/no_checkpoint_start.inc
-
---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 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/no_checkpoint_end.inc
-
---echo # Corrupt the first page (page_no=0) of the user tablespace.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
-my $page_size = $ENV{INNODB_PAGE_SIZE};
-open(FILE, "+<", $fname) or die;
-sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
-substr($page, 28, 4) = pack("N", 1000);
-sysseek(FILE, 0, 0)||die "Unable to seek $fname\n";
-die unless syswrite(FILE, $page, $page_size) == $page_size;
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-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 into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
---echo # Ensure that dirty pages of table t1 is flushed.
-flush tables t1 for export;
-unlock tables;
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---source ../include/no_checkpoint_start.inc
-
---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 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/no_checkpoint_end.inc
-
---echo # Make the 2nd page (page_no=1) of the tablespace all zeroes.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
+let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile;
+--source include/search_pattern_in_file.inc
+let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=[1-9][0-9]*, page number=3\];
+--source include/search_pattern_in_file.inc
+XA ROLLBACK 'x';
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 into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
---echo # Ensure that dirty pages of table t1 is flushed.
-flush tables t1 for export;
-unlock tables;
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
--source ../include/no_checkpoint_start.inc
+connect (dml,localhost,root,,);
+XA START 'x';
+insert into t1 values (6, repeat('%', @@innodb_page_size/2));
+XA END 'x';
+XA PREPARE 'x';
+disconnect dml;
+connection default;
---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 the dirty pages of table t1 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/no_checkpoint_end.inc
-
---echo # Corrupt the 2nd page (page_no=1) of the user tablespace.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-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.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are 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.
-# We do this after the transaction starts and all dirty pages have been flushed
-# already. So flushing of this specified dirty page will surely keep the
-# copy in doublewrite buffer, and no more writes to doublewrite buffer would
-# overwrite the copy. Thus, we can safely modify the original page when server
-# is down. So do the following testings.
-set global innodb_buf_flush_list_now = 1;
-
---source include/kill_mysqld.inc
-
---echo # Make the first page (page_no=0) of the system tablespace
---echo # all zeroes.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-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.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are 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;
-
---source include/kill_mysqld.inc
-
---echo # Corrupt the first page (page_no=0) of the system tablespace.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-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.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are 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 also flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/kill_mysqld.inc
-
---echo # Make the 2nd page (page_no=1) of the system tablespace
---echo # all zeroes.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-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.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are 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 also flushed.
-set global innodb_buf_flush_list_now = 1;
+flush table t1 for export;
---source include/kill_mysqld.inc
+let $restart_parameters=;
+--source ../include/no_checkpoint_end.inc
---echo # Make the 2nd page (page_no=1) of the system tablespace
---echo # all zeroes.
+# Zero out the first page in file and try to recover from dblwr
perl;
use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
+open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}test/t1.ibd") or die;
+syswrite(FILE, chr(0) x $ENV{INNODB_PAGE_SIZE});
close FILE;
EOF
--source include/start_mysqld.inc
-
-check table t1;
---let SEARCH_PATTERN= InnoDB: .*test.t1\\.ibd
+let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile;
--source include/search_pattern_in_file.inc
-
+XA ROLLBACK 'x';
+check table t1;
select f1, f2 from t1;
-
drop table t1;
---echo #
---echo # MDEV-12600 crash during install_db with innodb_page_size=32K
---echo # and ibdata1=3M
---echo #
-let bugdir= $MYSQLTEST_VARDIR/tmp/doublewrite;
---mkdir $bugdir
-
-let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES
-WHERE engine = 'innodb'
-AND support IN ('YES', 'DEFAULT', 'ENABLED');
-
---let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir
---let $ibd=$ibp --innodb-undo-tablespaces=0
---let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend
-
---let $restart_parameters= $ibp
---source include/restart_mysqld.inc
-eval $check_no_innodb;
---let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot create doublewrite buffer
---source include/search_pattern_in_file.inc
---let $restart_parameters=
---source include/restart_mysqld.inc
-
---remove_file $bugdir/ibdata1
---remove_file $bugdir/ibdata2
---remove_file $bugdir/ib_logfile0
---rmdir $bugdir
+--echo # End of 10.5 tests
diff --git a/mysql-test/suite/innodb/t/doublewrite_debug.combinations b/mysql-test/suite/innodb/t/doublewrite_debug.combinations
new file mode 100644
index 00000000..4f52013f
--- /dev/null
+++ b/mysql-test/suite/innodb/t/doublewrite_debug.combinations
@@ -0,0 +1,7 @@
+[strict_crc32]
+--innodb-checksum-algorithm=strict_crc32
+--innodb-use-atomic-writes=0
+
+[strict_full_crc32]
+--innodb-checksum-algorithm=strict_full_crc32
+--innodb-use-atomic-writes=0
diff --git a/mysql-test/suite/innodb/t/doublewrite_debug.test b/mysql-test/suite/innodb/t/doublewrite_debug.test
new file mode 100644
index 00000000..ab7fd8eb
--- /dev/null
+++ b/mysql-test/suite/innodb/t/doublewrite_debug.test
@@ -0,0 +1,170 @@
+--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/innodb_page_size.inc
+--source include/have_debug.inc
+--source include/not_embedded.inc
+--disable_query_log
+call mtr.add_suppression("InnoDB: Data file .* uses page size .* but the innodb_page_size start-up parameter is");
+call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS");
+call mtr.add_suppression("InnoDB: New log files created");
+call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\.");
+call mtr.add_suppression("InnoDB: Database creation was aborted");
+call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)");
+call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile");
+call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: ");
+call mtr.add_suppression("InnoDB: Inconsistent tablespace ID in .*t1\\.ibd");
+call mtr.add_suppression("InnoDB: Header page consists of zero bytes in datafile:");
+--enable_query_log
+
+let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
+let MYSQLD_DATADIR=`select @@datadir`;
+let ALGO=`select @@innodb_checksum_algorithm`;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+
+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 stats_persistent=0;
+
+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 # Test Begin: Test if recovery works if 1st page and 2nd page
+--echo # of system tablespace is full of zeroes.
+
+# Slow shutdown and restart to make sure ibuf merge is finished
+SET GLOBAL innodb_fast_shutdown = 0;
+let $shutdown_timeout=;
+let $restart_parameters="--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0";
+--source include/restart_mysqld.inc
+--source ../include/no_checkpoint_start.inc
+begin;
+insert into t1 values (6, repeat('%', 400));
+
+--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 # 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;
+
+set global innodb_buf_flush_list_now = 1;
+
+--let CLEANUP_IF_CHECKPOINT=drop table t1, unexpected_checkpoint;
+--source ../include/no_checkpoint_end.inc
+
+--echo # Make the 1st page (page_no=0) and 2nd page (page_no=1)
+--echo # of the system tablespace all zeroes.
+perl;
+use IO::Handle;
+my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
+open(FILE, "+<", $fname) or die;
+FILE->autoflush(1);
+binmode FILE;
+print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
+seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
+print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
+close FILE;
+EOF
+
+let $restart_parameters=;
+--source include/start_mysqld.inc
+
+let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile;
+--source include/search_pattern_in_file.inc
+
+let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=0, page number=1\];
+--source include/search_pattern_in_file.inc
+
+check table t1;
+select f1, f2 from t1;
+
+--echo # Test End
+--echo # ---------------------------------------------------------------
+--echo # Test Begin: Test if recovery works if 1st page of
+--echo # system tablespace is corrupted and 2nd page as corrupted.
+
+let $restart_parameters="--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0";
+--source include/restart_mysqld.inc
+--source ../include/no_checkpoint_start.inc
+begin;
+insert into t1 values (6, repeat('%', 400));
+
+--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 # 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;
+
+set global innodb_buf_flush_list_now = 1;
+
+--source ../include/no_checkpoint_end.inc
+
+--echo # Corrupt the 1st page (page_no=0) and 2nd page of the system tablespace.
+perl;
+use IO::Handle;
+my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
+open(FILE, "+<", $fname) or die;
+FILE->autoflush(1);
+binmode FILE;
+print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
+seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
+print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
+close FILE;
+EOF
+
+let $restart_parameters=;
+--source include/start_mysqld.inc
+
+let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile;
+--source include/search_pattern_in_file.inc
+
+let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=0, page number=1\];
+--source include/search_pattern_in_file.inc
+
+check table t1;
+select f1, f2 from t1;
+drop table t1;
+let $shutdown_timeout=;
+--echo # Test End
+--echo # ---------------------------------------------------------------
+--echo #
+--echo # MDEV-12600 crash during install_db with innodb_page_size=32K
+--echo # and ibdata1=3M
+--echo #
+let bugdir= $MYSQLTEST_VARDIR/tmp/doublewrite;
+--mkdir $bugdir
+
+let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+
+--let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir
+--let $ibp=$ibp --innodb-undo-tablespaces=0
+--let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend
+
+--let $restart_parameters= $ibp
+--source include/restart_mysqld.inc
+eval $check_no_innodb;
+--let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot create doublewrite buffer
+--source include/search_pattern_in_file.inc
+--let $restart_parameters=
+--source include/restart_mysqld.inc
+
+--remove_file $bugdir/ibdata1
+--remove_file $bugdir/ibdata2
+--remove_file $bugdir/ib_logfile0
+--rmdir $bugdir
diff --git a/mysql-test/suite/innodb/t/fk_col_alter.test b/mysql-test/suite/innodb/t/fk_col_alter.test
index 2ed10a95..21fd470e 100644
--- a/mysql-test/suite/innodb/t/fk_col_alter.test
+++ b/mysql-test/suite/innodb/t/fk_col_alter.test
@@ -149,4 +149,18 @@ ALTER TABLE t2 DROP INDEX idx;
ALTER TABLE t2 MODIFY f2 VARCHAR(1023);
SET SESSION FOREIGN_KEY_CHECKS = ON;
DROP TABLE t2, t1;
+
+--echo #
+--echo # MDEV-32638 MariaDB crashes with foreign_key_checks=0
+--echo # when changing a column and adding a foreign
+--echo # key at the same time
+--echo #
+CREATE TABLE t1(f1 VARCHAR(2) NOT NULL, PRIMARY KEY(f1))ENGINE=InnoDB;
+CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY,
+ f2 VARCHAR(10) NOT NULL DEFAULT '')ENGINE=InnoDB;
+SET SESSION FOREIGN_KEY_CHECKS = OFF;
+ALTER TABLE t2 CHANGE COLUMN f2 f3 VARCHAR(20) NOT NULL,
+ ADD CONSTRAINT t2_fk FOREIGN KEY(f3) REFERENCES t1(f1);
+DROP TABLE t2, t1;
+SET SESSION FOREIGN_KEY_CHECKS = ON;
--echo # End of 10.4 tests
diff --git a/mysql-test/suite/innodb/t/fk_drop_alter.test b/mysql-test/suite/innodb/t/fk_drop_alter.test
new file mode 100644
index 00000000..c79eb873
--- /dev/null
+++ b/mysql-test/suite/innodb/t/fk_drop_alter.test
@@ -0,0 +1,35 @@
+--source include/have_innodb.inc
+--echo #
+--echo # MDEV-22230 : Unexpected ER_ERROR_ON_RENAME upon DROP
+--echo # non-existing FOREIGN KEY
+--echo #
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=COPY;
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=INPLACE;
+# Cleanup
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, FOREIGN KEY fk_id (a) REFERENCES t1(a))ENGINE=InnoDB;
+CREATE TABLE t3 (a INT, FOREIGN KEY fk_1 (a) REFERENCES t1(a))ENGINE=InnoDB;
+ALTER TABLE t3 DROP FOREIGN KEY IF EXISTS fk_id;
+DROP TABLE t3, t2;
+ALTER TABLE t1 MODIFY COLUMN a VARCHAR(2), DROP FOREIGN KEY IF EXISTS x;
+DROP TABLE t1;
+
+CREATE DATABASE best;
+CREATE TABLE best.t1(f1 INT, KEY(f1))ENGINE=InnoDB;
+CREATE TABLE best.t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB;
+
+CREATE TABLE t1(f1 INT, KEY(f1))ENGINE=InnoDB;
+CREATE TABLE t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB;
+ALTER TABLE t2 DROP FOREIGN KEY foo;
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t2 DROP FOREIGN KEY foo;
+ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS foo;
+SHOW CREATE TABLE best.t2;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
+DROP TABLE best.t2, best.t1, t2, t1;
+DROP DATABASE best;
diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test
index b93f82c9..aeff7009 100644
--- a/mysql-test/suite/innodb/t/foreign-keys.test
+++ b/mysql-test/suite/innodb/t/foreign-keys.test
@@ -268,3 +268,7 @@ SET FOREIGN_KEY_CHECKS=1;
INSERT INTO t2 VALUES('G', 3);
DROP TABLE t2, t1;
SET FOREIGN_KEY_CHECKS=DEFAULT;
+
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE t1(a SERIAL) ENGINE=InnoDB ROW_FORMAT=COMPRESSED PAGE_COMPRESSED=1;
+SHOW WARNINGS;
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index 06da1b6f..0db3a7ca 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -2,6 +2,8 @@
--source include/count_sessions.inc
--source include/default_charset.inc
+SET GLOBAL innodb_stats_persistent = 0;
+
--echo #
--echo # Bug #19027905 ASSERT RET.SECOND DICT_CREATE_FOREIGN_CONSTRAINTS_LOW
--echo # DICT_CREATE_FOREIGN_CONSTR
@@ -126,6 +128,9 @@ FLUSH TABLES;
--let $shutdown_timeout=
disconnect incomplete;
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
INSERT INTO child SET a=0;
--error ER_NO_REFERENCED_ROW_2
INSERT INTO child SET a=1;
@@ -728,7 +733,9 @@ SELECT a FROM t1 FORCE INDEX(a);
# the "goto rollback_to_savept" in row_mysql_handle_errors() is reverted.
SELECT * FROM t1;
# Allow purge to continue by closing the read view.
-disconnect con1;
+connection con1;
+COMMIT;
+connection default;
# Wait for purge. With the fix reverted, the server would crash here.
--source include/wait_all_purged.inc
@@ -949,9 +956,37 @@ ALTER TABLE t1 MODIFY id INT unsigned AUTO_INCREMENT;
DROP TABLE t1,t2;
--echo #
---echo # End of 10.4 tests
+--echo # MDEV-31441 BLOB corruption on UPDATE of PRIMARY KEY with FOREIGN KEY
--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT) ENGINE=InnoDB;
+CREATE TABLE t2 (pk INT PRIMARY KEY, FOREIGN KEY (pk) REFERENCES t1(pk))
+ENGINE=InnoDB;
+
+SET @blob = REPEAT('A', @@innodb_page_size / 2);
+INSERT INTO t1 SET pk=1, t=@blob;
+INSERT INTO t2 SET pk=1;
+--connection con1
+BEGIN;
+DELETE FROM t2;
+--connection default
+# The following will be blocked by a FOREIGN KEY check on pk=1 in t2.
+--send
+UPDATE t1 SET pk=12;
+--connection con1
+let $wait_condition=
+SELECT count(*) > 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state='Updating';
+--source include/wait_condition.inc
+COMMIT;
+--disconnect con1
+--connection default
+--reap
+UPDATE t1 SET pk=1;
+SELECT pk,t=@blob FROM t1;
+DROP TABLE t2, t1;
+
+--echo # End of 10.4 tests
+
--echo #
--echo # MDEV-20729 Fix REFERENCES constraint in column definition
--echo #
@@ -1132,4 +1167,6 @@ DROP TABLE binaries, collections;
--echo # End of 10.6 tests
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
+
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/full_crc32_import.test b/mysql-test/suite/innodb/t/full_crc32_import.test
index b79fd954..0eb31f8d 100644
--- a/mysql-test/suite/innodb/t/full_crc32_import.test
+++ b/mysql-test/suite/innodb/t/full_crc32_import.test
@@ -2,6 +2,9 @@
# This test is slow on buildbot.
--source include/big_test.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
FLUSH TABLES;
let $MYSQLD_TMPDIR = `SELECT @@tmpdir`;
@@ -222,3 +225,4 @@ SELECT * FROM t1;
DROP TABLE t1;
SET GLOBAL innodb_compression_algorithm=@save_algo;
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test
index 9362f8da..b1f3c270 100644
--- a/mysql-test/suite/innodb/t/ibuf_not_empty.test
+++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test
@@ -74,6 +74,7 @@ EOF
--replace_regex /contains \d+ entries/contains 990 entries/
check table t1;
+SET GLOBAL innodb_buf_flush_list_now=ON;
--source include/shutdown_mysqld.inc
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 00000000..e1b1ae5d
--- /dev/null
+++ b/mysql-test/suite/innodb/t/import_update_stats.test
@@ -0,0 +1,80 @@
+#
+# 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 "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
+ib_backup_tablespaces("test", "t1");
+EOF
+
+UNLOCK TABLES;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ col_1 CHAR (255),
+ col_2 VARCHAR (255)
+) ENGINE = InnoDB STATS_PERSISTENT=1;
+
+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;
+
+SET STATEMENT use_stat_tables=never FOR
+ANALYZE TABLE t1;
+SHOW INDEXES FROM t1;
+
+ALTER TABLE t1 DISCARD TABLESPACE;
+
+perl;
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
+ib_discard_tablespaces("test", "t1");
+ib_restore_tablespaces("test", "t1");
+EOF
+
+ALTER TABLE t1 IMPORT TABLESPACE;
+
+SHOW INDEXES FROM t1;
+
+SET STATEMENT use_stat_tables=never FOR
+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/index_length.test b/mysql-test/suite/innodb/t/index_length.test
new file mode 100644
index 00000000..bf4940d4
--- /dev/null
+++ b/mysql-test/suite/innodb/t/index_length.test
@@ -0,0 +1,23 @@
+--source include/have_innodb.inc
+
+--connect (stop_purge,localhost,root)
+# Prevent the purge of history from acquiring a table handle.
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+--connection default
+
+CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(1024))
+ENGINE=InnoDB STATS_PERSISTENT=1;
+INSERT INTO t1 VALUES (1,REPEAT('b',1024));
+
+SELECT index_length FROM information_schema.tables
+WHERE table_schema = 'test' AND table_name = 't1';
+ALTER TABLE t1 ADD INDEX b (b(800));
+SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables
+WHERE table_schema = 'test' AND table_name = 't1';
+ALTER TABLE t1 ADD INDEX ba (b(800),a);
+SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables
+WHERE table_schema = 'test' AND table_name = 't1';
+disconnect stop_purge;
+DROP TABLE t1;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/suite/innodb/t/index_merge_threshold.test b/mysql-test/suite/innodb/t/index_merge_threshold.test
index a60ecf51..cb8e117d 100644
--- a/mysql-test/suite/innodb/t/index_merge_threshold.test
+++ b/mysql-test/suite/innodb/t/index_merge_threshold.test
@@ -13,6 +13,9 @@
--source include/have_innodb_16k.inc
--source include/have_partition.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
# Check index merge threshold by create index on all datatypes
CREATE TABLE tab(a BIGINT PRIMARY KEY,c1 TINYTEXT,c2 TEXT,c3 MEDIUMTEXT,
@@ -186,3 +189,5 @@ CREATE INDEX index1 ON tab1(b(750)) COMMENT 'MERGE_THRESHOLD=45';
--source suite/innodb/include/innodb_merge_threshold_secondary.inc
DROP TABLE tab1;
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
diff --git a/mysql-test/suite/innodb/t/innodb-16k.test b/mysql-test/suite/innodb/t/innodb-16k.test
index 8bec6254..fd024047 100644
--- a/mysql-test/suite/innodb/t/innodb-16k.test
+++ b/mysql-test/suite/innodb/t/innodb-16k.test
@@ -3,6 +3,9 @@
--source include/have_innodb.inc
--source include/have_innodb_16k.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
call mtr.add_suppression("InnoDB: Cannot add field .* in table");
let $MYSQLD_DATADIR= `select @@datadir`;
@@ -457,6 +460,7 @@ DROP TABLE t1;
--source include/wait_all_purged.inc
SET GLOBAL innodb_compression_level=@save_level;
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge;
DROP TABLE tlong;
diff --git a/mysql-test/suite/innodb/t/innodb-32k.test b/mysql-test/suite/innodb/t/innodb-32k.test
index 496977c1..a5fd78fd 100644
--- a/mysql-test/suite/innodb/t/innodb-32k.test
+++ b/mysql-test/suite/innodb/t/innodb-32k.test
@@ -3,10 +3,24 @@
--source include/have_innodb.inc
--source include/have_innodb_32k.inc
+SET GLOBAL innodb_stats_persistent = 0;
call mtr.add_suppression("Innodb: Cannot add field.*row size is");
let $MYSQLD_DATADIR= `select @@datadir`;
+SET SESSION innodb_strict_mode=ON;
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4;
+SET SESSION innodb_strict_mode=OFF;
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+SHOW WARNINGS;
+DROP TABLE t1;
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4;
+SHOW WARNINGS;
+DROP TABLE t1;
+
--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';
diff --git a/mysql-test/suite/innodb/t/innodb-64k.test b/mysql-test/suite/innodb/t/innodb-64k.test
index 972ba6bb..d89370ff 100644
--- a/mysql-test/suite/innodb/t/innodb-64k.test
+++ b/mysql-test/suite/innodb/t/innodb-64k.test
@@ -8,6 +8,19 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the
let $MYSQLD_DATADIR= `select @@datadir`;
+SET SESSION innodb_strict_mode=ON;
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4;
+SET SESSION innodb_strict_mode=OFF;
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
+SHOW WARNINGS;
+DROP TABLE t1;
+CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4;
+SHOW WARNINGS;
+DROP TABLE t1;
+
--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';
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 00000000..3376367b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test
@@ -0,0 +1,117 @@
+# DEBUG_SYNC must be compiled in.
+--source include/have_debug_sync.inc
+--source include/have_debug.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_start 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_start 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';
+SET DEBUG_SYNC= 'RESET';
+
+# 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';
+disconnect con6;
+disconnect con2;
+disconnect con3;
+disconnect con5;
+
+connection con1;
+reap;
+disconnect con1;
+
+connection con4;
+reap;
+disconnect con4;
+
+connection default;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
index 0ae116f5..2534f03d 100644
--- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
+++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test
@@ -65,8 +65,11 @@ set DEBUG_SYNC="now WAIT_FOR default_signal";
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
disconnect con1;
---replace_column 7 #
+# This may occasionally display records for a corrupted index(f2).
+# The original bug was about a crash during the execution of SHOW KEYS.
+--disable_result_log
SHOW KEYS FROM t1;
+--enable_result_log
DROP TABLE t1;
remove_files_wildcard $datadir/test #sql-*.frm;
diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test
index 78550763..5b121c70 100644
--- a/mysql-test/suite/innodb/t/innodb-alter.test
+++ b/mysql-test/suite/innodb/t/innodb-alter.test
@@ -701,6 +701,32 @@ ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE;
SET @@SQL_MODE= @OLD_SQL_MODE;
DROP TABLE t1;
+--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');
+
+let $source_db = test;
+let $dest_db = test;
+
+--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;
+
#
# End of 10.2 tests
#
diff --git a/mysql-test/suite/innodb/t/innodb-index-online-fk.test b/mysql-test/suite/innodb/t/innodb-index-online-fk.test
index 5423516c..64cea29e 100644
--- a/mysql-test/suite/innodb/t/innodb-index-online-fk.test
+++ b/mysql-test/suite/innodb/t/innodb-index-online-fk.test
@@ -482,3 +482,48 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS;
DROP TABLE t2;
DROP TABLE t3;
+
+--echo # Bug #17449901 TABLE DISAPPEARS WHEN ALTERING
+--echo # WITH FOREIGN KEY CHECKS OFF
+
+# Drop index via inplace algorithm
+create table t1(f1 int,primary key(f1))engine=innodb;
+create table t2(f2 int,f3 int,key t(f2,f3),foreign key(f2) references t1(f1))engine=innodb;
+SET foreign_key_checks=0;
+drop index t on t2;
+drop table t2;
+drop table t1;
+
+# Drop index using alter statement via inplace
+create table t1(f1 int ,primary key(f1))engine=innodb;
+create table t2(f2 int,f3 int, key t(f2),foreign key(f2) references t1(f1))engine=innodb;
+SET foreign_key_checks = 0;
+alter table t2 drop key t,algorithm=inplace;
+show create table t2;
+drop table t2;
+drop table t1;
+
+create table t1(f1 int ,primary key(f1))engine=innodb;
+create table t2(f2 int,f3 int, key t(f2),key t1(f2,f3),
+foreign key(f2) references t1(f1))engine=innodb;
+SET foreign_key_checks = 0;
+alter table t2 drop key t,algorithm=inplace;
+show create table t2;
+drop table t2;
+drop table t1;
+
+--echo #
+--echo # MDEV-29092 FOREIGN_KEY_CHECKS does not prevent non-copy
+--echo # alter from creating invalid FK structures
+--echo #
+CREATE TABLE t1(f1 INT, KEY(f1),
+ FOREIGN KEY(f1) references t1(f1))ENGINE=InnoDB;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1(f1 INT, KEY(f1),
+ FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=InnoDB;
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 DROP KEY f1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test
index f8eb8957..96ee3149 100644
--- a/mysql-test/suite/innodb/t/innodb-index-online.test
+++ b/mysql-test/suite/innodb/t/innodb-index-online.test
@@ -4,6 +4,10 @@
--source include/have_debug_sync.inc
--source include/no_valgrind_without_big.inc
+SET GLOBAL innodb_monitor_reset_all=all;
+--disable_warnings
+SET GLOBAL innodb_monitor_reset_all=default;
+--enable_warnings
let $innodb_metrics_select=
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
@@ -158,6 +162,7 @@ let $ID= `SELECT @id := CONNECTION_ID()`;
--error ER_QUERY_INTERRUPTED
KILL QUERY @id;
+SET GLOBAL innodb_max_purge_lag_wait=0;
SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2d_created WAIT_FOR kill_done';
--send
CREATE INDEX c2d ON t1(c2);
@@ -209,13 +214,13 @@ SHOW CREATE TABLE t1;
connection default;
SET @merge_encrypt_0=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_0=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_0=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
connection con1;
@@ -254,13 +259,13 @@ INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
ON si.index_id = sf.index_id WHERE si.name = '?c2e';
SET @merge_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
SELECT
@@ -297,16 +302,16 @@ ALTER TABLE t1 COMMENT 'testing if c2e will be dropped';
eval $innodb_metrics_select;
SET @merge_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
SET @rowlog_decrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
connection con1;
@@ -343,16 +348,16 @@ eval $innodb_metrics_select;
connection default;
SET @merge_encrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
SET @rowlog_decrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
SELECT
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 00000000..31bf8a73
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test
@@ -0,0 +1,110 @@
+--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
+connect purge_control,localhost,root;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
+
+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,,)
+
+# 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;
+}
+--connect(con2,localhost,root,,)
+
+SET debug_sync = 'now WAIT_FOR con1_locks_done';
+
+SET debug_sync = 'lock_wait_start SIGNAL con2_blocked
+WAIT_FOR con2_go';
+SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock
+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';
+
+connection purge_control;
+COMMIT;
+disconnect purge_control;
+connection default;
+
+# Wait for purge to delete the delete-marked record
+--source ../../innodb/include/wait_all_purged.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';
+
+--connection con1
+--reap
+--disconnect con1
+--connection default
+SET debug_sync = 'now SIGNAL con2_finish';
+
+--connection con2
+--error 0,ER_LOCK_WAIT_TIMEOUT
+--reap
+--disconnect con2
+
+--connection default
+SET DEBUG_SYNC= 'RESET';
+
+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;
+
+--inc $i
+}
diff --git a/mysql-test/suite/innodb/t/innodb-read-view.test b/mysql-test/suite/innodb/t/innodb-read-view.test
index 425cbeb0..21c79cf6 100644
--- a/mysql-test/suite/innodb/t/innodb-read-view.test
+++ b/mysql-test/suite/innodb/t/innodb-read-view.test
@@ -1,7 +1,6 @@
# DEBUG_SYNC must be compiled in.
--source include/have_debug_sync.inc
--source include/have_debug.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.
@@ -27,22 +26,16 @@ 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'
+--connect (con2,localhost,root,,)
SET AUTOCOMMIT=0;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
@@ -50,48 +43,36 @@ SELECT * FROM t1;
SELECT * FROM t2;
connection con1;
---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_search_for_mysql_before_return 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_search_for_mysql_before_return 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.
@@ -105,17 +86,12 @@ disconnect con2;
# 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;
@@ -124,7 +100,6 @@ SELECT * FROM t2;
COMMIT;
connection con2;
---echo 'T3'
SET AUTOCOMMIT=0;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
@@ -132,42 +107,30 @@ 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;
+disconnect con2;
connection default;
-disconnect con1;
-disconnect con2;
DROP TABLE t1;
DROP TABLE t2;
@@ -176,8 +139,7 @@ DROP TABLE t2;
--echo # Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION
--echo #
---connect (con1,localhost,root,,)
-
+connection con1;
CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB;
INSERT INTO t1 values (1, 0), (2, 0);
SELECT * FROM t1 ORDER BY col1;
@@ -200,9 +162,7 @@ reap;
disconnect con1;
connection default;
-
+SET DEBUG_SYNC= 'RESET';
DROP TABLE t1;
-# Clean up resources used in this test case.
-SET DEBUG_SYNC= 'RESET';
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/innodb-system-table-view.test b/mysql-test/suite/innodb/t/innodb-system-table-view.test
index 659c42f0..663b76a1 100644
--- a/mysql-test/suite/innodb/t/innodb-system-table-view.test
+++ b/mysql-test/suite/innodb/t/innodb-system-table-view.test
@@ -4,6 +4,9 @@
--source include/innodb_page_size_small.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
LET $MYSQLD_DATADIR = `select @@datadir`;
LET $INNODB_PAGE_SIZE = `select @@innodb_page_size`;
@@ -144,3 +147,5 @@ DROP TABLE parent;
--echo # temporary tablespace information
--echo #
SELECT SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE name like 'innodb_temporary';
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test
index ec4f4ef1..0612866a 100644
--- a/mysql-test/suite/innodb/t/innodb-table-online.test
+++ b/mysql-test/suite/innodb/t/innodb-table-online.test
@@ -4,6 +4,10 @@
--source include/have_debug_sync.inc
--source include/have_sequence.inc
+SET GLOBAL innodb_monitor_reset_all=all;
+--disable_warnings
+SET GLOBAL innodb_monitor_reset_all=default;
+--enable_warnings
let $innodb_metrics_select=
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
@@ -171,13 +175,13 @@ EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3;
ANALYZE TABLE t1;
SET @merge_encrypt_0=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_0=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_0=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
connection con1;
@@ -215,13 +219,13 @@ while ($c)
eval $innodb_metrics_select;
SET @merge_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
SELECT
@@ -243,16 +247,16 @@ reap;
eval $innodb_metrics_select;
SET @merge_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
SET @rowlog_decrypt_1=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
SET GLOBAL innodb_max_purge_lag_wait=0;
@@ -287,16 +291,16 @@ SELECT COUNT(c22f) FROM t1;
CHECK TABLE t1;
SET @merge_encrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
SET @merge_decrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
SET @rowlog_encrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
SET @rowlog_decrypt_2=
-(SELECT variable_value FROM information_schema.global_status
+(SELECT CAST(variable_value AS INTEGER) FROM information_schema.global_status
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
SELECT
diff --git a/mysql-test/suite/innodb/t/innodb-truncate.test b/mysql-test/suite/innodb/t/innodb-truncate.test
index 4d39fcae..cbd6139f 100644
--- a/mysql-test/suite/innodb/t/innodb-truncate.test
+++ b/mysql-test/suite/innodb/t/innodb-truncate.test
@@ -85,13 +85,11 @@ SET FOREIGN_KEY_CHECKS= ON;
CREATE TABLE t2 (f2 INT, FOREIGN KEY(f2) REFERENCES t1 (f2)) ENGINE=InnoDB;
--error ER_CANT_CREATE_TABLE
CREATE TABLE t3 (a INT) ENGINE=InnoDB;
---replace_result $datadir ./
---error ER_ERROR_ON_RENAME
ALTER TABLE t1 RENAME TO t3;
-ALTER TABLE t1 FORCE;
+ALTER TABLE t3 FORCE;
--error ER_TRUNCATE_ILLEGAL_FK
-TRUNCATE TABLE t1;
-DROP TABLE t2, t1;
+TRUNCATE TABLE t3;
+DROP TABLE t2, t3;
--echo #
--echo # MDEV-24861 Assertion `trx->rsegs.m_redo.rseg' failed
diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-1.test b/mysql-test/suite/innodb/t/innodb-wl5522-1.test
index dbd58835..9e5d606b 100644
--- a/mysql-test/suite/innodb/t/innodb-wl5522-1.test
+++ b/mysql-test/suite/innodb/t/innodb-wl5522-1.test
@@ -960,6 +960,25 @@ ALTER TABLE t1 IMPORT TABLESPACE;
DROP TABLE t1;
--remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd
---echo #
--echo # End of 10.3 tests
+
--echo #
+--echo # MDEV-29972 crash after "Unsupported meta-data version number"
+--echo #
+
+call mtr.add_suppression("Index for table 't2' is corrupt");
+
+CREATE TABLE t2 (i INT PRIMARY KEY) ENGINE=InnoDB;
+ALTER TABLE t2 DISCARD TABLESPACE;
+--copy_file std_data/mysql80/t2.cfg $MYSQLD_DATADIR/test/t2.cfg
+--copy_file std_data/mysql80/t2.ibd $MYSQLD_DATADIR/test/t2.ibd
+--error ER_NOT_SUPPORTED_YET
+ALTER TABLE t2 IMPORT TABLESPACE;
+--remove_file $MYSQLD_DATADIR/test/t2.cfg
+--error ER_NOT_KEYFILE
+ALTER TABLE t2 IMPORT TABLESPACE;
+--error ER_TABLESPACE_DISCARDED
+SELECT * FROM t2;
+DROP TABLE t2;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test
index 38109116..b393ca70 100644
--- a/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test
@@ -35,49 +35,44 @@ SET GLOBAL innodb_buffer_pool_dump_pct=100;
# - The granularity of the timestamp is one second.
# - There could have been some dump caused by some previous test
# just a few milliseconds before.
-# In order to avoid conflict with previous tests, read the current value
-# of INNODB_BUFFER_POOL_DUMP_STATUS
-# and confirm that the timestamp is different after the dump
#***********************************************************
-# Read the current value to compare with the new value.
-SELECT variable_value INTO @IBPDS
-FROM information_schema.global_status
-WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS';
-SET GLOBAL innodb_buffer_pool_dump_now=ON;
-
-# Sleep one second in order to ensure that the time stamp is
-# different at next dump
---sleep 1
+--error 0,1
+--remove_file $MYSQLD_DATADIR/ib_buffer_pool
+SET GLOBAL innodb_buffer_pool_dump_now=ON;
+perl;
+my $f="$ENV{MYSQLD_DATADIR}/ib_buffer_pool";
+my $count=300;
+until (-e $f)
+{
+ select(undef, undef, undef, .1);
+ die "File $f was not created\n" if (0 > --$count);
+}
+EOF
let $wait_condition = SELECT count(*) = 1
FROM information_schema.global_status
WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS'
-AND variable_value != @IBPDS
AND variable_value like 'Buffer pool(s) dump completed at%';
--source include/wait_condition.inc
--move_file $MYSQLD_DATADIR/ib_buffer_pool $MYSQLD_DATADIR/ib_buffer_pool100
SET GLOBAL innodb_buffer_pool_dump_pct=1;
-SELECT @@global.innodb_buffer_pool_dump_pct;
-
-# Read the current value to compare with the new value.
---disable_warnings
-SELECT variable_value INTO @IBPDS
-FROM information_schema.global_status
-WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS';
---enable_warnings
-
SET GLOBAL innodb_buffer_pool_dump_now=ON;
-# Sleep one second in order to ensure that the time stamp is
-# different at next dump
---sleep 1
+perl;
+my $f="$ENV{MYSQLD_DATADIR}/ib_buffer_pool";
+my $count=300;
+until (-e $f)
+{
+ select(undef, undef, undef, .1);
+ die "File $f was not created\n" if (0 > --$count);
+}
+EOF
let $wait_condition = SELECT count(*) = 1
FROM information_schema.global_status
WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS'
-AND variable_value != @IBPDS
AND variable_value like 'Buffer pool(s) dump completed at%';
--source include/wait_condition.inc
diff --git a/mysql-test/suite/innodb/t/innodb_bug12902967.test b/mysql-test/suite/innodb/t/innodb_bug12902967.test
deleted file mode 100644
index 5bd32cdf..00000000
--- a/mysql-test/suite/innodb/t/innodb_bug12902967.test
+++ /dev/null
@@ -1,25 +0,0 @@
-# Bug 12902967: Creating self referencing fk on same index unhandled,
-# confusing error
-#
-# Creating a self referencing foreign key on the same
-# column/index is an unhandled exception, it should throw a sensible
-# error but instead implies that your data dictionary may now be out
-# of sync:
-
---source include/have_innodb.inc
---source include/not_embedded.inc
-
-call mtr.add_suppression("In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition.");
-
-let error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err;
---source include/restart_mysqld.inc
-
-create table t1 (f1 integer primary key) engine innodb;
-
-# The below statement should produce error message in error log.
-# This error message should mention problem with foreign keys
-# rather than with data dictionary.
---replace_regex /'\.\/test\/#sql-alter-[0-9a-f_\-]*'/'#sql-alter'/
---error ER_ERROR_ON_RENAME
-alter table t1 add constraint c1 foreign key (f1) references t1(f1);
-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
index 2368af76..30364c06 100644
--- a/mysql-test/suite/innodb/t/innodb_force_recovery.test
+++ b/mysql-test/suite/innodb/t/innodb_force_recovery.test
@@ -21,8 +21,18 @@ SET GLOBAL innodb_fast_shutdown = 0;
--source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
+SELECT CAST(variable_value AS INTEGER) INTO @read1
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS
+WHERE VARIABLE_NAME='innodb_buffer_pool_read_requests';
+
select * from t1;
+SELECT CAST(variable_value AS INTEGER) INTO @read2
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS
+WHERE VARIABLE_NAME='innodb_buffer_pool_read_requests';
+
+SELECT @read1>0, @read2>@read1;
+
begin;
insert into t1 values(2, 3);
rollback;
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 00000000..e6e46dbf
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test
@@ -0,0 +1,169 @@
+#
+# Test that user data is correctly "visualized" in
+# INFORMATION_SCHEMA.innodb_locks.lock_data
+#
+
+-- source include/have_innodb.inc
+
+SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout;
+SET GLOBAL innodb_lock_wait_timeout=100000000;
+
+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=@save_timeout;
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 00000000..745e1d94
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test
@@ -0,0 +1,95 @@
+--source include/have_innodb.inc
+
+#
+# Test that transaction data is correctly "visualized" in
+# INFORMATION_SCHEMA.INNODB_TRX
+#
+
+SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout;
+SET GLOBAL innodb_lock_wait_timeout=100000000;
+
+DESCRIBE INFORMATION_SCHEMA.INNODB_TRX;
+
+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 ER_NO_REFERENCED_ROW_2
+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
+-- disconnect con_trx
+
+-- connection con_verify_innodb_trx
+SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error
+FROM INFORMATION_SCHEMA.INNODB_TRX;
+-- disconnect con_verify_innodb_trx
+
+-- connection default
+DROP TABLE t2;
+DROP TABLE t1;
+
+-- source include/wait_until_count_sessions.inc
+
+SET GLOBAL innodb_lock_wait_timeout=@save_timeout;
diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt
index 4edc71b6..101f6eae 100644
--- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt
+++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt
@@ -26,3 +26,4 @@
--loose-innodb_buffer_pool_pages
--loose-innodb_buffer_pool_pages_index
--loose-innodb_buffer_pool_pages_blob
+--innodb-open-files=1000000
diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test
index 15b3bf4f..c62705da 100644
--- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test
+++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test
@@ -1,6 +1,10 @@
-- source include/have_innodb.inc
-- source include/not_embedded.inc
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+let SEARCH_PATTERN= \[Warning\] InnoDB: innodb_open_files 1000000 should not be greater than the open_files_limit [0-9]+;
+--source include/search_pattern_in_file.inc
+
#
# MDEV-7762 InnoDB: Failing assertion: block->page.buf_fix_count > 0 in buf0buf.ic line 730
#
diff --git a/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test b/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test
index 1fb7c6d0..fa93e95c 100644
--- a/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test
+++ b/mysql-test/suite/innodb/t/innodb_prefix_index_restart_server.test
@@ -93,3 +93,17 @@ SELECT col_1_text = REPEAT("a", 3500) , col_2_text = REPEAT("o", 3500) FROM
worklog5743;
DROP TABLE worklog5743;
+
+--echo #
+--echo # MDEV-21245 InnoDB: Using a partial-field key prefix in search
+--echo #
+CREATE TABLE t1 (a VARCHAR(255), KEY k(a)) DEFAULT CHARSET=utf8mb3
+ENGINE=InnoDB;
+INSERT INTO t1 set a='';
+--enable_info
+alter table t1 change a a varchar(3000);
+--disable_info
+SELECT * FROM t1 WHERE a IN ('');
+DROP TABLE t1;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/suite/innodb/t/innodb_scrub.test b/mysql-test/suite/innodb/t/innodb_scrub.test
index 8fe460da..cf6b92e1 100644
--- a/mysql-test/suite/innodb/t/innodb_scrub.test
+++ b/mysql-test/suite/innodb/t/innodb_scrub.test
@@ -4,7 +4,7 @@
let $MYSQLD_DATADIR=`select @@datadir`;
CREATE TABLE t1(f1 int auto_increment primary key,
f2 varchar(256),
- f3 text) engine = innodb;
+ f3 text) engine = innodb stats_persistent=0;
let $numinserts = 500;
--disable_query_log
begin;
diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt
new file mode 100644
index 00000000..aa53ff2e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt
@@ -0,0 +1 @@
+--innodb-stats-persistent
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 00000000..e441a795
--- /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.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt
new file mode 100644
index 00000000..aa53ff2e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt
@@ -0,0 +1 @@
+--innodb-stats-persistent
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 00000000..aeb5b5c2
--- /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.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt
new file mode 100644
index 00000000..aa53ff2e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt
@@ -0,0 +1 @@
+--innodb-stats-persistent
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 00000000..88ca8910
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test
@@ -0,0 +1,45 @@
+#
+# Test the persistent stats auto recalc on lots of tables
+#
+
+--source include/no_valgrind_without_big.inc
+-- 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.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt
new file mode 100644
index 00000000..aa53ff2e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt
@@ -0,0 +1 @@
+--innodb-stats-persistent
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 00000000..4cd91007
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test
@@ -0,0 +1,88 @@
+#
+# 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
+
+# open and close the table
+SELECT * FROM t;
+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
+
+# open and close the table
+SELECT * FROM t;
+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
+
+# open and close the table
+SELECT * FROM t;
+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_external_pages.test b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test
new file mode 100644
index 00000000..da0dce9a
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test
@@ -0,0 +1,79 @@
+#
+# Bug#18384390 WRONG STATISTICS WITH BIG ROW LENGTH AND PERSISTENT STATS
+#
+
+--source include/have_innodb.inc
+--source include/have_innodb_max_16k.inc
+--source include/have_sequence.inc
+
+CREATE TABLE bug18384390 (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ txt VARCHAR(10000)
+) ENGINE=INNODB STATS_PERSISTENT=1 STATS_AUTO_RECALC=0;
+
+let $count=1024;
+eval
+INSERT INTO bug18384390 (txt) SELECT REPEAT('0', 10000) FROM seq_1_to_$count;
+
+set use_stat_tables=never;
+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_fetch.opt b/mysql-test/suite/innodb/t/innodb_stats_fetch.opt
new file mode 100644
index 00000000..faa681c8
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_fetch.opt
@@ -0,0 +1,7 @@
+--innodb_sys_tables
+--innodb_sys_indexes
+--innodb_sys_virtual
+--innodb_sys_foreign
+--innodb_sys_foreign_cols
+--innodb_sys_tablestats
+--innodb_sys_tablespaces
diff --git a/mysql-test/suite/innodb/t/innodb_stats_fetch.test b/mysql-test/suite/innodb/t/innodb_stats_fetch.test
index 549ad65f..99fc115a 100644
--- a/mysql-test/suite/innodb/t/innodb_stats_fetch.test
+++ b/mysql-test/suite/innodb/t/innodb_stats_fetch.test
@@ -81,3 +81,18 @@ FROM information_schema.tables WHERE table_name = 'test_ps_fetch';
DROP TABLE test_ps_fetch;
set @@use_stat_tables = @save_use_stat_tables;
+
+--echo #
+--echo # MDEV-28613 LeakSanitizer caused by I_S query using LIMIT ROWS EXAMINED
+--echo #
+CREATE TABLE t1(f1 VARCHAR(255), FULLTEXT(f1))ENGINE=InnoDB;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES LIMIT ROWS EXAMINED 5;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES LIMIT ROWS EXAMINED 5;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS LIMIT ROWS EXAMINED 5;
+--disable_result_log
+SELECT SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES LIMIT ROWS EXAMINED 5;
+--enable_result_log
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL LIMIT ROWS EXAMINED 5;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN LIMIT ROWS EXAMINED 5;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS LIMIT ROWS EXAMINED 5;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations b/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations
new file mode 100644
index 00000000..561eb72d
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations
@@ -0,0 +1,4 @@
+[on]
+--innodb-stats-persistent=1
+[off]
+--innodb-stats-persistent=0
diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global.test b/mysql-test/suite/innodb/t/innodb_stats_flag_global.test
new file mode 100644
index 00000000..88f0ed7c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global.test
@@ -0,0 +1,91 @@
+-- source include/have_innodb.inc
+-- source include/not_embedded.inc
+
+#
+-- echo =====
+-- echo === Test ANALYZE behavior after default creation
+-- echo =====
+
+CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+DROP TABLE test_ps_flag;
+
+CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=default;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+DROP TABLE test_ps_flag;
+
+#
+-- echo =====
+-- echo === Test ANALYZE behavior after creation with explicit PS=OFF
+-- echo =====
+
+CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+DROP TABLE test_ps_flag;
+
+#
+-- echo =====
+-- echo === Test ANALYZE behavior after creation with explicit PS=ON
+-- echo =====
+
+CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+DROP TABLE test_ps_flag;
+
+#
+-- echo =====
+-- echo === Test ANALYZE behavior after creation with explicit PS=OFF,
+-- echo === then ALTER to ON, then ALTER to OFF, then ALTER to default
+-- echo =====
+
+CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0;
+
+ALTER TABLE test_ps_flag STATS_PERSISTENT=1;
+
+# also check that the change from the ALTER TABLE survives server restart
+-- source include/restart_mysqld.inc
+
+-- source innodb_stats_flag_global_analyze.inc
+
+ALTER TABLE test_ps_flag STATS_PERSISTENT=0;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+ALTER TABLE test_ps_flag STATS_PERSISTENT=default;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+DROP TABLE test_ps_flag;
+
+#
+-- echo =====
+-- echo === Test ANALYZE behavior after creation with explicit PS=ON,
+-- echo === then ALTER to OFF, then ALTER to ON, then ALTER to default
+-- echo =====
+
+CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1;
+
+ALTER TABLE test_ps_flag STATS_PERSISTENT=0;
+
+# also check that the change from the ALTER TABLE survives server restart
+-- source include/restart_mysqld.inc
+
+-- source innodb_stats_flag_global_analyze.inc
+
+ALTER TABLE test_ps_flag STATS_PERSISTENT=1;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+ALTER TABLE test_ps_flag STATS_PERSISTENT=default;
+
+-- source innodb_stats_flag_global_analyze.inc
+
+DROP TABLE test_ps_flag;
diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc b/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc
new file mode 100644
index 00000000..8a68677e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc
@@ -0,0 +1,13 @@
+SHOW CREATE TABLE test_ps_flag;
+
+DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag';
+DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag';
+
+# must be 0, we have just deleted the rows
+SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag';
+
+SET STATEMENT use_stat_tables=never FOR
+ANALYZE TABLE test_ps_flag;
+
+# if the table is PS enabled, then this should be 1 and 0 otherwise
+SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag';
diff --git a/mysql-test/suite/innodb/t/innodb_stats_persistent.test b/mysql-test/suite/innodb/t/innodb_stats_persistent.test
index a8a311a6..294f283b 100644
--- a/mysql-test/suite/innodb/t/innodb_stats_persistent.test
+++ b/mysql-test/suite/innodb/t/innodb_stats_persistent.test
@@ -13,6 +13,7 @@ ENGINE=INNODB STATS_PERSISTENT=1,STATS_AUTO_RECALC=1;
CREATE TABLE t2 LIKE t1;
INSERT INTO t1 (val) SELECT 4 FROM seq_1_to_16;
+SET STATEMENT use_stat_tables=never FOR
ANALYZE TABLE t1;
connect(con1, localhost, root,,);
@@ -49,7 +50,7 @@ SELECT COUNT(*) FROM t2;
connection con1;
EXPLAIN SELECT * FROM t2 WHERE val=4;
---source include/wait_all_purged.inc
+SET GLOBAL innodb_max_purge_lag_wait=0;
--echo # After COMMIT and purge, the DELETE must show up.
EXPLAIN SELECT * FROM t1 WHERE val=4;
@@ -82,3 +83,41 @@ DROP TABLE t1,t2;
SET GLOBAL innodb_stats_include_delete_marked = @saved_include_delete_marked;
SET GLOBAL innodb_stats_traditional = @saved_traditional;
SET GLOBAL innodb_stats_modified_counter = @saved_modified_counter;
+
+#
+# Bug#12429573 TIMESTAMP COLUMN OF INNODB.INDEX_STATS ARE NOT UPDATED
+# WHEN RE-RUNNING ANALYZE
+#
+CREATE TABLE bug12429573 (i INTEGER PRIMARY KEY, j INTEGER, KEY(j))
+ENGINE=INNODB STATS_PERSISTENT=1;
+
+SET STATEMENT use_stat_tables=never FOR
+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 INTO @last FROM mysql.innodb_table_stats
+WHERE table_name = 'bug12429573';
+SELECT * FROM mysql.innodb_index_stats
+WHERE table_name = 'bug12429573' AND last_update!=@last;
+
+# 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
+
+SET STATEMENT use_stat_tables=never FOR
+ANALYZE TABLE bug12429573;
+
+SELECT * FROM mysql.innodb_table_stats
+WHERE table_name = 'bug12429573' AND last_update=@last;
+SELECT * FROM mysql.innodb_index_stats
+WHERE table_name = 'bug12429573' AND last_update=@last;
+
+DROP TABLE bug12429573;
diff --git a/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt
new file mode 100644
index 00000000..aa53ff2e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt
@@ -0,0 +1 @@
+--innodb-stats-persistent
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 00000000..1aac71a0
--- /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 00000000..01fe4331
--- /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/no_valgrind_without_big.inc
+-- source include/have_innodb.inc
+-- 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 00000000..a5c3c862
--- /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_ut_format_name.test b/mysql-test/suite/innodb/t/innodb_ut_format_name.test
new file mode 100644
index 00000000..6e4023c7
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_ut_format_name.test
@@ -0,0 +1,17 @@
+#
+# 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 @save_dbug = @@debug_dbug;
+SET debug_dbug = '+d,test_ut_format_name';
+
+DROP TABLE t;
+
+SET debug_dbug = @save_dbug;
diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test
index 5b6d3f87..d6d7a988 100644
--- a/mysql-test/suite/innodb/t/instant_alter.test
+++ b/mysql-test/suite/innodb/t/instant_alter.test
@@ -3,6 +3,9 @@
let $datadir=`select @@datadir`;
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
--echo #
--echo # MDEV-11369: Instant ADD COLUMN for InnoDB
--echo #
@@ -964,3 +967,4 @@ remove_file $datadir/test/mdev28822_100427_innodb.frm;
copy_file std_data/mysql_upgrade/mdev28822_100427_innodb.frm $datadir/test/mdev28822_100427_innodb.frm;
ALTER TABLE mdev28822_100427_innodb ADD i1 INTEGER, ALGORITHM=INSTANT;
DROP TABLE mdev28822_100427_innodb;
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test
index 81d36849..8a4299e5 100644
--- a/mysql-test/suite/innodb/t/instant_alter_bugs.test
+++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test
@@ -1,4 +1,8 @@
--source include/have_innodb.inc
+--source include/have_sequence.inc
+
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
--echo #
--echo # MDEV-17821 Assertion `!page_rec_is_supremum(rec)' failed
@@ -526,4 +530,32 @@ CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB;
ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i;
DROP TABLE t1;
+--echo #
+--echo # MDEV-18322 Assertion "wrong_page_type" on instant ALTER
+--echo #
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE c TEXT
+ DEFAULT(SELECT CONCAT('CREATE TABLE t1 (c',
+ GROUP_CONCAT(seq SEPARATOR ' CHAR(200), c'),
+ ' CHAR(211)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT')
+ FROM seq_1_to_40);
+ EXECUTE IMMEDIATE c;
+END;
+$$
+DELIMITER ;$$
+INSERT INTO t1 SET c1=NULL;
+--error ER_TOO_BIG_ROWSIZE
+ALTER TABLE t1 ADD c41 INT FIRST;
+--error ER_TOO_BIG_ROWSIZE
+ALTER TABLE t1 ADD c41 INT FIRST;
+CHECK TABLE t1;
+SELECT COUNT(*) FROM t1;
+DROP TABLE t1;
+
--echo # End of 10.4 tests
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
+
+--echo # End of 10.6 tests
diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test
index b687664d..f51f61e3 100644
--- a/mysql-test/suite/innodb/t/instant_alter_crash.test
+++ b/mysql-test/suite/innodb/t/instant_alter_crash.test
@@ -14,7 +14,7 @@ let MYSQLD_DATADIR=`select @@datadir`;
--echo #
CREATE TABLE t1(id INT PRIMARY KEY, c2 INT UNIQUE)
-ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
+ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=REDUNDANT;
CREATE TABLE t2 LIKE t1;
INSERT INTO t1 VALUES(0,2);
INSERT INTO t2 VALUES(2,1);
diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test
index d9ef7b06..f11d0bd0 100644
--- a/mysql-test/suite/innodb/t/instant_alter_debug.test
+++ b/mysql-test/suite/innodb/t/instant_alter_debug.test
@@ -3,6 +3,9 @@
--source include/have_debug_sync.inc
--source include/have_sequence.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
SET @old_instant=
(SELECT variable_value FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column');
@@ -607,3 +610,7 @@ SET DEBUG_SYNC=RESET;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
+
+--echo # End of 10.6 tests
diff --git a/mysql-test/suite/innodb/t/instant_alter_purge.test b/mysql-test/suite/innodb/t/instant_alter_purge.test
index 445cae4d..5fbd4da8 100644
--- a/mysql-test/suite/innodb/t/instant_alter_purge.test
+++ b/mysql-test/suite/innodb/t/instant_alter_purge.test
@@ -14,7 +14,7 @@ connect (prevent_purge,localhost,root);
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
-CREATE TABLE t1 (f1 INT, f2 INT) ENGINE=InnoDB;
+CREATE TABLE t1 (f1 INT, f2 INT) ENGINE=InnoDB STATS_PERSISTENT=0;
INSERT INTO t1 () VALUES ();
ALTER TABLE t1 DROP f2, ADD COLUMN f2 INT;
ALTER TABLE t1 DROP f1;
diff --git a/mysql-test/suite/innodb/t/instant_alter_rollback.test b/mysql-test/suite/innodb/t/instant_alter_rollback.test
index a4608001..491f6346 100644
--- a/mysql-test/suite/innodb/t/instant_alter_rollback.test
+++ b/mysql-test/suite/innodb/t/instant_alter_rollback.test
@@ -3,6 +3,8 @@
# The embedded server tests do not support restarting.
--source include/not_embedded.inc
+SET GLOBAL innodb_stats_persistent = 0;
+
# Flush any open myisam tables from previous tests
FLUSH TABLES;
diff --git a/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test b/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test
index 3a04c712..0f88f8d9 100644
--- a/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test
+++ b/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test
@@ -3,7 +3,8 @@
--source include/have_debug.inc
--source include/have_debug_sync.inc
-CREATE TABLE t (pk int PRIMARY KEY, c varchar(10)) ENGINE=InnoDB;
+CREATE TABLE t (pk int PRIMARY KEY, c varchar(10))
+STATS_PERSISTENT=0 ENGINE=InnoDB;
INSERT INTO t VALUES (10, "0123456789");
--connection default
diff --git a/mysql-test/suite/innodb/t/log_file_name.test b/mysql-test/suite/innodb/t/log_file_name.test
index eb616d7f..f88a13db 100644
--- a/mysql-test/suite/innodb/t/log_file_name.test
+++ b/mysql-test/suite/innodb/t/log_file_name.test
@@ -7,6 +7,8 @@
# Embedded server does not support crashing
--source include/not_embedded.inc
+call mtr.add_suppression("InnoDB: Header page consists of zero bytes in datafile:");
+
SET GLOBAL innodb_file_per_table=ON;
FLUSH TABLES;
@@ -171,6 +173,9 @@ call mtr.add_suppression("InnoDB: Plugin initialization aborted");
call mtr.add_suppression("Plugin 'InnoDB' \(init function returned error\|registration as a STORAGE ENGINE failed\)");
call mtr.add_suppression("InnoDB: Table test/u[123] in the InnoDB data dictionary has tablespace id [1-9][0-9]*, but tablespace with that id or name does not exist\\. Have you deleted or moved \\.ibd files\\?");
call mtr.add_suppression("InnoDB: Cannot replay rename of tablespace.*");
+call mtr.add_suppression("InnoDB: Attempted to open a previously opened tablespace");
+call mtr.add_suppression("InnoDB: Recovery cannot access file");
+call mtr.add_suppression("InnoDB: Cannot read first page in datafile:");
FLUSH TABLES;
--enable_query_log
diff --git a/mysql-test/suite/innodb/t/mdev-14846.test b/mysql-test/suite/innodb/t/mdev-14846.test
index b1f32302..e9698cc0 100644
--- a/mysql-test/suite/innodb/t/mdev-14846.test
+++ b/mysql-test/suite/innodb/t/mdev-14846.test
@@ -2,6 +2,8 @@
--source include/count_sessions.inc
--source include/have_debug_sync.inc
+--source include/innodb_stable_estimates.inc
+
CREATE TABLE t1 (
pk INT,
f1 VARCHAR(10) NOT NULL,
diff --git a/mysql-test/suite/innodb/t/mem_pressure.test b/mysql-test/suite/innodb/t/mem_pressure.test
new file mode 100644
index 00000000..91f75e65
--- /dev/null
+++ b/mysql-test/suite/innodb/t/mem_pressure.test
@@ -0,0 +1,44 @@
+--source include/have_debug.inc
+--source include/linux.inc
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+--source include/have_sequence.inc
+
+--echo #
+--echo # MDEV-24670 avoid OOM by linux kernel co-operative memory management
+--echo #
+
+set @save_dbug=@@debug_dbug;
+
+set @save_limit=@@GLOBAL.innodb_limit_optimistic_insert_debug;
+# Wait for the undo logs to be empty from previous tests.
+# This is not an actual parameter, so there is no need to restore it.
+set GLOBAL innodb_max_purge_lag_wait=0;
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+SET GLOBAL innodb_limit_optimistic_insert_debug=2;
+SET STATEMENT unique_checks=0, foreign_key_checks=0 FOR
+INSERT INTO t1 SELECT * FROM seq_1_to_1000;
+
+SET GLOBAL innodb_limit_optimistic_insert_debug=@save_limit;
+
+DROP TABLE t1;
+
+SELECT CAST(VARIABLE_VALUE AS INTEGER) INTO @dirty_prev
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS
+WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty';
+
+set debug_dbug="d,trigger_garbage_collection";
+SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size;
+
+SELECT CAST(VARIABLE_VALUE AS INTEGER) < @dirty_prev AS LESS_DIRTY_IS_GOOD
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS
+WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty';
+
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+let SEARCH_PATTERN= InnoDB: Memory pressure event freed.*;
+--source include/search_pattern_in_file.inc
+
+set debug_dbug=@save_dbug;
+
+--echo # End of 10.11 tests
diff --git a/mysql-test/suite/innodb/t/no_pad.test b/mysql-test/suite/innodb/t/no_pad.test
index 1be1972c..15ab71b6 100644
--- a/mysql-test/suite/innodb/t/no_pad.test
+++ b/mysql-test/suite/innodb/t/no_pad.test
@@ -8,3 +8,49 @@ ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES ('',2);
ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-26743 InnoDB: CHAR+nopad does not work well
+--echo #
+
+--echo #
+--echo # Basic Latin letter vs equal accented letter
+--echo #
+
+SET NAMES utf8mb3;
+CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT;
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES ('a'),('ä');
+DROP TABLE t1;
+
+--echo #
+--echo # Two letters vs equal (but space padded) expansion
+--echo #
+
+CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES ('ss'),('ß');
+SET sql_mode=PAD_CHAR_TO_FULL_LENGTH;
+SELECT HEX(a) FROM t1;
+SET sql_mode=DEFAULT;
+DROP TABLE t1;
+
+--echo #
+--echo # Basic Latin letter (but followed by an ignorable character) vs equal accented letter
+--echo #
+
+SET NAMES utf8mb3;
+CREATE TABLE t1 (a CHAR(3), PRIMARY KEY(a)) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES (CONCAT('a',_utf8mb3 0x01)),('ä');
+SET sql_mode=PAD_CHAR_TO_FULL_LENGTH;
+SELECT HEX(a) FROM t1 ORDER BY HEX(a);
+SET sql_mode=DEFAULT;
+DROP TABLE t1;
+
+SET NAMES utf8mb3;
+CREATE TABLE t1 (a CHAR(2), PRIMARY KEY(a)) COLLATE utf8_unicode_nopad_ci ENGINE=InnoDB ROW_FORMAT=COMPACT;
+INSERT INTO t1 VALUES (CONCAT('a',_utf8mb3 0x01)),('ä');
+SET sql_mode=PAD_CHAR_TO_FULL_LENGTH;
+SELECT HEX(a) FROM t1 ORDER BY HEX(a);
+SET sql_mode=DEFAULT;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/page_id_innochecksum.test b/mysql-test/suite/innodb/t/page_id_innochecksum.test
index 902d2aba..9d8114d1 100644
--- a/mysql-test/suite/innodb/t/page_id_innochecksum.test
+++ b/mysql-test/suite/innodb/t/page_id_innochecksum.test
@@ -6,7 +6,7 @@ let MYSQLD_BASEDIR= `SELECT @@basedir`;
let MYSQLD_DATADIR= `SELECT @@datadir`;
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
-create table t1(f1 int not null)engine=innodb;
+create table t1(f1 int not null)engine=innodb stats_persistent=0;
insert into t1 values(1), (2), (3);
let $resultlog=$MYSQLTEST_VARDIR/tmp/result.log;
diff --git a/mysql-test/suite/innodb/t/purge.test b/mysql-test/suite/innodb/t/purge.test
index 97c0fb86..1dc2b117 100644
--- a/mysql-test/suite/innodb/t/purge.test
+++ b/mysql-test/suite/innodb/t/purge.test
@@ -1,6 +1,9 @@
--source include/have_innodb.inc
--source include/have_innodb_16k.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
--echo # Bug #12429576 - Test an assertion failure on purge.
CREATE TABLE t1_purge (
A int,
@@ -110,4 +113,6 @@ SHOW CREATE TABLE t12963823;
# We need to activate the purge thread before DROP TABLE.
-- source include/wait_all_purged.inc
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge, t12637786, t12963823;
diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test
index 4e664109..8a38a418 100644
--- a/mysql-test/suite/innodb/t/purge_secondary.test
+++ b/mysql-test/suite/innodb/t/purge_secondary.test
@@ -1,6 +1,9 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
--disable_query_log
call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool");
--enable_query_log
@@ -170,3 +173,7 @@ UNLOCK TABLES;
DROP TABLE t1;
--echo # End of 10.3 tests
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
+
+--echo # End of 10.6 tests
diff --git a/mysql-test/suite/innodb/t/purge_thread_shutdown.test b/mysql-test/suite/innodb/t/purge_thread_shutdown.test
deleted file mode 100644
index 53b375b8..00000000
--- a/mysql-test/suite/innodb/t/purge_thread_shutdown.test
+++ /dev/null
@@ -1,43 +0,0 @@
-source include/have_innodb.inc;
-source include/not_embedded.inc;
-source include/have_debug.inc;
-
-connect con1, localhost, root;
-create table t1 (a int) engine=innodb;
-insert t1 values (1),(2),(3),(4);
-delete from t1 where a=1;
-
-select user,state from information_schema.processlist order by 2;
-
-set global debug_dbug='+d,only_kill_system_threads';
-set global innodb_fast_shutdown=0;
-
---let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')`
---let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect
-exec echo "wait" > $_expect_file_name;
-send shutdown;
-
-connection default;
-disconnect con1;
-
-sleep 5;
-select user,state from information_schema.processlist order by 2;
-set global innodb_fast_shutdown=1;
-
-let $wait_condition=select count(*) = 0 from information_schema.processlist where user='system user';
-source include/wait_condition.inc;
-select user,state from information_schema.processlist order by 2;
-
-delete from t1 where a=3;
-error ER_WRONG_VALUE_FOR_VAR;
-set global innodb_fast_shutdown=0;
-
-# Get id with space prefix to ensure that replace_result doesn't replace
-# the error code
-let $me=`select concat(' ', connection_id())`;
-replace_result $me ID;
-error ER_CONNECTION_KILLED, 2026;
-eval kill $me;
-
-source include/start_mysqld.inc;
-drop table t1;
diff --git a/mysql-test/suite/innodb/t/read_only_recovery.test b/mysql-test/suite/innodb/t/read_only_recovery.test
index 47146213..d011b3aa 100644
--- a/mysql-test/suite/innodb/t/read_only_recovery.test
+++ b/mysql-test/suite/innodb/t/read_only_recovery.test
@@ -39,6 +39,8 @@ SELECT * FROM t;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t;
SET GLOBAL innodb_max_purge_lag_wait=0;
+INSERT INTO mysql.innodb_index_stats
+SELECT * FROM mysql.innodb_index_stats LIMIT 0;
--let $restart_parameters=
--source include/restart_mysqld.inc
SELECT * FROM t;
diff --git a/mysql-test/suite/innodb/t/records_in_range.test b/mysql-test/suite/innodb/t/records_in_range.test
new file mode 100644
index 00000000..697dbc1e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/records_in_range.test
@@ -0,0 +1,432 @@
+#
+# Test btr_estimate_n_rows_in_range() which is used by
+# ha_innobase::records_in_range()
+#
+
+-- source include/have_debug.inc
+-- source include/have_innodb.inc
+-- source include/innodb_page_size_small.inc
+
+CREATE TABLE records_in_range_test (
+ c1 VARCHAR(16),
+ c2 VARCHAR(512),
+ PRIMARY KEY (c1)
+) ENGINE=INNODB STATS_PERSISTENT=1;
+
+# Insert some records so that they cannot fit in one page for some page sizes
+# in order to exercise records_in_range() where 1, 2 or more pages are sampled
+INSERT INTO records_in_range_test VALUES
+('ccc', REPEAT('v', 512)),
+('kkk01', REPEAT('v', 512)),
+('kkk02', REPEAT('v', 512)),
+('kkk03', REPEAT('v', 512)),
+('kkk04', REPEAT('v', 512)),
+('kkk05', REPEAT('v', 512)),
+('kkk06', REPEAT('v', 512)),
+('kkk07', REPEAT('v', 512)),
+('kkk08', REPEAT('v', 512)),
+('mmm', REPEAT('v', 512)),
+('nnn', REPEAT('v', 512)),
+('uuu01', REPEAT('v', 512)),
+('uuu02', REPEAT('v', 512)),
+('uuu03', REPEAT('v', 512)),
+('uuu04', REPEAT('v', 512)),
+('uuu05', REPEAT('v', 512)),
+('uuu06', REPEAT('v', 512)),
+('uuu07', REPEAT('v', 512)),
+('uuu08', REPEAT('v', 512)),
+('xxx', REPEAT('v', 512));
+
+SET STATEMENT use_stat_tables=never FOR
+ANALYZE TABLE records_in_range_test;
+
+# 16k or bigger page size: 1 leaf page
+# 8k page size: 2 leaf pages
+# 4k page size: 4 leaf pages
+SELECT index_name, stat_name, stat_value
+FROM mysql.innodb_index_stats
+WHERE
+table_name='records_in_range_test' AND stat_name = 'n_leaf_pages';
+
+# 16k or bigger page size: 1 page in total (leaf + nonleaf)
+# 8k page size: 3 pages in total (leaf + nonleaf)
+# 4k page size: 5 pages in total (leaf + nonleaf)
+SELECT index_name, stat_name, stat_value
+FROM mysql.innodb_index_stats
+WHERE
+table_name='records_in_range_test' AND stat_name = 'size';
+
+# We exploit the warning mechanism here to display the return value from
+# btr_estimate_n_rows_in_range()
+SET @save_dbug = @@debug_dbug;
+SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value';
+
+-- echo
+-- echo In all SELECTs below the number of the records in the range returned
+-- echo by COUNT(*) must be the same as the number returned by
+-- echo btr_estimate_n_rows_in_range() which can be seen inside the artificial
+-- echo warning
+
+-- echo
+-- echo Test left-unbounded, right-open intervals
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'aaa';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'zzz';
+
+-- echo
+-- echo Test left-unbounded, right-closed intervals
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'aaa';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'zzz';
+
+-- echo
+-- echo Test left-open, right-unbounded intervals
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz';
+
+-- echo
+-- echo Test left-closed, right-unbounded intervals
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz';
+
+-- echo
+-- echo Test left-open, right-open intervals
+-- echo In some cases here the optimizer is smart enough not to call
+-- echo ha_innobase::records_in_range() at all, so we get no warning containing
+-- echo the value returned from btr_estimate_n_rows_in_range()
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'zzz';
+
+-- echo
+-- echo Test left-closed, right-open intervals
+-- echo In some cases here the optimizer is smart enough not to call
+-- echo ha_innobase::records_in_range() at all, so we get no warning containing
+-- echo the value returned from btr_estimate_n_rows_in_range()
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'zzz';
+
+-- echo
+-- echo Test left-open, right-closed intervals
+-- echo In some cases here the optimizer is smart enough not to call
+-- echo ha_innobase::records_in_range() at all, so we get no warning containing
+-- echo the value returned from btr_estimate_n_rows_in_range()
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'zzz';
+
+-- echo
+-- echo Test left-closed, right-closed intervals
+-- echo In some cases here the optimizer is smart enough not to call
+-- echo ha_innobase::records_in_range() at all, so we get no warning containing
+-- echo the value returned from btr_estimate_n_rows_in_range()
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'zzz';
+-- echo
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'bbb';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'ccc';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'eee';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'mmm';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'nnn';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'qqq';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'xxx';
+SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'zzz';
+
+SET DEBUG_DBUG = @save_dbug;
+
+DROP TABLE records_in_range_test;
diff --git a/mysql-test/suite/innodb/t/row_format_redundant.opt b/mysql-test/suite/innodb/t/row_format_redundant.opt
index c44c611e..d1d93da0 100644
--- a/mysql-test/suite/innodb/t/row_format_redundant.opt
+++ b/mysql-test/suite/innodb/t/row_format_redundant.opt
@@ -1 +1,3 @@
--innodb-checksum-algorithm=crc32
+--skip-innodb-fast-shutdown
+--skip-innodb-buffer-pool-dump-at-shutdown
diff --git a/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test b/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test
index dab9bcfa..24029a48 100644
--- a/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test
+++ b/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test
@@ -1,7 +1,7 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
--source include/innodb_page_size_small.inc
---source include/have_normal_bzip.inc
+--source include/have_normal_zlib.inc
call mtr.add_suppression("InnoDB: Cannot add field .* in table .* because after adding it, the row size is .* which is greater than maximum allowed size (.*) for a record on index leaf page.");
diff --git a/mysql-test/suite/innodb/t/scrub_debug.test b/mysql-test/suite/innodb/t/scrub_debug.test
index a1f0b38e..8cebfca6 100644
--- a/mysql-test/suite/innodb/t/scrub_debug.test
+++ b/mysql-test/suite/innodb/t/scrub_debug.test
@@ -10,7 +10,7 @@ SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=2;
let $MYSQLD_DATADIR=`select @@datadir`;
CREATE TABLE t1(f1 INT AUTO_INCREMENT PRIMARY KEY,
f2 VARCHAR(256) GENERATED ALWAYS as('repairman'),
- INDEX idx(f2))ENGINE= InnoDB;
+ INDEX idx(f2))ENGINE= InnoDB STATS_PERSISTENT=0;
INSERT INTO t1(f1) SELECT seq FROM seq_1_to_50;
FLUSH TABLE t1 FOR EXPORT;
let SEARCH_PATTERN= repairman;
diff --git a/mysql-test/suite/innodb/t/table_flags.opt b/mysql-test/suite/innodb/t/table_flags.opt
index bca67495..8f6c7db5 100644
--- a/mysql-test/suite/innodb/t/table_flags.opt
+++ b/mysql-test/suite/innodb/t/table_flags.opt
@@ -1,2 +1,3 @@
--innodb-checksum-algorithm=crc32
--skip-innodb-read-only-compressed
+--skip-innodb-buffer-pool-dump-at-shutdown
diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test
index 34204ae1..511d3c24 100644
--- a/mysql-test/suite/innodb/t/table_flags.test
+++ b/mysql-test/suite/innodb/t/table_flags.test
@@ -157,7 +157,9 @@ SHOW CREATE TABLE tr;
SHOW CREATE TABLE tc;
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM tc;
+--error ER_GET_ERRNO
SHOW CREATE TABLE td;
+--error ER_GET_ERRNO
SELECT * FROM td;
# This table was converted to NO_ROLLBACK due to the SYS_TABLES.TYPE change.
SHOW CREATE TABLE tz;
diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt
new file mode 100644
index 00000000..66bceccc
--- /dev/null
+++ b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt
@@ -0,0 +1 @@
+--innodb-sys-tablespaces
diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test
new file mode 100644
index 00000000..dc87e3fa
--- /dev/null
+++ b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test
@@ -0,0 +1,162 @@
+--echo #
+--echo # Test the limits of a file-per-table tablespace name. MySQL combines
+--echo # the database name with the table name to make a unique table name.
+--echo #
+
+--source include/have_innodb.inc
+--source include/not_windows.inc
+# This will test the limit of a filename in MySQL at 512 bytes.
+# We control that by making it a relative path starting with "./".
+# The embedded server uses an absolute path as the datadir
+# which has a non-deterministic length.
+--source include/not_embedded.inc
+
+SET default_storage_engine=InnoDB;
+LET $MYSQLD_DATADIR = `select @@datadir`;
+
+--echo #
+--echo # MySQL limits each database and tablename identifier to 64 characters
+--echo # of up to 3 bytes per character, corresponding to 192 bytes.
+--echo #
+LET $too_long_name = this_sixty_five_byte_name_is_too_long____________________________;
+--error ER_WRONG_DB_NAME
+--eval CREATE DATABASE `$too_long_name`
+
+LET $long_name = this_sixty_four_byte_name_is_not_too_long_______________________;
+--eval CREATE DATABASE `$long_name`
+--eval USE `$long_name`
+
+--echo #
+--echo # A 64 character tablename can be created in a 64 character database name
+--echo #
+--eval CREATE TABLE `$long_name`.`$long_name` (a SERIAL)
+
+--echo #
+--echo # A 65 character tablename is too long.
+--echo #
+--error ER_WRONG_TABLE_NAME
+--eval CREATE TABLE `test`.`$too_long_name` (a SERIAL)
+--error ER_WRONG_TABLE_NAME
+--eval CREATE TABLE `$long_name`.`$too_long_name` (a SERIAL)
+
+--echo #
+--echo # Non-non-filename-safe characters like '#' are expanded to '@0023'.
+--echo # On many file systems, such as Linux extfs, you can create a database name
+--echo # that expands to up to 255 bytes long.
+--echo # `##################################################_long` is expanded to
+--echo # (50 * 5) + 5 = 255.
+--echo #
+LET $long_db_name = ##################################################_long;
+--eval CREATE DATABASE `$long_db_name`;
+--eval USE `$long_db_name`
+
+--echo #
+--echo # This 256-byte name is only one byte longer but fails with an error code
+--echo # from the stat operation.
+--echo # `##################################################_long_` is expanded to
+--echo # (50 * 5) + 6 = 256.
+--echo #
+--replace_regex /Errcode: [0-9]+/Errcode: ##/ /@0023/#/
+--error 13
+CREATE DATABASE `##################################################_long_`;
+
+--echo #
+--echo # This 300-byte name which is the longest name that gets an error code
+--echo # from the stat operation.
+--echo # `###########################################################_long` is expanded to
+--echo # (59 * 5) + 5 = 300.
+--echo #
+--replace_regex /Errcode: [0-9]+/Errcode: ##/ /@0023/#/
+--error 13
+CREATE DATABASE `###########################################################_long`;
+
+--echo #
+--echo # This 301-byte name which is only one byte longer but fails with ER_TOO_LONG_IDENT.
+--echo # `###########################################################_long_` is expanded to
+--echo # (59 * 5) + 6 = 301.
+--echo #
+--replace_result @0023 #
+--error ER_WRONG_DB_NAME
+CREATE DATABASE `###########################################################_long_`;
+
+USE test;
+
+LET $long_249_byte_table_name = #################################################long;
+LET $long_250_byte_table_name = #################################################_long;
+LET $long_251_byte_table_name = #################################################_long_;
+LET $long_252_byte_table_name = #################################################_long___;
+
+--echo #
+--echo # An expanded table name is limited to 251 bytes
+--echo #
+--eval CREATE TABLE `test`.`$long_251_byte_table_name` (a SERIAL)
+
+--echo #
+--echo # A 252-byte tablename is too long
+--echo #
+--replace_regex /errno: [0-9]+/errno: ##/ /@0023/#/
+--error ER_CANT_CREATE_TABLE
+--eval CREATE TABLE `test`.`$long_252_byte_table_name` (a SERIAL)
+
+CREATE DATABASE twenty_byte_db_name_;
+USE `twenty_byte_db_name_`;
+
+--echo #
+--echo # A 251 byte expanded table name will fit with a longer database name
+--echo #
+--eval CREATE TABLE `twenty_byte_db_name_`.`$long_251_byte_table_name` (a SERIAL)
+
+--echo #
+--echo # A 252 byte expanded table name is also too long in a longer database name
+--echo #
+--replace_regex /errno: [0-9]+/errno: ##/ /@0023/#/
+--error ER_CANT_CREATE_TABLE
+--eval CREATE TABLE `twenty_byte_db_name_`.`$long_252_byte_table_name` (a SERIAL)
+
+--echo #
+--echo # Another limitation is a 512 byte length to an expanded path that includes
+--echo # the datadir which is './' in this test, the expanded database name,
+--echo # the directory separator '/', the expanded table name, and the file extension.
+--echo # './long_db_name.long_250_byte_table_name.frm'
+--echo # 2+ 255 +1+ 250 +1+3 = 512
+--echo #
+--eval CREATE TABLE `$long_db_name`.`$long_250_byte_table_name` (a SERIAL)
+
+--error ER_IDENT_CAUSES_TOO_LONG_PATH
+--eval CREATE TABLE `$long_db_name`.`$long_251_byte_table_name` (a SERIAL)
+SHOW WARNINGS;
+
+--echo #
+--echo # Show the successfully created databases and tables
+--echo #
+--echo ---- list_files MYSQLD_DATADIR/test
+--replace_result @0023 #
+--list_files $MYSQLD_DATADIR/test
+--echo ---- list_files MYSQLD_DATADIR/$long_name
+--replace_result @0023 #
+--list_files $MYSQLD_DATADIR/$long_name
+--echo ---- list_files MYSQLD_DATADIR/$long_db_name
+--replace_result @0023 #
+--list_files $MYSQLD_DATADIR/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023_long
+
+--replace_result @0023 #
+SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%';
+--replace_result @0023 #
+SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%';
+--vertical_results
+--replace_regex /innodb_file_per_table_[0-9]*/innodb_file_per_table_##/
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR @0023 #
+SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%';
+--horizontal_results
+
+--echo #
+--echo # Cleanup
+--echo #
+
+--eval DROP TABLE `$long_name`.`$long_name`
+--eval DROP TABLE `test`.`$long_251_byte_table_name`
+--eval DROP TABLE `twenty_byte_db_name_`.`$long_251_byte_table_name`
+--eval DROP TABLE `$long_db_name`.`$long_250_byte_table_name`
+--eval DROP DATABASE `$long_name`
+--eval DROP DATABASE `$long_db_name`
+DROP DATABASE `twenty_byte_db_name_`;
diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt b/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt
new file mode 100644
index 00000000..66bceccc
--- /dev/null
+++ b/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt
@@ -0,0 +1 @@
+--innodb-sys-tablespaces
diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_windows.test b/mysql-test/suite/innodb/t/tablespace_per_table_windows.test
new file mode 100644
index 00000000..eee7209c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/tablespace_per_table_windows.test
@@ -0,0 +1,77 @@
+--echo #
+--echo # Test the limits of a file-per-table tablespace name. MySQL combines
+--echo # the database name with the table name to make a unique table name.
+--echo #
+
+# There is no use in testing the maximum expanded filename using "#" or
+# some other character that is expanded by MySQL to "@0023" because
+# Windows imposes a maximum absolute path length of 260 bytes. So the
+# results will depend upon what local directory this test is run in.
+# See https://msdn.microsoft.com/en-us/library/aa365247.aspx
+# "Maximum Path Length Limitation
+# In the Windows API, the maximum length for a path is MAX_PATH, which is
+# defined as 260 characters. A local path is structured in the following
+# order: drive letter, colon, backslash, name components separated by
+# backslashes, and a terminating null character. For example, the maximum
+# path on drive D is "D:\some 256-character path string<NUL>" where
+# "<NUL>" represents the invisible terminating null character for the
+# current system codepage. (The characters < > are used here for visual
+# clarity and cannot be part of a valid path string.)"
+
+--source include/have_innodb.inc
+--source include/windows.inc
+# This will test the limit of a filename in MySQL at 512 bytes.
+# We control that by making it a relative path starting with "./".
+# The embedded server uses an absolute path as the datadir
+# which has a non-deterministic length.
+--source include/not_embedded.inc
+
+SET default_storage_engine=InnoDB;
+LET $MYSQLD_DATADIR = `select @@datadir`;
+
+--echo #
+--echo # MySQL limits each database and tablename identifier to 64 characters
+--echo # of up to 3 bytes per character, corresponding to 192 bytes.
+--echo #
+LET $too_long_name = this_sixty_five_byte_name_is_too_long____________________________;
+--error ER_WRONG_DB_NAME
+--eval CREATE DATABASE `$too_long_name`
+
+LET $long_name = this_sixty_four_byte_name_is_not_too_long_______________________;
+--eval CREATE DATABASE `$long_name`
+--eval USE `$long_name`
+
+--echo #
+--echo # A 64 character tablename can be created in a 64 character database name
+--echo #
+--eval CREATE TABLE `$long_name`.`$long_name` (a SERIAL)
+
+--echo #
+--echo # A 65 character tablename is too long.
+--echo #
+--error ER_WRONG_TABLE_NAME
+--eval CREATE TABLE `test`.`$too_long_name` (a SERIAL)
+--error ER_WRONG_TABLE_NAME
+--eval CREATE TABLE `$long_name`.`$too_long_name` (a SERIAL)
+
+--echo #
+--echo # Show the successfully created database and table
+--echo #
+--eval SHOW CREATE TABLE `$long_name`.`$long_name`
+
+--echo ---- list_files MYSQLD_DATADIR/$long_name
+--list_files $MYSQLD_DATADIR/$long_name
+
+SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%';
+SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%';
+--vertical_results
+--replace_regex /innodb_file_per_table_[0-9]*/innodb_file_per_table_##/
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%';
+--horizontal_results
+
+--echo #
+--echo # Cleanup
+--echo #
+
+--eval DROP DATABASE `$long_name`
diff --git a/mysql-test/suite/innodb/t/truncate_crash.test b/mysql-test/suite/innodb/t/truncate_crash.test
index c5156b4b..8a11b1ed 100644
--- a/mysql-test/suite/innodb/t/truncate_crash.test
+++ b/mysql-test/suite/innodb/t/truncate_crash.test
@@ -4,7 +4,7 @@
--source include/not_embedded.inc
FLUSH TABLES;
-CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0;
INSERT INTO t1 VALUES (1),(2);
connect (wait,localhost,root,,test);
diff --git a/mysql-test/suite/innodb/t/truncate_foreign.test b/mysql-test/suite/innodb/t/truncate_foreign.test
index abbe1b3d..c29c1410 100644
--- a/mysql-test/suite/innodb/t/truncate_foreign.test
+++ b/mysql-test/suite/innodb/t/truncate_foreign.test
@@ -89,16 +89,14 @@ call mtr.add_suppression("InnoDB: In ALTER TABLE `test`\\.`t1` has or is");
CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY (pk), KEY (a)) ENGINE=InnoDB;
SET FOREIGN_KEY_CHECKS=0;
-ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a), ALGORITHM=COPY;
+ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (a), ALGORITHM=COPY;
INSERT INTO t1 VALUES (1,1);
+CREATE TABLE t2(f1 INT PRIMARY KEY)ENGINE=InnoDB;
LOCK TABLES t1 WRITE;
SET FOREIGN_KEY_CHECKS=1;
--error ER_CANNOT_ADD_FOREIGN
TRUNCATE t1;
-# Whether TRUNCATE succeeds or fails, it will reload FOREIGN KEY constraints.
-# As a result, ha_innobase::referenced_by_foreign_key() will retun TRUE
-# (for the self-referential key), and the statement will fail.
---error ER_TABLE_NOT_LOCKED
+--error ER_NO_REFERENCED_ROW_2
INSERT INTO t1 VALUES (2,2);
SELECT * FROM t1;
UNLOCK TABLES;
@@ -107,6 +105,6 @@ INSERT INTO t1 VALUES (2,2);
SET FOREIGN_KEY_CHECKS=0;
INSERT INTO t1 VALUES (2,2);
SELECT * FROM t1;
-DROP TABLE t1;
+DROP TABLE t2, t1;
--echo # End of 10.6 tests
diff --git a/mysql-test/suite/innodb/t/trx_id_future.test b/mysql-test/suite/innodb/t/trx_id_future.test
index 1aeb1372..049e8f2c 100644
--- a/mysql-test/suite/innodb/t/trx_id_future.test
+++ b/mysql-test/suite/innodb/t/trx_id_future.test
@@ -8,7 +8,7 @@
let PAGE_SIZE=`select @@innodb_page_size`;
-CREATE TABLE t1(a INT) row_format=redundant engine=innoDB;
+CREATE TABLE t1(a INT) row_format=redundant engine=innoDB stats_persistent=0;
INSERT INTO t1 VALUES(1);
let MYSQLD_DATADIR=`select @@datadir`;
diff --git a/mysql-test/suite/innodb/t/undo_log.test b/mysql-test/suite/innodb/t/undo_log.test
index 2dbc9191..60da94c3 100644
--- a/mysql-test/suite/innodb/t/undo_log.test
+++ b/mysql-test/suite/innodb/t/undo_log.test
@@ -1,5 +1,8 @@
--source include/have_innodb.inc
+SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent = 0;
+
SET innodb_strict_mode=OFF;
CREATE TABLE test_tab (
a_str_18 mediumtext,
@@ -151,3 +154,5 @@ ROLLBACK;
--source include/wait_all_purged.inc
DROP TABLE t1;
DROP TABLE t2;
+
+SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
diff --git a/mysql-test/suite/innodb/t/undo_space_dblwr.opt b/mysql-test/suite/innodb/t/undo_space_dblwr.opt
index 0b4f5917..f498dd1f 100644
--- a/mysql-test/suite/innodb/t/undo_space_dblwr.opt
+++ b/mysql-test/suite/innodb/t/undo_space_dblwr.opt
@@ -1,2 +1,3 @@
--innodb_undo_tablespaces=3
--innodb_sys_tablespaces
+--innodb-stats-persistent=0