diff --git a/mysql-test/include/wait_innodb_all_purged.inc b/mysql-test/include/wait_innodb_all_purged.inc new file mode 100644 index 00000000000..97b038acc44 --- /dev/null +++ b/mysql-test/include/wait_innodb_all_purged.inc @@ -0,0 +1,59 @@ +# include/wait_innodb_all_purged.inc +# +# SUMMARY +# +# Waits until purged all undo records of innodb, or operation times out. +# +# USAGE +# +# --source include/wait_innodb_all_purged.inc +# +--source include/have_innodb.inc +--source include/have_debug.inc + +--disable_query_log + +let $wait_counter_init= 300; +if ($wait_timeout) +{ + let $wait_counter_init= `SELECT $wait_timeout * 10`; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; + +let $wait_counter= $wait_counter_init; + +# Keep track of how many times the wait condition is tested +let $wait_condition_reps= 0; +let $prev_trx_age= 0; +while ($wait_counter) +{ + let $trx_age = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME = 'INNODB_PURGE_TRX_ID_AGE';`; + + if ($trx_age != $prev_trx_age) + { + let $wait_counter= $wait_counter_init; + let $prev_trx_age= $trx_age; + } + + let $success= `SELECT $trx_age < 1`; + inc $wait_condition_reps; + if ($success) + { + let $wait_counter= 0; + } + if (!$success) + { + set global innodb_purge_run_now=ON; + real_sleep 0.1; + dec $wait_counter; + } +} +if (!$success) +{ + echo Timeout in wait_innodb_all_purged.inc for INNODB_PURGE_TRX_ID_AGE = $trx_age; +} + +--enable_query_log diff --git a/mysql-test/suite/innodb/disabled.def b/mysql-test/suite/innodb/disabled.def index ad1323d4857..8cae44a3607 100644 --- a/mysql-test/suite/innodb/disabled.def +++ b/mysql-test/suite/innodb/disabled.def @@ -9,4 +9,4 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -innodb_bug14676111: MDEV-4396 + diff --git a/mysql-test/suite/innodb/r/innodb_bug14676111.result b/mysql-test/suite/innodb/r/innodb_bug14676111.result index ebecd1d00cb..c2fdfee5522 100644 --- a/mysql-test/suite/innodb/r/innodb_bug14676111.result +++ b/mysql-test/suite/innodb/r/innodb_bug14676111.result @@ -1,4 +1,6 @@ drop table if exists t1; +call mtr.add_suppression("option 'innodb-purge-threads': unsigned value 0 adjusted to*"); +set global innodb_stats_persistent = false; CREATE TABLE t1 (a int not null primary key) engine=InnoDB; set global innodb_limit_optimistic_insert_debug = 2; insert into t1 values (1); @@ -9,45 +11,55 @@ insert into t1 values (2); analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; -DATA_LENGTH / 16384 -10.0000 +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; +CLUST_INDEX_SIZE +10 delete from t1 where a=4; +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; -DATA_LENGTH / 16384 -8.0000 +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; +CLUST_INDEX_SIZE +8 delete from t1 where a=5; +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; -DATA_LENGTH / 16384 -5.0000 -set global innodb_limit_optimistic_insert_debug = 10000; +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; +CLUST_INDEX_SIZE +5 +set global innodb_limit_optimistic_insert_debug = 0; delete from t1 where a=2; +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; -DATA_LENGTH / 16384 -3.0000 +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; +CLUST_INDEX_SIZE +3 insert into t1 values (2); delete from t1 where a=2; +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; -DATA_LENGTH / 16384 -2.0000 +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; +CLUST_INDEX_SIZE +2 insert into t1 values (2); delete from t1 where a=2; +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; -DATA_LENGTH / 16384 -1.0000 +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; +CLUST_INDEX_SIZE +1 drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_bug14676111.opt b/mysql-test/suite/innodb/t/innodb_bug14676111.opt new file mode 100644 index 00000000000..77945d1e4bb --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14676111.opt @@ -0,0 +1 @@ +--innodb-sys-tablestats=1 \ No newline at end of file diff --git a/mysql-test/suite/innodb/t/innodb_bug14676111.test b/mysql-test/suite/innodb/t/innodb_bug14676111.test index 41862b8105e..ba04d421fde 100644 --- a/mysql-test/suite/innodb/t/innodb_bug14676111.test +++ b/mysql-test/suite/innodb/t/innodb_bug14676111.test @@ -3,11 +3,6 @@ -- source include/have_innodb.inc -- source include/have_debug.inc -# Note that this test needs to be able to manipulate how/when purge is done -# using @@innodb_limit_optimistic_insert_debug. This does not work with -# background purge threads, so we disabled them in the -master.opt (they are -# off by default in normal 5.5 innodb but on by default in xtradb) - if (`select count(*)=0 from information_schema.global_variables where variable_name = 'INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG'`) { --skip Test requires InnoDB built with UNIV_DEBUG definition. @@ -15,16 +10,20 @@ if (`select count(*)=0 from information_schema.global_variables where variable_n --disable_query_log set @old_innodb_limit_optimistic_insert_debug = @@innodb_limit_optimistic_insert_debug; +set @old_innodb_stats_persistent = @@innodb_stats_persistent; +set @old_innodb_undo_logs = @@innodb_undo_logs; +# Limit undo segments for stable progress of purge. +set global innodb_undo_logs = 1; --enable_query_log --disable_warnings drop table if exists t1; --enable_warnings -CREATE TABLE t1 (a int not null primary key) engine=InnoDB; +call mtr.add_suppression("option 'innodb-purge-threads': unsigned value 0 adjusted to*"); -let $wait_condition= - SELECT VARIABLE_VALUE < 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS - WHERE VARIABLE_NAME = 'INNODB_PURGE_TRX_ID_AGE'; +set global innodb_stats_persistent = false; + +CREATE TABLE t1 (a int not null primary key) engine=InnoDB; # # make 4 leveled straight tree @@ -55,10 +54,12 @@ insert into t1 values (2); #(1, 2) (3) (4) (5) analyze table t1; -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; delete from t1 where a=4; ---source include/wait_condition.inc +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; +--source include/wait_innodb_all_purged.inc #deleting 1 record of 2 records don't cause merge artificially. #current tree form # (1, 5) @@ -67,10 +68,12 @@ delete from t1 where a=4; #(1, 2) (3) (5) analyze table t1; -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; delete from t1 where a=5; ---source include/wait_condition.inc +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; +--source include/wait_innodb_all_purged.inc #deleting 1 record of 2 records don't cause merge artificially. #current tree form # (1) @@ -79,16 +82,18 @@ delete from t1 where a=5; #(1, 2) (3) <- merged next analyze table t1; -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; # # cause merge at level 0 # #disable the artificial limitation of records in a page -set global innodb_limit_optimistic_insert_debug = 10000; +set global innodb_limit_optimistic_insert_debug = 0; delete from t1 where a=2; ---source include/wait_condition.inc +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; +--source include/wait_innodb_all_purged.inc #merge page occurs. and lift up occurs. #current tree form # (1) @@ -96,7 +101,7 @@ delete from t1 where a=2; # (1, 3) analyze table t1; -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; insert into t1 values (2); #current tree form @@ -105,13 +110,15 @@ insert into t1 values (2); # (1, 2, 3) delete from t1 where a=2; ---source include/wait_condition.inc +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; +--source include/wait_innodb_all_purged.inc #current tree form # (1) # (1, 3) analyze table t1; -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; insert into t1 values (2); #current tree form @@ -119,15 +126,19 @@ insert into t1 values (2); # (1, 2, 3) <- lift up this level next, because the father is root delete from t1 where a=2; ---source include/wait_condition.inc +set global innodb_purge_stop_now=ON; +set global innodb_purge_run_now=ON; +--source include/wait_innodb_all_purged.inc #current tree form # (1, 3) analyze table t1; -select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +select CLUST_INDEX_SIZE from information_schema.INNODB_SYS_TABLESTATS where NAME = 'test/t1'; drop table t1; --disable_query_log set global innodb_limit_optimistic_insert_debug = @old_innodb_limit_optimistic_insert_debug; +set global innodb_stats_persistent = @old_innodb_stats_persistent; +set global innodb_undo_logs = @old_innodb_undo_logs; --enable_query_log