Commit b2a5e0f2 authored by Marko Mäkelä's avatar Marko Mäkelä

Make innodb.innodb_defrag_stats more deterministic

Let us mask the actual values of the defragmentation-related fields,
because they may vary. Also, remove the dependency on purge,
and instead delete records by a ROLLBACK of INSERT.
parent 3690c549
...@@ -8,77 +8,65 @@ SET GLOBAL innodb_defragment_stats_accuracy = 20; ...@@ -8,77 +8,65 @@ SET GLOBAL innodb_defragment_stats_accuracy = 20;
DELETE FROM mysql.innodb_index_stats; DELETE FROM mysql.innodb_index_stats;
--echo # Create table. --echo # Create table.
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB; CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256),
KEY SECOND(a, b)) ENGINE=INNODB STATS_PERSISTENT=0;
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024; INSERT INTO t1 SELECT 100*FLOOR(seq/70)+seq%70, REPEAT('A', 256)
FROM seq_1_to_1024;
--echo # Not enough page splits to trigger persistent stats write yet. --echo # Not enough page splits to trigger persistent stats write yet.
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split'); SELECT * FROM mysql.innodb_index_stats;
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
--echo # Persistent stats recorded. INSERT INTO t1 SELECT 100*FLOOR(seq/70)+seq%70, REPEAT('A', 256)
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split'); FROM seq_1025_to_1433;
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
--echo # Delete some rows.
BEGIN; BEGIN;
let $num_delete = 20; let $num_delete = 20;
while ($num_delete) while ($num_delete)
{ {
let $j = 100 * $num_delete; eval INSERT INTO t1 SELECT 100*$num_delete+seq, REPEAT('A', 256)
eval delete from t1 where a between $j and $j + 30; FROM seq_70_to_99;
dec $num_delete; dec $num_delete;
} }
COMMIT; ROLLBACK;
SELECT @@GLOBAL.innodb_force_recovery<2 "have background defragmentation";
# Wait for defrag_pool to be processed.
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split'); let $wait_timeout=30;
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed'); let $wait_condition = SELECT COUNT(*)>0 FROM mysql.innodb_index_stats;
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag'); --source include/wait_condition.inc
--sorted_result
SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
optimize table t1; optimize table t1;
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split'); --sorted_result
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed'); SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
set global innodb_defragment_stats_accuracy = 40; set global innodb_defragment_stats_accuracy = 40;
INSERT INTO t1 (b) SELECT b from t1; INSERT INTO t1 (b) SELECT b from t1;
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split'); --sorted_result
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed'); SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
INSERT INTO t1 (b) SELECT b from t1; INSERT INTO t1 (b) SELECT b from t1;
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split'); --sorted_result
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed'); SELECT stat_name FROM mysql.innodb_index_stats WHERE table_name='t1';
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
--echo # Table rename should cause stats rename. --echo # Table rename should cause stats rename.
rename table t1 to t2; rename table t1 to t2;
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split'); --sorted_result
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed'); SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
--echo # Drop index should cause stats drop, but will not. --echo # Drop index should cause stats drop, but will not.
drop index SECOND on t2; drop index SECOND on t2;
--sorted_result
SELECT stat_name, stat_value>0 FROM mysql.innodb_index_stats
WHERE table_name like '%t2%' AND index_name='SECOND';
--echo # --echo #
--echo # MDEV-26636: Statistics must not be written for temporary tables --echo # MDEV-26636: Statistics must not be written for temporary tables
--echo # --echo #
...@@ -89,13 +77,13 @@ INSERT INTO t SELECT seq, '' FROM seq_1_to_100; ...@@ -89,13 +77,13 @@ INSERT INTO t SELECT seq, '' FROM seq_1_to_100;
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
SELECT * FROM mysql.innodb_index_stats where table_name like '%t1%';
--sorted_result --sorted_result
SELECT table_name, index_name, stat_name, stat_value>0 SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
FROM mysql.innodb_index_stats;
--echo # Clean up --echo # Clean up
# Starting with 10.6, DROP TABLE will not touch persistent statistics
# (not defragmentation statistics either) if the table has none!
ALTER TABLE t2 STATS_PERSISTENT=1;
DROP TABLE t2; DROP TABLE t2;
SELECT * FROM mysql.innodb_index_stats; SELECT * FROM mysql.innodb_index_stats;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment