From dcb0bd59cedbd2e8fa4220986863549d614fb05e Mon Sep 17 00:00:00 2001 From: Krunal Bauskar Date: Thu, 14 May 2020 15:05:36 +0800 Subject: [PATCH 1/4] MDEV-22544: Inconsistent and Incorrect rw-lock stats - There are multiple inconsistency and incorrect way in which rw-lock stats are calculated. - shared rw-lock stats: "rounds" counter is incremented only once for N rounds done in spin-cycle. - all rw-lock stats: If the spin-cycle is short-circuited then attempts are re-counted. [If spin-cycle is interrupted, before it completes srv_n_spin_wait_rounds (default 30) rounds, spin_count is incremented to consider this. If thread resumes spin-cycle (due to unavailability of the locks) and is again interrupted or completed, spin_count is again incremented with the total count, failing to adjust the previous attempt increment]. - s/x rw-lock stats: spin_loop counter is not incremented at-all instead it is projected as 0 (in show engine output) and division to calculate spin-round per spin-loop is adjusted. As per the original semantics spin_loop counter should be incremented once per spin_loop execution. - sx rw-lock stats: sx locks increments spin_loop counter but instead of incrementing it once for a spin_loop invocation it does it multiple times based on how many time spin_loop flow is repeated for same instance post os-wait. --- storage/innobase/sync/sync0rw.cc | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index df710a53cf6..b46126bde58 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -293,10 +293,13 @@ rw_lock_s_lock_spin( ut_ad(rw_lock_validate(lock)); + rw_lock_stats.rw_s_spin_wait_count.inc(); + lock_loop: /* Spin waiting for the writer field to become free */ HMT_low(); + ulint j = i; while (i < srv_n_spin_wait_rounds && lock->lock_word <= 0) { ut_delay(srv_spin_wait_delay); i++; @@ -307,7 +310,7 @@ lock_loop: os_thread_yield(); } - ++spin_count; + spin_count += lint(i - j); /* We try once again to obtain the lock */ if (rw_lock_s_lock_low(lock, pass, file_name, line)) { @@ -428,7 +431,7 @@ rw_lock_x_lock_wait_func( HMT_medium(); /* If there is still a reader, then go to sleep.*/ - ++n_spins; + n_spins += i; sync_cell_t* cell; @@ -654,6 +657,12 @@ rw_lock_x_lock_func( ut_ad(rw_lock_validate(lock)); ut_ad(!rw_lock_own(lock, RW_LOCK_S)); + if (rw_lock_x_lock_low(lock, pass, file_name, line)) { + /* Locking succeeded */ + return; + } + rw_lock_stats.rw_x_spin_wait_count.inc(); + lock_loop: if (rw_lock_x_lock_low(lock, pass, file_name, line)) { @@ -673,6 +682,7 @@ lock_loop: /* Spin waiting for the lock_word to become free */ HMT_low(); + ulint j = i; while (i < srv_n_spin_wait_rounds && lock->lock_word <= X_LOCK_HALF_DECR) { @@ -681,7 +691,7 @@ lock_loop: } HMT_medium(); - spin_count += i; + spin_count += lint(i - j); if (i >= srv_n_spin_wait_rounds) { @@ -749,11 +759,17 @@ rw_lock_sx_lock_func( sync_array_t* sync_arr; ulint spin_count = 0; uint64_t count_os_wait = 0; - ulint spin_wait_count = 0; ut_ad(rw_lock_validate(lock)); ut_ad(!rw_lock_own(lock, RW_LOCK_S)); + if (rw_lock_sx_lock_low(lock, pass, file_name, line)) { + /* Locking succeeded */ + return; + } + + rw_lock_stats.rw_sx_spin_wait_count.inc(); + lock_loop: if (rw_lock_sx_lock_low(lock, pass, file_name, line)) { @@ -765,16 +781,14 @@ lock_loop: } rw_lock_stats.rw_sx_spin_round_count.add(spin_count); - rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count); /* Locking succeeded */ return; } else { - ++spin_wait_count; - /* Spin waiting for the lock_word to become free */ + ulint j = i; while (i < srv_n_spin_wait_rounds && lock->lock_word <= X_LOCK_HALF_DECR) { @@ -782,7 +796,7 @@ lock_loop: i++; } - spin_count += i; + spin_count += lint(i - j); if (i >= srv_n_spin_wait_rounds) { @@ -814,7 +828,6 @@ lock_loop: } rw_lock_stats.rw_sx_spin_round_count.add(spin_count); - rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count); /* Locking succeeded */ return; From efd68f5e3184c54e04045a1350a1ff37dc313348 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Mon, 11 May 2020 19:56:14 +0530 Subject: [PATCH 2/4] MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT For the case when the optimizer does the IN-EXISTS transformation, the equality condition is injected in the WHERE OR HAVING clause of the subquery. If the select list of the subquery has a reference to the parent select make sure to use the reference and not the original item. --- mysql-test/r/subselect4.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/subselect4.test | 24 ++++++++++++++++++++++++ sql/item_subselect.cc | 9 ++++++--- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index a7e2bd9d1b5..863105b24b6 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2534,3 +2534,35 @@ x c1 1 drop table t1; +# +# MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT +# +set @save_sql_select_limit= @@sql_select_limit; +SET sql_select_limit=0; +CREATE TABLE t1(b INT, c INT); +CREATE TABLE t2(a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Zero limit +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having (`test`.`t2`.`a`,(select `test`.`t2`.`b` from `test`.`t1` where ((`test`.`t2`.`a`) = `test`.`t2`.`b`))) +SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +sum(a) a b +SET @@sql_select_limit= @save_sql_select_limit; +EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having <`test`.`t2`.`a`,`test`.`t2`.`b`>((`test`.`t2`.`a`,(select `test`.`t2`.`b` from `test`.`t1` where ((`test`.`t2`.`a`) = `test`.`t2`.`b`)))) +SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); +sum(a) a b +6 1 1 +DROP TABLE t1,t2; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index d5a40419185..f0b1d16be7b 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -2075,3 +2075,27 @@ insert into t1 values(2,1),(1,2); select (select c1 from t1 group by c1,c2 order by c1 limit 1) as x; (select c1 from t1 group by c1,c2 order by c1 limit 1); drop table t1; + +--echo # +--echo # MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT +--echo # + +set @save_sql_select_limit= @@sql_select_limit; +SET sql_select_limit=0; + +CREATE TABLE t1(b INT, c INT); +CREATE TABLE t2(a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); + +let $query= +SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1); + +eval EXPLAIN EXTENDED $query; +eval $query; + +SET @@sql_select_limit= @save_sql_select_limit; + +eval EXPLAIN EXTENDED $query; +eval $query; +DROP TABLE t1,t2; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index e3cb82df170..16ef8a192c5 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2135,10 +2135,13 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, } else { + /* + No need to use real_item for the item, as the ref items that are possible + in the subquery either belong to views or to the parent select. + For such case we need to refer to the reference and not to the original + item. + */ Item *item= (Item*) select_lex->item_list.head(); - if (item->type() != REF_ITEM || - ((Item_ref*)item)->ref_type() != Item_ref::VIEW_REF) - item= item->real_item(); if (select_lex->table_list.elements) { From 3f12a5968a56cb5030381a78b313fdb36024c7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 15 May 2020 22:54:05 +0300 Subject: [PATCH 3/4] MDEV-13626: Make test more robust In commit b1742a5c951633213d756600ee73ba7bfa7800ff we forgot FLUSH TABLES, potentially causing errors for MyISAM system tables. --- mysql-test/suite/innodb/t/xa_recovery_debug.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/suite/innodb/t/xa_recovery_debug.test b/mysql-test/suite/innodb/t/xa_recovery_debug.test index 21a38854adb..ada2940ed9c 100644 --- a/mysql-test/suite/innodb/t/xa_recovery_debug.test +++ b/mysql-test/suite/innodb/t/xa_recovery_debug.test @@ -4,6 +4,10 @@ # Embedded server does not support restarting --source include/not_embedded.inc +--disable_query_log +FLUSH TABLES; +--enable_query_log + --echo # --echo # Bug#20872655 XA ROLLBACK IS NOT CRASH-SAFE --echo # From 85651269b6186b53bae804413c76f4117fa225d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 16 May 2020 06:24:09 +0300 Subject: [PATCH 4/4] MDEV-18100: Clean up test --- mysql-test/main/custom_aggregate_functions.result | 2 ++ mysql-test/main/custom_aggregate_functions.test | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/mysql-test/main/custom_aggregate_functions.result b/mysql-test/main/custom_aggregate_functions.result index 8ad7b4b4dc0..0e73f963b45 100644 --- a/mysql-test/main/custom_aggregate_functions.result +++ b/mysql-test/main/custom_aggregate_functions.result @@ -1186,3 +1186,5 @@ common_schema.sum_ints(seq) 3 drop database common_schema; drop database another_schema; +USE test; +# End of 10.3 tests diff --git a/mysql-test/main/custom_aggregate_functions.test b/mysql-test/main/custom_aggregate_functions.test index 4d9dd0a4929..7442c7ec2ee 100644 --- a/mysql-test/main/custom_aggregate_functions.test +++ b/mysql-test/main/custom_aggregate_functions.test @@ -998,3 +998,7 @@ SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t; drop database common_schema; drop database another_schema; + +USE test; + +--echo # End of 10.3 tests