Skip to content

Commit c073ec5

Browse files
Merge branch 'bug1625151-5.6' into bug1625151-5.7
2 parents 4084f07 + 35afd73 commit c073ec5

8 files changed

Lines changed: 136 additions & 6 deletions

File tree

‎mysql-test/include/index_merge1.inc‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,10 @@ alter table t3 add keyB int not null, add index iB(keyB);
455455
alter table t3 add keyC int not null, add index iC(keyC);
456456
update t3 set key9=key1,keyA=key1,keyB=key1,keyC=key1;
457457

458+
# Force complete purge
459+
SET @@GLOBAL.innodb_fast_shutdown = 0;
460+
--source include/restart_mysqld.inc
461+
458462
-- disable_query_log
459463
-- disable_result_log
460464
analyze table t3;

‎mysql-test/include/index_merge2.inc‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ alter table t1 add index i2(key2);
372372
alter table t1 add index i3(key3);
373373
update t1 set key2=key1,key3=key1;
374374

375+
# Force complete purge
376+
SET @@GLOBAL.innodb_fast_shutdown = 0;
377+
--source include/restart_mysqld.inc
378+
375379
-- disable_query_log
376380
-- disable_result_log
377381
analyze table t1;

‎mysql-test/include/index_merge_ror.inc‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=1
184184

185185
delete from t1 where key3=100 and key4=100;
186186

187+
# Force complete purge
188+
SET @@GLOBAL.innodb_fast_shutdown = 0;
189+
--source include/restart_mysqld.inc
190+
187191
-- disable_query_log
188192
-- disable_result_log
189193
analyze table t1;

‎mysql-test/r/index_merge_innodb.result‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,8 @@ alter table t3 add keyA int not null, add index iA(keyA);
420420
alter table t3 add keyB int not null, add index iB(keyB);
421421
alter table t3 add keyC int not null, add index iC(keyC);
422422
update t3 set key9=key1,keyA=key1,keyB=key1,keyC=key1;
423+
SET @@GLOBAL.innodb_fast_shutdown = 0;
424+
# restart
423425
explain select * from t3 where
424426
key1=1 or key2=2 or key3=3 or key4=4 or
425427
key5=5 or key6=6 or key7=7 or key8=8 or
@@ -917,6 +919,8 @@ select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=1
917919
key1 key2 key3 key4 filler1
918920
-1 -1 100 100 key4-key3
919921
delete from t1 where key3=100 and key4=100;
922+
SET @@GLOBAL.innodb_fast_shutdown = 0;
923+
# restart
920924
# ROR-union with all ROR-intersections giving empty results
921925
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
922926
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
@@ -1422,6 +1426,8 @@ set @d=@d*2;
14221426
alter table t1 add index i2(key2);
14231427
alter table t1 add index i3(key3);
14241428
update t1 set key2=key1,key3=key1;
1429+
SET @@GLOBAL.innodb_fast_shutdown = 0;
1430+
# restart
14251431
explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40);
14261432
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
14271433
1 SIMPLE t1 NULL index_merge i2,i3 i3,i2 4,4 NULL # 100.00 Using sort_union(i3,i2); Using where

‎mysql-test/r/index_merge_myisam.result‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@ alter table t3 add keyA int not null, add index iA(keyA);
428428
alter table t3 add keyB int not null, add index iB(keyB);
429429
alter table t3 add keyC int not null, add index iC(keyC);
430430
update t3 set key9=key1,keyA=key1,keyB=key1,keyC=key1;
431+
SET @@GLOBAL.innodb_fast_shutdown = 0;
432+
# restart
431433
explain select * from t3 where
432434
key1=1 or key2=2 or key3=3 or key4=4 or
433435
key5=5 or key6=6 or key7=7 or key8=8 or
@@ -959,6 +961,8 @@ select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=1
959961
key1 key2 key3 key4 filler1
960962
-1 -1 100 100 key4-key3
961963
delete from t1 where key3=100 and key4=100;
964+
SET @@GLOBAL.innodb_fast_shutdown = 0;
965+
# restart
962966
# ROR-union with all ROR-intersections giving empty results
963967
explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
964968
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
@@ -1479,6 +1483,8 @@ set @d=@d*2;
14791483
alter table t1 add index i2(key2);
14801484
alter table t1 add index i3(key3);
14811485
update t1 set key2=key1,key3=key1;
1486+
SET @@GLOBAL.innodb_fast_shutdown = 0;
1487+
# restart
14821488
explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40);
14831489
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
14841490
1 SIMPLE t1 NULL index_merge i2,i3 i3,i2 4,4 NULL 11 100.00 Using sort_union(i3,i2); Using where
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#
2+
# Bug 84366: InnoDB index dives do not detect concurrent tree changes, return
3+
# bogus estimates
4+
#
5+
CREATE TABLE t1 (key1 INT NOT NULL, key2 INT NOT NULL,
6+
INDEX i1(key1), INDEX i2(key2)) ENGINE = InnoDB;
7+
SET @@GLOBAL.innodb_purge_stop_now = TRUE;
8+
ALTER TABLE t1 ADD keyC INT NOT NULL, ADD INDEX iC(keyC);
9+
UPDATE t1 SET keyC = key1;
10+
ANALYZE TABLE t1;
11+
Table Op Msg_type Msg_text
12+
test.t1 analyze status OK
13+
EXPLAIN SELECT * FROM t1 WHERE key1 = 1 OR key2 = 2 OR keyC = 12;
14+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
15+
1 SIMPLE t1 NULL index_merge i1,i2,iC i1,i2,iC 4,4,4 NULL 3 100.00 Using union(i1,i2,iC); Using where
16+
Warnings:
17+
Note 1003 /* select#1 */ select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`keyC` AS `keyC` from `test`.`t1` where ((`test`.`t1`.`key1` = 1) or (`test`.`t1`.`key2` = 2) or (`test`.`t1`.`keyC` = 12))
18+
SET DEBUG_SYNC = "btr_estimate_n_rows_in_range_between_dives SIGNAL estimate_ready WAIT_FOR estimate_finish";
19+
EXPLAIN SELECT * FROM t1 WHERE key1 = 1 OR key2 = 2 OR keyC = 12;
20+
SET DEBUG_SYNC = "now WAIT_FOR estimate_ready";
21+
SET @@GLOBAL.innodb_purge_run_now = TRUE;
22+
SET DEBUG_SYNC = "now SIGNAL estimate_finish";
23+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
24+
1 SIMPLE t1 NULL index_merge i1,i2,iC i1,i2,iC 4,4,4 NULL 3 100.00 Using union(i1,i2,iC); Using where
25+
Warnings:
26+
Note 1003 /* select#1 */ select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`keyC` AS `keyC` from `test`.`t1` where ((`test`.`t1`.`key1` = 1) or (`test`.`t1`.`key2` = 2) or (`test`.`t1`.`keyC` = 12))
27+
EXPLAIN SELECT * FROM t1 WHERE key1=1 or key2=2 or keyC=12;
28+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
29+
1 SIMPLE t1 NULL index_merge i1,i2,iC i1,i2,iC 4,4,4 NULL 3 100.00 Using union(i1,i2,iC); Using where
30+
Warnings:
31+
Note 1003 /* select#1 */ select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`keyC` AS `keyC` from `test`.`t1` where ((`test`.`t1`.`key1` = 1) or (`test`.`t1`.`key2` = 2) or (`test`.`t1`.`keyC` = 12))
32+
DROP TABLE t1;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
--source include/have_debug.inc
2+
--source include/have_debug_sync.inc
3+
--source include/have_innodb.inc
4+
5+
--echo #
6+
--echo # Bug 84366: InnoDB index dives do not detect concurrent tree changes, return
7+
--echo # bogus estimates
8+
--echo #
9+
10+
--source include/count_sessions.inc
11+
12+
CREATE TABLE t1 (key1 INT NOT NULL, key2 INT NOT NULL,
13+
INDEX i1(key1), INDEX i2(key2)) ENGINE = InnoDB;
14+
15+
--disable_query_log
16+
INSERT INTO t1 VALUES (1, 1), (2, 2);
17+
18+
let $1=9;
19+
SET @d=2;
20+
while ($1)
21+
{
22+
INSERT INTO t1 SELECT key1 + @d, key2 + @d FROM t1;
23+
SET @d=@d*2;
24+
dec $1;
25+
}
26+
--enable_query_log
27+
28+
SET @@GLOBAL.innodb_purge_stop_now = TRUE;
29+
30+
ALTER TABLE t1 ADD keyC INT NOT NULL, ADD INDEX iC(keyC);
31+
UPDATE t1 SET keyC = key1;
32+
33+
ANALYZE TABLE t1;
34+
35+
--connect(con1,localhost,root,,)
36+
37+
EXPLAIN SELECT * FROM t1 WHERE key1 = 1 OR key2 = 2 OR keyC = 12;
38+
39+
SET DEBUG_SYNC = "btr_estimate_n_rows_in_range_between_dives SIGNAL estimate_ready WAIT_FOR estimate_finish";
40+
41+
send EXPLAIN SELECT * FROM t1 WHERE key1 = 1 OR key2 = 2 OR keyC = 12;
42+
43+
connection default;
44+
SET DEBUG_SYNC = "now WAIT_FOR estimate_ready";
45+
46+
SET @@GLOBAL.innodb_purge_run_now = TRUE;
47+
48+
# wait_innodb_all_purged.inc is not used directly as we wait for the trx age
49+
# to become one, not zero, due to one open transaction
50+
--let $status_var= innodb_purge_trx_id_age
51+
--let $status_var_value= 1
52+
--source include/wait_for_status_var.inc
53+
54+
SET DEBUG_SYNC = "now SIGNAL estimate_finish";
55+
56+
connection con1;
57+
reap;
58+
59+
EXPLAIN SELECT * FROM t1 WHERE key1=1 or key2=2 or keyC=12;
60+
61+
disconnect con1;
62+
connection default;
63+
64+
DROP TABLE t1;
65+
66+
--source include/wait_until_count_sessions.inc

‎storage/innobase/btr/btr0cur.cc‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5769,6 +5769,12 @@ btr_estimate_n_rows_in_range_low(
57695769

57705770
mtr_commit(&mtr);
57715771

5772+
#ifdef UNIV_DEBUG
5773+
if (!strcmp(index->name, "iC")) {
5774+
DEBUG_SYNC_C("btr_estimate_n_rows_in_range_between_dives");
5775+
}
5776+
#endif
5777+
57725778
mtr_start(&mtr);
57735779

57745780
cursor.path_arr = path2;
@@ -5945,12 +5951,16 @@ btr_estimate_n_rows_in_range_low(
59455951

59465952
if (!diverged && slot1->nth_rec != slot2->nth_rec) {
59475953

5948-
/* If both slots do not point to the same page,
5954+
/* If both slots do not point to the same page or if
5955+
the paths have crossed and the same page on both
5956+
apparently contains a different number of records,
59495957
this means that the tree must have changed between
59505958
the dive for slot1 and the dive for slot2 at the
59515959
beginning of this function. */
59525960
if (slot1->page_no != slot2->page_no
5953-
|| slot1->page_level != slot2->page_level) {
5961+
|| slot1->page_level != slot2->page_level
5962+
|| (slot1->nth_rec >= slot2->nth_rec
5963+
&& slot1->n_recs != slot2->n_recs)) {
59545964

59555965
/* If the tree keeps changing even after a
59565966
few attempts, then just return some arbitrary
@@ -5991,10 +6001,8 @@ btr_estimate_n_rows_in_range_low(
59916001
and we select where x > 20 and x < 30;
59926002
in this case slot1->nth_rec will point
59936003
to the supr record and slot2->nth_rec
5994-
will point to 6. */
5995-
n_rows = 0;
5996-
should_count_the_left_border = false;
5997-
should_count_the_right_border = false;
6004+
will point to 6 */
6005+
return(0);
59986006
}
59996007

60006008
} else if (diverged && !diverged_lot) {

0 commit comments

Comments
 (0)