mirror of
https://github.com/MariaDB/server.git
synced 2025-08-26 01:44:06 +03:00
PROBLEM By design stats estimation always reading uncommitted data. In this scenario an uncommitted transaction has deleted all rows in the table. In Innodb uncommitted delete records are marked as delete but not actually removed from Btree until the transaction has committed or a read view for the rows is present.While calculating persistent stats we were ignoring the delete marked records,since all the records are delete marked we were estimating the number of rows present in the table as zero which leads to bad plans in other transaction operating on the table. Fix Introduced a system variable called innodb_stats_include_delete_marked which when enabled includes delete marked records for stat calculations .
114 lines
3.7 KiB
Plaintext
114 lines
3.7 KiB
Plaintext
--source include/have_innodb.inc
|
|
--source include/big_test.inc
|
|
|
|
--echo #
|
|
--echo # Bug 23333990 PERSISTENT INDEX STATISTICS UPDATE BEFORE
|
|
--echo # TRANSACTION IS COMMITTED
|
|
--echo #
|
|
|
|
--echo "Test 1:- Uncommited delete test"
|
|
CREATE TABLE t1 (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
val INT UNSIGNED NOT NULL,
|
|
INDEX (val)) ENGINE=INNODB
|
|
STATS_PERSISTENT=1,STATS_AUTO_RECALC=1;
|
|
|
|
|
|
INSERT INTO t1 (val) VALUES (CEIL(RAND()*20));
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
INSERT INTO t1 (val) SELECT CEIL(RAND()*20) FROM t1;
|
|
|
|
SELECT COUNT(*) FROM t1;
|
|
ANALYZE TABLE t1;
|
|
|
|
connect(con1, localhost, root,,);
|
|
START TRANSACTION;
|
|
DELETE FROM t1;
|
|
send SELECT COUNT(*) FROM t1;
|
|
|
|
connection default;
|
|
let $row_count= query_get_value(EXPLAIN SELECT * FROM t1 WHERE val=4, rows,1);
|
|
if ($row_count > 20000)
|
|
{
|
|
--echo Test correctly estimates the number of rows as > 20000
|
|
--echo even when in other uncommmited transaction
|
|
--echo all rows have been deleted.
|
|
}
|
|
|
|
connection con1;
|
|
reap;
|
|
commit;
|
|
|
|
connection default;
|
|
|
|
--echo Test 2:- Insert and rollback test
|
|
CREATE TABLE t2 (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
val INT UNSIGNED NOT NULL,
|
|
INDEX (val)) ENGINE=INNODB
|
|
STATS_PERSISTENT=1,STATS_AUTO_RECALC=1;
|
|
|
|
connection con1;
|
|
|
|
START TRANSACTION;
|
|
INSERT INTO t2 (val) VALUES (CEIL(RAND()*20));
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
INSERT INTO t2 (val) SELECT CEIL(RAND()*20) FROM t2;
|
|
send SELECT COUNT(*) FROM t2;
|
|
|
|
connection default;
|
|
select count(*) from t2;
|
|
let $row_count= query_get_value(EXPLAIN SELECT * FROM t2 WHERE val=4, rows,1);
|
|
if ($row_count > 20000)
|
|
{
|
|
--echo Test correctly estimates the number of rows as > 20000
|
|
--echo even when in other uncommited transaction
|
|
--echo many rows are inserted.
|
|
}
|
|
|
|
connection con1;
|
|
reap;
|
|
--echo Rollback the insert
|
|
rollback;
|
|
disconnect con1;
|
|
|
|
connection default;
|
|
let $row_count= query_get_value(EXPLAIN SELECT * FROM t2 WHERE val=4, rows,1);
|
|
if ($row_count <= 1)
|
|
{
|
|
--echo Test correctly estimates the number of rows as $row_count
|
|
--echo after rollback.
|
|
}
|
|
|
|
DROP TABLE t1,t2;
|