SET @saved_include_delete_marked = @@GLOBAL.innodb_stats_include_delete_marked; SET GLOBAL innodb_stats_include_delete_marked = ON; SET @saved_traditional = @@GLOBAL.innodb_stats_traditional; SET GLOBAL innodb_stats_traditional=false; SET @saved_modified_counter = @@GLOBAL.innodb_stats_modified_counter; SET GLOBAL innodb_stats_modified_counter=1; CREATE TABLE t1 (id SERIAL, val INT UNSIGNED NOT NULL, KEY(val)) 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; Table Op Msg_type Msg_text test.t1 analyze status OK connect con1, localhost, root,,; START TRANSACTION; DELETE FROM t1; SELECT COUNT(*) FROM t1; connection default; # With innodb_stats_include_delete_marked=ON, # DELETE must not affect statistics before COMMIT. EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref val val 4 const 1 Using index connection con1; COUNT(*) 0 ROLLBACK; SELECT COUNT(*) FROM t1; COUNT(*) 16 EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref val val 4 const 16 Using index BEGIN; DELETE FROM t1; COMMIT; SELECT COUNT(*) FROM t1; COUNT(*) 0 connection default; BEGIN; INSERT INTO t2 (val) SELECT 4 FROM seq_1_to_16; # The INSERT will show up before COMMIT. EXPLAIN SELECT * FROM t2 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref val val 4 const 16 Using index SELECT COUNT(*) FROM t2; COUNT(*) 16 # The ROLLBACK of the INSERT must affect the statistics. ROLLBACK; SELECT COUNT(*) FROM t2; COUNT(*) 0 connection con1; EXPLAIN SELECT * FROM t2 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref val val 4 const 1 Using index SET GLOBAL innodb_max_purge_lag_wait=0; # After COMMIT and purge, the DELETE must show up. EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref val val 4 const 1 Using index SET GLOBAL innodb_stats_include_delete_marked = OFF; BEGIN; INSERT INTO t1 (val) SELECT 4 FROM seq_1_to_16; EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref val val 4 const 16 Using index ROLLBACK; EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref val val 4 const 1 Using index BEGIN; INSERT INTO t1 (val) SELECT 4 FROM seq_1_to_16; COMMIT; EXPLAIN SELECT * FROM t1 WHERE val=4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref val val 4 const 16 Using index BEGIN; DELETE FROM t1; SELECT COUNT(*) FROM t1; COUNT(*) 0 # With innodb_stats_include_delete_marked=OFF, # DELETE must affect statistics even before COMMIT. # However, if there was a WHERE condition, # ha_innobase::records_in_range() would count the delete-marked records. EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL val 4 NULL 1 Using index ROLLBACK; EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL val 4 NULL 16 Using index SELECT COUNT(*) FROM t1; COUNT(*) 16 disconnect con1; connection default; 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; 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; Table Op Msg_type Msg_text test.bug12429573 analyze status OK 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; database_name table_name index_name last_update stat_name stat_value sample_size stat_description SET STATEMENT use_stat_tables=never FOR ANALYZE TABLE bug12429573; Table Op Msg_type Msg_text test.bug12429573 analyze status OK SELECT * FROM mysql.innodb_table_stats WHERE table_name = 'bug12429573' AND last_update=@last; database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes SELECT * FROM mysql.innodb_index_stats WHERE table_name = 'bug12429573' AND last_update=@last; database_name table_name index_name last_update stat_name stat_value sample_size stat_description DROP TABLE bug12429573;