lists.mariadb.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

commits

Thread Start a new thread
Threads by month
  • ----- 2025 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
commits@lists.mariadb.org

  • 14605 discussions
[Commits] bba46cb393e: MDEV-19632: Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
by sujatha 16 Aug '19

16 Aug '19
revision-id: bba46cb393edc36fc5e5a783402cce8bc7b2a15b (mariadb-10.3.17-33-gbba46cb393e) parent(s): 130d9490c844d82a7a8613c343a1969c0bec4c62 author: Sujatha committer: Sujatha timestamp: 2019-08-16 12:58:33 +0530 message: MDEV-19632: Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode Analysis and Fix: ================= When SQL_MODE=ORACLE the 'BLOB' type gets translated to 'LONGBLOB'. Because of this change replicated CREATE ... SELECT statement fails on slave in row based replication. The reason being, the source field type is 'BLOB' and destination field type is 'LONGBLOB'. The BLOB type translation issue was fixed as part of MDEV-20263. At present MDEV-19632 adds a replication specific test case to prove replication works fine. --- .../suite/rpl/r/rpl_row_blob_oracle_mode.result | 10 ++++++ .../suite/rpl/t/rpl_row_blob_oracle_mode.test | 36 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/mysql-test/suite/rpl/r/rpl_row_blob_oracle_mode.result b/mysql-test/suite/rpl/r/rpl_row_blob_oracle_mode.result new file mode 100644 index 00000000000..1c697825002 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_blob_oracle_mode.result @@ -0,0 +1,10 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1 (a BLOB); +INSERT INTO t1 VALUES (0); +SET SQL_MODE= 'ORACLE'; +CREATE TABLE t2 SELECT * FROM t1; +connection slave; +connection master; +DROP TABLE t1, t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_blob_oracle_mode.test b/mysql-test/suite/rpl/t/rpl_row_blob_oracle_mode.test new file mode 100644 index 00000000000..f002b99f639 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_blob_oracle_mode.test @@ -0,0 +1,36 @@ +# ==== Purpose ==== +# +# Test verifies that fields of type 'BLOB' are replicated properly in row based +# replication, when SQL_MODE= ORACLE. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create a table which contains a field of type 'BLOB'. +# 1 - Insert some data into the table. +# 2 - Set SQL_MODE to 'ORACLE'. +# 3 - Execute a CREATE ... SELECT statement to create a new table. +# 4 - Verify that slave is in sync with master. No type conversion errors +# should be reported. +# +# ==== References ==== +# +# MDEV-20263: sql_mode=ORACLE: BLOB(65535) should not translate to LONGBLOB +# MDEV-19632: Replication aborts with ER_SLAVE_CONVERSION_FAILED upon +# CREATE ... SELECT in ORACLE mode +# + +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +CREATE TABLE t1 (a BLOB); +INSERT INTO t1 VALUES (0); + +SET SQL_MODE= 'ORACLE'; +CREATE TABLE t2 SELECT * FROM t1; +--sync_slave_with_master + +# Cleanup +--connection master +DROP TABLE t1, t2; +--source include/rpl_end.inc
1 0
0 0
[Commits] 41a6b8c: MDEV-20265 Unknown column in field list
by IgorBabaev 16 Aug '19

16 Aug '19
revision-id: 41a6b8c8e2168eda7efe72f9e90d14d85162281d (mariadb-5.5.65-5-g41a6b8c) parent(s): 1217e4a0c05eff7a394e46e64dffc849c9edda22 author: Igor Babaev committer: Igor Babaev timestamp: 2019-08-15 17:27:49 -0700 message: MDEV-20265 Unknown column in field list This patch corrects the fix of the patch for mdev-19421 that resolved the problem of parsing some embedded join expressions such as t1 join t2 left join t3 on t2.a=t3.a on t1.a=t2.a. Yet the patch contained a bug that prevented proper context analysis of the queries where such expressions were used together with comma separated table references in from clauses. --- mysql-test/r/join.result | 326 +++++++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/join.test | 59 +++++++++ sql/sql_parse.cc | 103 +++++++++++---- 3 files changed, 460 insertions(+), 28 deletions(-) diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 6b051ac..cb2d006 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -2921,5 +2921,331 @@ NULL NULL NULL 9 NULL NULL NULL 5 drop table t1,t2,t3,t4,s1,s2; # +# MDEV-20265: Mix of comma joins with JOIN expressions +# (correction of the fix for MDEV-19421) +# MDEV-20330: duplicate +# +create table t1 (a int); +insert into t1 values (7), (5), (3); +create table t2 (a int); +insert into t2 values (5), (1), (7); +create table t3 (a int); +insert into t3 values (2), (7), (3); +create table t4 (a int); +insert into t4 values (4), (7), (9), (5); +create table t5 (a int); +insert into t5 values (3), (7), (9), (2); +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 left join t4 on t3.a=t4.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a` from `test`.`t1` join `test`.`t2` join `test`.`t3` left join `test`.`t4` on((`test`.`t4`.`a` = `test`.`t3`.`a`)) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 left join t4 on t3.a=t4.a; +t1_a t2_a t3_a t4_a +7 5 7 7 +5 5 7 7 +3 5 7 7 +7 1 7 7 +5 1 7 7 +3 1 7 7 +7 7 7 7 +5 7 7 7 +3 7 7 7 +7 5 2 NULL +5 5 2 NULL +3 5 2 NULL +7 1 2 NULL +5 1 2 NULL +3 1 2 NULL +7 7 2 NULL +5 7 2 NULL +3 7 2 NULL +7 5 3 NULL +5 5 3 NULL +3 5 3 NULL +7 1 3 NULL +5 1 3 NULL +3 1 3 NULL +7 7 3 NULL +5 7 3 NULL +3 7 3 NULL +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 right join t4 on t3.a=t4.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a` from `test`.`t1` join `test`.`t4` left join (`test`.`t2` join `test`.`t3`) on((`test`.`t3`.`a` = `test`.`t4`.`a`)) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 right join t4 on t3.a=t4.a; +t1_a t2_a t3_a t4_a +7 5 7 7 +5 5 7 7 +3 5 7 7 +7 1 7 7 +5 1 7 7 +3 1 7 7 +7 7 7 7 +5 7 7 7 +3 7 7 7 +7 NULL NULL 4 +5 NULL NULL 4 +3 NULL NULL 4 +7 NULL NULL 9 +5 NULL NULL 9 +3 NULL NULL 9 +7 NULL NULL 5 +5 NULL NULL 5 +3 NULL NULL 5 +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` join `test`.`t2` join `test`.`t3` join `test`.`t4` left join `test`.`t5` on((`test`.`t5`.`a` = `test`.`t4`.`a`)) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a; +t1_a t2_a t3_a t4_a t5_a +7 5 2 7 7 +5 5 2 7 7 +3 5 2 7 7 +7 1 2 7 7 +5 1 2 7 7 +3 1 2 7 7 +7 7 2 7 7 +5 7 2 7 7 +3 7 2 7 7 +7 5 7 7 7 +5 5 7 7 7 +3 5 7 7 7 +7 1 7 7 7 +5 1 7 7 7 +3 1 7 7 7 +7 7 7 7 7 +5 7 7 7 7 +3 7 7 7 7 +7 5 3 7 7 +5 5 3 7 7 +3 5 3 7 7 +7 1 3 7 7 +5 1 3 7 7 +3 1 3 7 7 +7 7 3 7 7 +5 7 3 7 7 +3 7 3 7 7 +7 5 2 9 9 +5 5 2 9 9 +3 5 2 9 9 +7 1 2 9 9 +5 1 2 9 9 +3 1 2 9 9 +7 7 2 9 9 +5 7 2 9 9 +3 7 2 9 9 +7 5 7 9 9 +5 5 7 9 9 +3 5 7 9 9 +7 1 7 9 9 +5 1 7 9 9 +3 1 7 9 9 +7 7 7 9 9 +5 7 7 9 9 +3 7 7 9 9 +7 5 3 9 9 +5 5 3 9 9 +3 5 3 9 9 +7 1 3 9 9 +5 1 3 9 9 +3 1 3 9 9 +7 7 3 9 9 +5 7 3 9 9 +3 7 3 9 9 +7 5 2 4 NULL +5 5 2 4 NULL +3 5 2 4 NULL +7 1 2 4 NULL +5 1 2 4 NULL +3 1 2 4 NULL +7 7 2 4 NULL +5 7 2 4 NULL +3 7 2 4 NULL +7 5 7 4 NULL +5 5 7 4 NULL +3 5 7 4 NULL +7 1 7 4 NULL +5 1 7 4 NULL +3 1 7 4 NULL +7 7 7 4 NULL +5 7 7 4 NULL +3 7 7 4 NULL +7 5 3 4 NULL +5 5 3 4 NULL +3 5 3 4 NULL +7 1 3 4 NULL +5 1 3 4 NULL +3 1 3 4 NULL +7 7 3 4 NULL +5 7 3 4 NULL +3 7 3 4 NULL +7 5 2 5 NULL +5 5 2 5 NULL +3 5 2 5 NULL +7 1 2 5 NULL +5 1 2 5 NULL +3 1 2 5 NULL +7 7 2 5 NULL +5 7 2 5 NULL +3 7 2 5 NULL +7 5 7 5 NULL +5 5 7 5 NULL +3 5 7 5 NULL +7 1 7 5 NULL +5 1 7 5 NULL +3 1 7 5 NULL +7 7 7 5 NULL +5 7 7 5 NULL +3 7 7 5 NULL +7 5 3 5 NULL +5 5 3 5 NULL +3 5 3 5 NULL +7 1 3 5 NULL +5 1 3 5 NULL +3 1 3 5 NULL +7 7 3 5 NULL +5 7 3 5 NULL +3 7 3 5 NULL +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` join `test`.`t5` left join (`test`.`t2` join `test`.`t3` join `test`.`t4`) on((`test`.`t4`.`a` = `test`.`t5`.`a`)) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a; +t1_a t2_a t3_a t4_a t5_a +7 5 2 7 7 +5 5 2 7 7 +3 5 2 7 7 +7 1 2 7 7 +5 1 2 7 7 +3 1 2 7 7 +7 7 2 7 7 +5 7 2 7 7 +3 7 2 7 7 +7 5 7 7 7 +5 5 7 7 7 +3 5 7 7 7 +7 1 7 7 7 +5 1 7 7 7 +3 1 7 7 7 +7 7 7 7 7 +5 7 7 7 7 +3 7 7 7 7 +7 5 3 7 7 +5 5 3 7 7 +3 5 3 7 7 +7 1 3 7 7 +5 1 3 7 7 +3 1 3 7 7 +7 7 3 7 7 +5 7 3 7 7 +3 7 3 7 7 +7 5 2 9 9 +5 5 2 9 9 +3 5 2 9 9 +7 1 2 9 9 +5 1 2 9 9 +3 1 2 9 9 +7 7 2 9 9 +5 7 2 9 9 +3 7 2 9 9 +7 5 7 9 9 +5 5 7 9 9 +3 5 7 9 9 +7 1 7 9 9 +5 1 7 9 9 +3 1 7 9 9 +7 7 7 9 9 +5 7 7 9 9 +3 7 7 9 9 +7 5 3 9 9 +5 5 3 9 9 +3 5 3 9 9 +7 1 3 9 9 +5 1 3 9 9 +3 1 3 9 9 +7 7 3 9 9 +5 7 3 9 9 +3 7 3 9 9 +7 NULL NULL NULL 3 +5 NULL NULL NULL 3 +3 NULL NULL NULL 3 +7 NULL NULL NULL 2 +5 NULL NULL NULL 2 +3 NULL NULL NULL 2 +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t1`.`a`)) join `test`.`t5` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`a` = `test`.`t5`.`a`)) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a; +t1_a t2_a t3_a t4_a t5_a +5 5 2 7 7 +7 7 2 7 7 +3 NULL 2 7 7 +5 5 7 7 7 +7 7 7 7 7 +3 NULL 7 7 7 +5 5 3 7 7 +7 7 3 7 7 +3 NULL 3 7 7 +5 5 2 9 9 +7 7 2 9 9 +3 NULL 2 9 9 +5 5 7 9 9 +7 7 7 9 9 +3 NULL 7 9 9 +5 5 3 9 9 +7 7 3 9 9 +3 NULL 3 9 9 +5 5 NULL NULL 3 +7 7 NULL NULL 3 +3 NULL NULL NULL 3 +5 5 NULL NULL 2 +7 7 NULL NULL 2 +3 NULL NULL NULL 2 +drop table t1,t2,t3,t4,t5; +select a.a +from (select 1 as a) a, +(select 2 as b) b +cross join +(select 3 as c) c +left join +(select 4 as d) d +on 1; +a +1 +# # End of MariaDB 5.5 tests # diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 168cfe4..c24fe3b 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -1614,5 +1614,64 @@ eval $q; drop table t1,t2,t3,t4,s1,s2; --echo # +--echo # MDEV-20265: Mix of comma joins with JOIN expressions +--echo # (correction of the fix for MDEV-19421) +--echo # MDEV-20330: duplicate +--echo # + +create table t1 (a int); +insert into t1 values (7), (5), (3); +create table t2 (a int); +insert into t2 values (5), (1), (7); +create table t3 (a int); +insert into t3 values (2), (7), (3); +create table t4 (a int); +insert into t4 values (4), (7), (9), (5); +create table t5 (a int); +insert into t5 values (3), (7), (9), (2); + + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 left join t4 on t3.a=t4.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 right join t4 on t3.a=t4.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a; +eval explain extended $q; +eval $q; + +drop table t1,t2,t3,t4,t5; + +select a.a +from (select 1 as a) a, + (select 2 as b) b + cross join + (select 3 as c) c + left join + (select 4 as d) d + on 1; + +--echo # --echo # End of MariaDB 5.5 tests --echo # diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 346f8ad..ae5a6b4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6435,10 +6435,6 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) TABLE_LIST *head= join_list->head(); if (head->nested_join && head->nested_join->nest_type & REBALANCED_NEST) { - List_iterator<TABLE_LIST> li(*join_list); - li++; - while (li++) - li.remove(); DBUG_RETURN(head); } @@ -6522,13 +6518,13 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) context and right-associative in another context. In this query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1) + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1) JOIN is left-associative and the query Q1 is interpreted as - SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a. + SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a. While in this query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2) + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2) JOIN is right-associative and the query Q2 is interpreted as - SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b + SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b JOIN is right-associative if it is used with ON clause or with USING clause. Otherwise it is left-associative. @@ -6574,9 +6570,9 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) J LJ - ON / \ / \ - t1 LJ - ON (TQ3*) => J t2 - / \ / \ - t3 t2 t1 t3 + t1 LJ - ON (TQ3*) => t3 J + / \ / \ + t3 t2 t1 t2 With several left associative JOINs SELECT * FROM t1 JOIN t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q4) @@ -6584,15 +6580,15 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) J1 LJ - ON / \ / \ - t1 LJ - ON J2 t4 + t1 J2 J2 t4 / \ => / \ - J2 t4 J1 t3 - / \ / \ - t2 t3 t1 t2 + t2 LJ - ON J1 t3 + / \ / \ + t3 t4 t1 t2 - Here's another example: - SELECT * - FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5) + Here's another example: + SELECT * + FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5) J LJ - ON / \ / \ @@ -6602,15 +6598,58 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) / \ t3 t4 - If the transformed nested join node node is a natural join node like in - the following query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6) - the transformation additionally has to take care about setting proper - references in the field natural_join for both operands of the natural - join operation. - The function also has to change the name resolution context for ON - expressions used in the transformed join expression to take into - account the tables of the left_op node. + If the transformed nested join node node is a natural join node like in + the following query + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6) + the transformation additionally has to take care about setting proper + references in the field natural_join for both operands of the natural + join operation. + + The queries that combine comma syntax for join operation with + JOIN expression require a special care. Consider the query + SELECT * FROM t1, t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q7) + This query is equivalent to the query + SELECT * FROM (t1, t2) JOIN t3 LEFT JOIN t4 ON t3.a=t4.a + The latter is transformed in the same way as query Q1 + + J LJ - ON + / \ / \ + (t1,t2) LJ - ON => J t4 + / \ / \ + t3 t4 (t1,t2) t3 + + A transformation similar to the transformation for Q3 is done for + the following query with RIGHT JOIN + SELECT * FROM t1, t2 JOIN t3 RIGHT JOIN t4 ON t3.a=t4.a (Q8) + + J LJ - ON + / \ / \ + t3 LJ - ON => t4 J + / \ / \ + t4 (t1,t2) (t1,t2) t3 + + The function also has to change the name resolution context for ON + expressions used in the transformed join expression to take into + account the tables of the left_op node. + + TODO: + A more elegant solution would be to implement the transformation that + eliminates nests for cross join operations. For Q7 it would work like this: + + J LJ - ON + / \ / \ + (t1,t2) LJ - ON => (t1,t2,t3) t4 + / \ + t3 t4 + + For Q8 with RIGHT JOIN the transformation would work similarly: + + J LJ - ON + / \ / \ + t3 LJ - ON => t4 (t1,t2,t3) + / \ + t4 (t1,t2) + */ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, @@ -6633,7 +6672,11 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, } TABLE_LIST *tbl; - List<TABLE_LIST> *jl= &right_op->nested_join->join_list; + List<TABLE_LIST> *right_op_jl= right_op->join_list; + TABLE_LIST *r_tbl= right_op_jl->pop(); + DBUG_ASSERT(right_op == r_tbl); + TABLE_LIST *l_tbl= right_op_jl->pop(); + DBUG_ASSERT(left_op == l_tbl); TABLE_LIST *cj_nest; /* @@ -6650,6 +6693,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, List<TABLE_LIST> *cjl= &cj_nest->nested_join->join_list; cjl->empty(); + List<TABLE_LIST> *jl= &right_op->nested_join->join_list; + DBUG_ASSERT(jl->elements == 2); /* Look for the left most node tbl of the right_op tree */ for ( ; ; ) { @@ -6721,6 +6766,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, create a new top level nested join node. */ right_op->nested_join->nest_type|= REBALANCED_NEST; + if (unlikely(right_op_jl->push_front(right_op))) + DBUG_RETURN(true); DBUG_RETURN(false); }
1 0
0 0
[Commits] 29e560cdf32: MDEV-20348: DROP TABLE IF EXISTS killed on master but was replicated
by sujatha 14 Aug '19

14 Aug '19
revision-id: 29e560cdf32a2c6aa10298c2404bbeb54e628d6e (mariadb-10.2.26-26-g29e560cdf32) parent(s): 2347ffd843b8e4ee9d8eaafab05368435db59ece author: Sujatha committer: Sujatha timestamp: 2019-08-14 22:53:16 +0530 message: MDEV-20348: DROP TABLE IF EXISTS killed on master but was replicated Problem: ======= DROP TABLE IF EXISTS was killed. The table still exists on the master but the DDL was still logged. Analysis: ========= During the execution of DROP TABLE command "ha_delete_table" call is invoked to delete the table. If the query is killed at this point, the kill command is not handled within the code. This results in two issues. 1) The table which is not dropped also gets written into the binary log. 2) The code continues further upon receiving 'KILL QUERY'. Fix: === Upon receiving the KILL command the query should stop its current execution. Tables which were successfully dropped prior to KILL command should be included in the binary log. --- .../suite/rpl/r/rpl_failed_drop_tbl_binlog.result | 32 +++++++++++ .../suite/rpl/t/rpl_failed_drop_tbl_binlog.test | 64 +++++++++++++++++++++ sql/sql_table.cc | 67 ++++++++++------------ 3 files changed, 127 insertions(+), 36 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result new file mode 100644 index 00000000000..df36fa82e0f --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result @@ -0,0 +1,32 @@ +include/master-slave.inc +[connection master] +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +drop table t1, t2, t3; +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +kill query CONNECTION_ID; +connection master; +ERROR 70100: Query execution was interrupted +"Tables t2 and t3 should be listed" +SHOW TABLES; +Tables_in_test +t2 +t3 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +connection slave; +drop table t2, t3; +connection master; +set debug_sync='RESET'; +drop table t2, t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test new file mode 100644 index 00000000000..281e2a2ab47 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test @@ -0,0 +1,64 @@ +# ==== Purpose ==== +# +# Check that when the execution of a DROP TABLE command with single table +# fails it should not be written to the binary log. Also test that when the +# execution of DROP TABLE command with multiple tables fails the command +# should be written into the binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create tables named t1, t2, t3 +# 1 - Execute DROP TABLE t1,t2,t3 command. +# 2 - Kill the DROP TABLE command while it is trying to drop table 't2'. +# 3 - Verify that tables t2,t3 are present after the DROP command execution +# was interrupted. +# 4 - Check that table 't1' is present in binary log as part of DROP +# command. +# +# ==== References ==== +# +# MDEV-20348: DROP TABLE IF EXISTS killed on master but was replicated. +# + +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +let $id=`select connection_id()`; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +send drop table t1, t2, t3; + +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point:%'; +source include/wait_condition.inc; +--replace_result $id CONNECTION_ID +eval kill query $id; + +connection master; +error ER_QUERY_INTERRUPTED; +reap; + +--echo "Tables t2 and t3 should be listed" +SHOW TABLES; +--source include/show_binlog_events.inc +--sync_slave_with_master +drop table t2, t3; + +connection master; +set debug_sync='RESET'; +drop table t2, t3; + +source include/rpl_end.inc; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9d7e03727d3..cc58dc4a7e8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2362,35 +2362,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, path_length= build_table_filename(path, sizeof(path) - 1, db, alias, reg_ext, 0); - /* - This handles the case where a "DROP" was executed and a regular - table "may be" dropped as drop_temporary is FALSE and error is - TRUE. If the error was FALSE a temporary table was dropped and - regardless of the status of drop_temporary a "DROP TEMPORARY" - must be used. - */ - if (!dont_log_query) - { - /* - Note that unless if_exists is TRUE or a temporary table was deleted, - there is no means to know if the statement should be written to the - binary log. See further information on this variable in what follows. - */ - non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); - /* - Don't write the database name if it is the current one (or if - thd->db is NULL). - */ - if (thd->db == NULL || strcmp(db,thd->db) != 0) - { - append_identifier(thd, &built_query, db, db_length); - built_query.append("."); - } - - append_identifier(thd, &built_query, table->table_name, - table->table_name_length); - built_query.append(","); - } } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); error= 0; @@ -2464,14 +2435,20 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, // Remove extension for delete *(end= path + path_length - reg_ext_length)= '\0'; - error= ha_delete_table(thd, table_type, path, db, table->table_name, - !dont_log_query); - - if (!error) + if ((error= ha_delete_table(thd, table_type, path, db, table->table_name, + !dont_log_query))) + { + if (thd->is_killed()) + { + error= -1; + goto err; + } + } + else { int frm_delete_error, trigger_drop_error= 0; - /* Delete the table definition file */ - strmov(end,reg_ext); + /* Delete the table definition file */ + strmov(end,reg_ext); if (table_type && table_type != view_pseudo_hton && table_type->discover_table) { @@ -2505,7 +2482,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (error) { if (wrong_tables.length()) - wrong_tables.append(','); + wrong_tables.append(','); wrong_tables.append(db); wrong_tables.append('.'); wrong_tables.append(table->table_name); @@ -2518,6 +2495,24 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_audit_drop_table(thd, table); } + if (!dont_log_query && !drop_temporary) + { + non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); + /* + Don't write the database name if it is the current one (or if + thd->db is NULL). + */ + if (thd->db == NULL || strcmp(db,thd->db) != 0) + { + append_identifier(thd, &built_query, db, db_length); + built_query.append("."); + } + + append_identifier(thd, &built_query, table->table_name, + table->table_name_length); + built_query.append(","); + } + DBUG_PRINT("table", ("table: %p s: %p", table->table, table->table ? table->table->s : NULL)); }
1 0
0 0
[Commits] 2e61c0561c0: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated
by sujatha 14 Aug '19

14 Aug '19
revision-id: 2e61c0561c0f2cc760c042b3e4ec8880eaaf4882 (mariadb-10.2.26-25-g2e61c0561c0) parent(s): 65296123d0fcaeb122bc3b9d9e387468052c06b6 author: Sujatha committer: Sujatha timestamp: 2019-08-14 17:34:06 +0530 message: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated Problem: ======= DROP TABLE IF EXISTS was killed. The table still exists on the master but the DDL was still logged. Analysis: ========= During the execution of DROP TABLE command "ha_delete_table" call is invoked to delete the table. If the query is killed at this point, the kill command is not handled within the code. This results in two issues. 1) The table which is not dropped also gets written into the binary log. 2) The code continues further upon receiving 'KILL QUERY'. Fix: === Upon receiving the KILL command the query should stop its current execution. Tables which were successfully dropped prior to KILL command should be included in the binary log. --- .../suite/rpl/r/rpl_failed_drop_tbl_binlog.result | 29 ++++++++++ .../suite/rpl/t/rpl_failed_drop_tbl_binlog.test | 61 ++++++++++++++++++++++ sql/sql_table.cc | 53 +++++++++++-------- 3 files changed, 122 insertions(+), 21 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result new file mode 100644 index 00000000000..2831cb05dbd --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result @@ -0,0 +1,29 @@ +include/master-slave.inc +[connection master] +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +drop table t1, t2, t3; +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +kill query CONNECTION_ID; +connection master; +ERROR 70100: Query execution was interrupted +"Tables t2 and t3 should be listed" +SHOW TABLES; +Tables_in_test +t2 +t3 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +set debug_sync='RESET'; +drop table t2, t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test new file mode 100644 index 00000000000..93ac6916777 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test @@ -0,0 +1,61 @@ +# ==== Purpose ==== +# +# Check that when the execution of a DROP TABLE command with single table +# fails it should not be written to the binary log. Also test that when the +# execution of DROP TABLE command with multiple tables fails the command +# should be written into the binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create tables named t1, t2, t3 +# 1 - Execute DROP TABLE t1,t2,t3 command. +# 2 - Kill the DROP TABLE command while it is trying to drop table 't2'. +# 3 - Verify that tables t2,t3 are present after the DROP command execution +# was interrupted. +# 4 - Check that table 't1' is present in binary log as part of DROP +# command. +# +# ==== References ==== +# +# MENT-325: DROP TABLE IF EXISTS killed on master but was replicated. +# + +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +let $id=`select connection_id()`; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +send drop table t1, t2, t3; + +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point:%'; +source include/wait_condition.inc; +--replace_result $id CONNECTION_ID +eval kill query $id; + +connection master; +error ER_QUERY_INTERRUPTED; +reap; + +--echo "Tables t2 and t3 should be listed" +SHOW TABLES; +--source include/show_binlog_events.inc + +set debug_sync='RESET'; +drop table t2, t3; + +source include/rpl_end.inc; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9d7e03727d3..c78fca28031 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2185,6 +2185,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, int error= 0; int non_temp_tables_count= 0; bool non_tmp_error= 0; + bool at_least_one_table_dropped= false; bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; bool non_tmp_table_deleted= 0; bool is_drop_tmp_if_exists_added= 0; @@ -2377,19 +2378,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, binary log. See further information on this variable in what follows. */ non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); - /* - Don't write the database name if it is the current one (or if - thd->db is NULL). - */ - if (thd->db == NULL || strcmp(db,thd->db) != 0) - { - append_identifier(thd, &built_query, db, db_length); - built_query.append("."); - } - - append_identifier(thd, &built_query, table->table_name, - table->table_name_length); - built_query.append(","); } } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); @@ -2464,14 +2452,20 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, // Remove extension for delete *(end= path + path_length - reg_ext_length)= '\0'; - error= ha_delete_table(thd, table_type, path, db, table->table_name, - !dont_log_query); - - if (!error) + if ((error= ha_delete_table(thd, table_type, path, db, table->table_name, + !dont_log_query))) + { + if (thd->killed) + { + error= -1; + goto err; + } + } + else { int frm_delete_error, trigger_drop_error= 0; - /* Delete the table definition file */ - strmov(end,reg_ext); + /* Delete the table definition file */ + strmov(end,reg_ext); if (table_type && table_type != view_pseudo_hton && table_type->discover_table) { @@ -2505,7 +2499,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (error) { if (wrong_tables.length()) - wrong_tables.append(','); + wrong_tables.append(','); wrong_tables.append(db); wrong_tables.append('.'); wrong_tables.append(table->table_name); @@ -2518,6 +2512,22 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_audit_drop_table(thd, table); } + /* + Add table name to "DROP TABLE command" only after successful deletion. + Don't write the database name if it is the current one (or if + thd->db is NULL). + */ + if (thd->db == NULL || strcmp(db,thd->db) != 0) + { + append_identifier(thd, &built_query, db, db_length); + built_query.append("."); + } + + append_identifier(thd, &built_query, table->table_name, + table->table_name_length); + built_query.append(","); + at_least_one_table_dropped= true; + DBUG_PRINT("table", ("table: %p s: %p", table->table, table->table ? table->table->s : NULL)); } @@ -2586,7 +2596,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, is_drop_tmp_if_exists_added, 0); } - if (non_tmp_table_deleted) + if (non_tmp_table_deleted && + (at_least_one_table_dropped == true)) { /* Chop of the last comma */ built_query.chop();
1 0
0 0
[Commits] 2cde654d994: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated
by sujatha 14 Aug '19

14 Aug '19
revision-id: 2cde654d9948eaf28dff621db34c44ce47c20b5f (mariadb-10.2.26-25-g2cde654d994) parent(s): 65296123d0fcaeb122bc3b9d9e387468052c06b6 author: Sujatha committer: Sujatha timestamp: 2019-08-14 17:31:23 +0530 message: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated Problem: ======= DROP TABLE IF EXISTS was killed. The table still exists on the master but the DDL was still logged. Fix: === When DROP TABLE command execution is interuppted because of kill command the replicated DROP TABLE command should include only the list of tables which were dropped succesfully.MENT-325: DROP TABLE IF EXISTS killed on master but was replicated Problem: ======= DROP TABLE IF EXISTS was killed. The table still exists on the master but the DDL was still logged. Analysis: ========= During the execution of DROP TABLE command "ha_delete_table" call is invoked to delete the table. If the query is killed at this point, the kill command is not handled within the code. This results in two issues. 1) The table which is not dropped also gets written into the binary log. 2) The code continues further upon receiving 'KILL QUERY'. Fix: === Upon receiving the KILL command the query should stop its current execution. Tables which were successfully dropped prior to KILL command should be included in the binary log. --- .../suite/rpl/r/rpl_failed_drop_tbl_binlog.result | 29 ++++++++++ .../suite/rpl/t/rpl_failed_drop_tbl_binlog.test | 61 ++++++++++++++++++++++ sql/sql_table.cc | 53 +++++++++++-------- 3 files changed, 122 insertions(+), 21 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result new file mode 100644 index 00000000000..2831cb05dbd --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result @@ -0,0 +1,29 @@ +include/master-slave.inc +[connection master] +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +drop table t1, t2, t3; +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +kill query CONNECTION_ID; +connection master; +ERROR 70100: Query execution was interrupted +"Tables t2 and t3 should be listed" +SHOW TABLES; +Tables_in_test +t2 +t3 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +set debug_sync='RESET'; +drop table t2, t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test new file mode 100644 index 00000000000..93ac6916777 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test @@ -0,0 +1,61 @@ +# ==== Purpose ==== +# +# Check that when the execution of a DROP TABLE command with single table +# fails it should not be written to the binary log. Also test that when the +# execution of DROP TABLE command with multiple tables fails the command +# should be written into the binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create tables named t1, t2, t3 +# 1 - Execute DROP TABLE t1,t2,t3 command. +# 2 - Kill the DROP TABLE command while it is trying to drop table 't2'. +# 3 - Verify that tables t2,t3 are present after the DROP command execution +# was interrupted. +# 4 - Check that table 't1' is present in binary log as part of DROP +# command. +# +# ==== References ==== +# +# MENT-325: DROP TABLE IF EXISTS killed on master but was replicated. +# + +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +create table t1 (a int) engine=innodb; +create table t2 (b longblob) engine=innodb; +create table t3 (c int) engine=innodb; +insert into t2 values (repeat('b',1024*1024)); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +let $id=`select connection_id()`; +set debug_sync='rm_table_no_locks_before_delete_table SIGNAL nogo WAIT_FOR go EXECUTE 2'; +send drop table t1, t2, t3; + +connect foo,localhost,root; +set debug_sync='now SIGNAL go'; +let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point:%'; +source include/wait_condition.inc; +--replace_result $id CONNECTION_ID +eval kill query $id; + +connection master; +error ER_QUERY_INTERRUPTED; +reap; + +--echo "Tables t2 and t3 should be listed" +SHOW TABLES; +--source include/show_binlog_events.inc + +set debug_sync='RESET'; +drop table t2, t3; + +source include/rpl_end.inc; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9d7e03727d3..c78fca28031 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2185,6 +2185,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, int error= 0; int non_temp_tables_count= 0; bool non_tmp_error= 0; + bool at_least_one_table_dropped= false; bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; bool non_tmp_table_deleted= 0; bool is_drop_tmp_if_exists_added= 0; @@ -2377,19 +2378,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, binary log. See further information on this variable in what follows. */ non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); - /* - Don't write the database name if it is the current one (or if - thd->db is NULL). - */ - if (thd->db == NULL || strcmp(db,thd->db) != 0) - { - append_identifier(thd, &built_query, db, db_length); - built_query.append("."); - } - - append_identifier(thd, &built_query, table->table_name, - table->table_name_length); - built_query.append(","); } } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); @@ -2464,14 +2452,20 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, // Remove extension for delete *(end= path + path_length - reg_ext_length)= '\0'; - error= ha_delete_table(thd, table_type, path, db, table->table_name, - !dont_log_query); - - if (!error) + if ((error= ha_delete_table(thd, table_type, path, db, table->table_name, + !dont_log_query))) + { + if (thd->killed) + { + error= -1; + goto err; + } + } + else { int frm_delete_error, trigger_drop_error= 0; - /* Delete the table definition file */ - strmov(end,reg_ext); + /* Delete the table definition file */ + strmov(end,reg_ext); if (table_type && table_type != view_pseudo_hton && table_type->discover_table) { @@ -2505,7 +2499,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (error) { if (wrong_tables.length()) - wrong_tables.append(','); + wrong_tables.append(','); wrong_tables.append(db); wrong_tables.append('.'); wrong_tables.append(table->table_name); @@ -2518,6 +2512,22 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_audit_drop_table(thd, table); } + /* + Add table name to "DROP TABLE command" only after successful deletion. + Don't write the database name if it is the current one (or if + thd->db is NULL). + */ + if (thd->db == NULL || strcmp(db,thd->db) != 0) + { + append_identifier(thd, &built_query, db, db_length); + built_query.append("."); + } + + append_identifier(thd, &built_query, table->table_name, + table->table_name_length); + built_query.append(","); + at_least_one_table_dropped= true; + DBUG_PRINT("table", ("table: %p s: %p", table->table, table->table ? table->table->s : NULL)); } @@ -2586,7 +2596,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, is_drop_tmp_if_exists_added, 0); } - if (non_tmp_table_deleted) + if (non_tmp_table_deleted && + (at_least_one_table_dropped == true)) { /* Chop of the last comma */ built_query.chop();
1 0
0 0
[Commits] 3b9ce7937e2: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated
by sujatha 14 Aug '19

14 Aug '19
revision-id: 3b9ce7937e2422dc7bae26218b63b27ac68ba057 (mariadb-10.2.26-25-g3b9ce7937e2) parent(s): 65296123d0fcaeb122bc3b9d9e387468052c06b6 author: Sujatha committer: Sujatha timestamp: 2019-08-14 12:06:27 +0530 message: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated Problem: ======= DROP TABLE IF EXISTS was killed. The table still exists on the master but the DDL was still logged. Fix: === When DROP TABLE command execution is interuppted because of kill command the replicated DROP TABLE command should include only the list of tables which were dropped succesfully. --- .../suite/rpl/r/rpl_failed_drop_tbl_binlog.result | 61 +++++++++++++++ .../suite/rpl/t/rpl_failed_drop_tbl_binlog.test | 88 ++++++++++++++++++++++ sql/sql_table.cc | 33 ++++---- 3 files changed, 168 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result new file mode 100644 index 00000000000..7d02b4624e3 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result @@ -0,0 +1,61 @@ +include/master-slave.inc +[connection master] +connect master2,localhost,root,,; +connection master; +CREATE TABLE t1 (A INT); +CREATE TABLE t2 (A INT); +connection slave; +connection master; +LOCK TABLE t1 WRITE; +SET debug_sync='rm_table_no_locks_before_delete_table WAIT_FOR go'; +DROP TABLE IF EXISTS t1; +connection master1; +SET debug_sync='open_tables_after_open_and_process_table SIGNAL go WAIT_FOR go2'; +PREPARE x FROM "INSERT t1 VALUES (10)"; +connection master2; +KILL QUERY 9; +SET debug_sync='now SIGNAL go2'; +connection master; +ERROR 70100: Query execution was interrupted +include/assert.inc [Drop with single table should not be written to the binary log if the query execution fails] +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (A INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (A INT) +disconnect master2; +"Table t1 should be listed" +SHOW TABLES; +Tables_in_test +t1 +t2 +connection master; +UNLOCK TABLES; +SET debug_sync='reset'; +# DROP TABLE command with multiple tables fails the command should be written into the binary log. +DROP TABLE t1,t3; +ERROR 42S02: Unknown table 'test.t3' +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (A INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (A INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t3` /* generated by server */ +# Testing DROP TABLE command with a non existing table and an existing table. Both should be writtent to binary log. +DROP TABLE t3,t2; +ERROR 42S02: Unknown table 'test.t3' +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (A INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (A INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t3` /* generated by server */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t3`,`t2` /* generated by server */ +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test new file mode 100644 index 00000000000..9612848cc62 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test @@ -0,0 +1,88 @@ +# ==== Purpose ==== +# +# Check that when the execution of a DROP TABLE command with single table +# fails it should not be written to the binary log. Also test that when the +# execution of DROP TABLE command with multiple tables fails the command +# should be written into the binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create table named t1. +# 1 - Simulate a scenario where DROP TABLE command waits for an exclusive +# MDL lock to drop the table. +# 2 - Kill the query from another session. +# 3 - The DROP TABLE query execution will be interrupted. Ensure that the +# failed DROP TABLE command is not written to the binary log. +# 4 - Execute DROP TABLE t1, t2 statement. It will fail as 't2' table is +# not present. It should error out with unknown table error. +# 5 - The command should be written to binary log as it has already dropped +# table t1. +# +# ==== References ==== +# +# MENT-325: DROP TABLE IF EXISTS killed on master but was replicated. +# + +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +connect (master2,localhost,root,,); + +--connection master +CREATE TABLE t1 (A INT); +CREATE TABLE t2 (A INT); +# Save master position +--let $saved_master_pos=query_get_value('SHOW MASTER STATUS', Position, 1) +--sync_slave_with_master + +--connection master +--let id=`select connection_id()` +LOCK TABLE t1 WRITE; +SET debug_sync='rm_table_no_locks_before_delete_table WAIT_FOR go'; +--send DROP TABLE IF EXISTS t1 + +--connection master1 +--let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE like "debug sync point: rm_table_no_locks_before_delete_table%" +--source include/wait_condition.inc +SET debug_sync='open_tables_after_open_and_process_table SIGNAL go WAIT_FOR go2'; +--send PREPARE x FROM "INSERT t1 VALUES (10)" + +--connection master2 +--let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE like "debug sync point: open_tables_after_open_and_process_table%" +--source include/wait_condition.inc +eval KILL QUERY $id; +SET debug_sync='now SIGNAL go2'; + +--connection master +--error ER_QUERY_INTERRUPTED +reap; + +--let $current_master_pos=query_get_value('SHOW MASTER STATUS', Position, 1) +--let $assert_text= Drop with single table should not be written to the binary log if the query execution fails +--let $assert_cond= $current_master_pos = $saved_master_pos +--source include/assert.inc + +--source include/show_binlog_events.inc +disconnect master2; + +--echo "Table t1 should be listed" +SHOW TABLES; + +--connection master +UNLOCK TABLES; +SET debug_sync='reset'; + +--echo # DROP TABLE command with multiple tables fails the command should be written into the binary log. +--error ER_BAD_TABLE_ERROR +DROP TABLE t1,t3; +--source include/show_binlog_events.inc + +--echo # Testing DROP TABLE command with a non existing table and an existing table. Both should be writtent to binary log. +--error ER_BAD_TABLE_ERROR +DROP TABLE t3,t2; +--source include/show_binlog_events.inc +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9d7e03727d3..f1185845d59 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2185,6 +2185,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, int error= 0; int non_temp_tables_count= 0; bool non_tmp_error= 0; + bool at_least_one_table_dropped= false; bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; bool non_tmp_table_deleted= 0; bool is_drop_tmp_if_exists_added= 0; @@ -2377,19 +2378,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, binary log. See further information on this variable in what follows. */ non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); - /* - Don't write the database name if it is the current one (or if - thd->db is NULL). - */ - if (thd->db == NULL || strcmp(db,thd->db) != 0) - { - append_identifier(thd, &built_query, db, db_length); - built_query.append("."); - } - - append_identifier(thd, &built_query, table->table_name, - table->table_name_length); - built_query.append(","); } } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); @@ -2518,6 +2506,22 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_audit_drop_table(thd, table); } + /* + Add table name to "DROP TABLE command" only after successful deletion. + Don't write the database name if it is the current one (or if + thd->db is NULL). + */ + if (thd->db == NULL || strcmp(db,thd->db) != 0) + { + append_identifier(thd, &built_query, db, db_length); + built_query.append("."); + } + + append_identifier(thd, &built_query, table->table_name, + table->table_name_length); + built_query.append(","); + at_least_one_table_dropped= true; + DBUG_PRINT("table", ("table: %p s: %p", table->table, table->table ? table->table->s : NULL)); } @@ -2586,7 +2590,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, is_drop_tmp_if_exists_added, 0); } - if (non_tmp_table_deleted) + if (non_tmp_table_deleted && + (at_least_one_table_dropped == true)) { /* Chop of the last comma */ built_query.chop();
1 0
0 0
[Commits] 65296123d0f: MDEV-12439: MariaRocks produces numerous (spurious?) valgrind failures
by Sergei Petrunia 13 Aug '19

13 Aug '19
revision-id: 65296123d0fcaeb122bc3b9d9e387468052c06b6 (mariadb-10.2.26-24-g65296123d0f) parent(s): c5b4697b2432d1692227ddf4abb46eb625d94d61 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2019-08-13 16:37:21 +0300 message: MDEV-12439: MariaRocks produces numerous (spurious?) valgrind failures Enable the rocksdb test suite. It now passes the valgrind tests. --- storage/rocksdb/mysql-test/rocksdb/suite.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/rocksdb/mysql-test/rocksdb/suite.pm b/storage/rocksdb/mysql-test/rocksdb/suite.pm index 3423d34ded5..e4f074df471 100644 --- a/storage/rocksdb/mysql-test/rocksdb/suite.pm +++ b/storage/rocksdb/mysql-test/rocksdb/suite.pm @@ -20,8 +20,8 @@ my $sst_dump= return "RocksDB is not compiled, no sst_dump" unless $sst_dump; $ENV{MARIAROCKS_SST_DUMP}="$sst_dump"; -# Temporarily disable testing under valgrind, due to MDEV-12439 -return "RocksDB tests disabled under valgrind" if ($::opt_valgrind); +## Temporarily disable testing under valgrind, due to MDEV-12439 +#return "RocksDB tests disabled under valgrind" if ($::opt_valgrind); bless { };
1 0
0 0
[Commits] c5b4697b243: MDEV-20315: Backport to 10.2: Myrocks: Get the upstream's valgrind suppressions to work
by Sergei Petrunia 13 Aug '19

13 Aug '19
revision-id: c5b4697b2432d1692227ddf4abb46eb625d94d61 (mariadb-10.2.26-23-gc5b4697b243) parent(s): a18d1cc7778633a9d05f46082e7ddeb8e40130ba author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2019-08-13 16:27:51 +0300 message: MDEV-20315: Backport to 10.2: Myrocks: Get the upstream's valgrind suppressions to work --- mysql-test/valgrind.supp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index c113447b229..43f22db69c6 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -1794,6 +1794,30 @@ } +{ + Still reachable for once-per-process initializations 2 + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb16ThreadStatusUtil19NewColumnFamilyInfoEPKNS_2DBEPKNS_16ColumnFamilyDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_3EnvE + fun:_ZNK7rocksdb6DBImpl21NewThreadStatusCfInfoEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb6DBImpl4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPNS_2DBEbb + fun:_ZN7rocksdb13TransactionDB4OpenERKNS_9DBOptionsERKNS_20TransactionDBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISG_EEPSF_IPNS_18ColumnFamilyHandleESaISM_EEPPS0_ +# fun:_ZN7myrocksL17rocksdb_init_funcEPv +# ^ commenting the above out because we are hitting the --num-callers=16 +# limitation that MTR sets for valgrind +} + +{ + Still reachable for once-per-process initializations 3 + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb16ThreadStatusUtil19NewColumnFamilyInfoEPKNS_2DBEPKNS_16ColumnFamilyDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_3EnvE + fun:_ZNK7rocksdb6DBImpl21NewThreadStatusCfInfoEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb6DBImpl22CreateColumnFamilyImplERKNS_19ColumnFamilyOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPPNS_18ColumnFamilyHandleE +} + { Still reachable for once-per-process initializations Memcheck:Leak @@ -1802,7 +1826,6 @@ fun:_ZN7rocksdb19ThreadStatusUpdater14RegisterThreadENS_12ThreadStatus10ThreadTypeEm fun:_ZN7rocksdb16ThreadStatusUtil14RegisterThreadEPKNS_3EnvENS_12ThreadStatus10ThreadTypeE fun:_ZN7rocksdb14ThreadPoolImpl4Impl15BGThreadWrapperEPv - fun:_ZNSt12_Bind_simpleIFPFPvS0_EPN7rocksdb16BGThreadMetadataEEE9_M_invokeIILm0EEEES0_St12_Index_tupleIIXspT_EEE ... }
1 0
0 0
[Commits] a18d1cc7778: MDEV-20315: MyRocks tests produce valgrind failures (Backport to 10.2)
by Sergei Petrunia 13 Aug '19

13 Aug '19
revision-id: a18d1cc7778633a9d05f46082e7ddeb8e40130ba (mariadb-10.2.26-22-ga18d1cc7778) parent(s): ed4ccf34a6603bd2374a721a7e1ad88472f335fc author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2019-08-13 16:26:17 +0300 message: MDEV-20315: MyRocks tests produce valgrind failures (Backport to 10.2) - Include the valgrind suppressions from the FB upstream - Use HAVE_Valgrind, not HAVE_Purify (like the rest of MariaDB code does) The call to DisownData() is now actually disabled under Valgrind --- mysql-test/valgrind.supp | 94 +++++++++++++++++++++++++++++++++++++++++++ storage/rocksdb/ha_rocksdb.cc | 4 +- 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index a8ca80e203a..c113447b229 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -1771,3 +1771,97 @@ obj:/usr/lib64/libcrypto.so* } + + +## +## The following is a copy of facebook/mysql-5.6 suppressions: +## + +# +# RocksDB Storage Engine suppressions start +# + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb16ThreadStatusUtil19NewColumnFamilyInfoEPKNS_2DBEPKNS_16ColumnFamilyDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_3EnvE + fun:_ZNK7rocksdb6DBImpl21NewThreadStatusCfInfoEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb2DB4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPS0_ + fun:_ZN7rocksdb13TransactionDB4OpenERKNS_9DBOptionsERKNS_20TransactionDBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISG_EEPSF_IPNS_18ColumnFamilyHandleESaISM_EEPPS0_ + fun:_ZN7myrocksL17rocksdb_init_funcEPv +} + + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb19ThreadStatusUpdater14RegisterThreadENS_12ThreadStatus10ThreadTypeEm + fun:_ZN7rocksdb16ThreadStatusUtil14RegisterThreadEPKNS_3EnvENS_12ThreadStatus10ThreadTypeE + fun:_ZN7rocksdb14ThreadPoolImpl4Impl15BGThreadWrapperEPv + fun:_ZNSt12_Bind_simpleIFPFPvS0_EPN7rocksdb16BGThreadMetadataEEE9_M_invokeIILm0EEEES0_St12_Index_tupleIIXspT_EEE + ... +} + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb14ThreadLocalPtr14InitSingletonsEv + fun:_ZN7rocksdb3Env7DefaultEv + fun:_ZN7rocksdb9DBOptionsC1Ev + ... + fun:_ZN7myrocksL27rdb_init_rocksdb_db_optionsEv +} + +{ + Still reachable for once-per-process initializations + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb12_GLOBAL__N_18PosixEnv* + fun:_ZN7rocksdb3Env7DefaultEv + fun:_ZN7rocksdb9DBOptionsC1Ev + ... + fun:_ZN7myrocksL27rdb_init_rocksdb_db_optionsEv +} + +{ + Still reachable for thread local storage initialization (SetHandle) + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZNSt13unordered_mapIjPFvPvESt4hashIjESt8equal_toIjESaISt4pairIKjS2_EEEixERS8_ + fun:_ZN7rocksdb14ThreadLocalPtr10StaticMeta10SetHandlerEjPFvPvE + fun:_ZN7rocksdb14ThreadLocalPtrC1EPFvPvE + ... +} + +{ + Still reachable for thread local storage initialization (ReclaimId) + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_ZN7rocksdb10autovectorIjLm8EE9push_backERKj + fun:_ZN7rocksdb14ThreadLocalPtr10StaticMeta9ReclaimIdEj + fun:_ZN7rocksdb14ThreadLocalPtrD1Ev + ... +} + +{ + Static initialization + Memcheck:Leak + match-leak-kinds: reachable + ... + fun:_Z41__static_initialization_and_destruction_0ii + ... +} + +## +## RocksDB Storage Engine suppressions end +## + diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 613ac0884a7..bf9183d7dea 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -5836,11 +5836,11 @@ static int rocksdb_done_func(void *const p) { // Disown the cache data since we're shutting down. // This results in memory leaks but it improved the shutdown time. // Don't disown when running under valgrind -#ifndef HAVE_purify +#ifndef HAVE_valgrind if (rocksdb_tbl_options->block_cache) { rocksdb_tbl_options->block_cache->DisownData(); } -#endif /* HAVE_purify */ +#endif /* HAVE_valgrind */ /* MariaDB: don't clear rocksdb_db_options and rocksdb_tbl_options.
1 0
0 0
[Commits] e8a96aeb62a: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated
by sujatha 13 Aug '19

13 Aug '19
revision-id: e8a96aeb62ab6880cb703fc7935083f12438d782 (mariadb-10.2.26-17-ge8a96aeb62a) parent(s): 609ea2f37b8169a7c282fe2d607c2412467ccbbb author: Sujatha committer: Sujatha timestamp: 2019-08-13 14:02:46 +0530 message: MENT-325: DROP TABLE IF EXISTS killed on master but was replicated Problem: ======= DROP TABLE IF EXISTS was killed. The table still exists on the master but the DDL was still logged. Fix: === When DROP TABLE command execution is interrupted because of kill command the replicated DROP TABLE command should include only the list of tables which were dropped successfully. For DROP TABLE IF EXISTS .. The command should contain the list of all tables which were actually dropped and unknown tables till the point at which kill command is executed. For DROP TABLE ... The command should contain the list of tables which were dropped. --- .../suite/rpl/r/rpl_failed_drop_tbl_binlog.result | 42 +++++++++++ .../suite/rpl/t/rpl_failed_drop_tbl_binlog.test | 81 ++++++++++++++++++++++ sql/sql_table.cc | 48 ++++++++++--- 3 files changed, 161 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result new file mode 100644 index 00000000000..de166047bed --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_failed_drop_tbl_binlog.result @@ -0,0 +1,42 @@ +include/master-slave.inc +[connection master] +connect master2,localhost,root,,; +connection master; +CREATE TABLE t1 (A INT); +connection slave; +connection master; +LOCK TABLE t1 WRITE; +SET debug_sync='rm_table_no_locks_before_delete_table WAIT_FOR go'; +DROP TABLE IF EXISTS t1; +connection master1; +SET debug_sync='open_tables_after_open_and_process_table SIGNAL go WAIT_FOR go2'; +PREPARE x FROM "INSERT t1 VALUES (10)"; +connection master2; +KILL QUERY 9; +SET debug_sync='now SIGNAL go2'; +connection master; +ERROR 70100: Query execution was interrupted +include/assert.inc [Drop with single table should not be written to the binary log if the query execution fails] +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (A INT) +disconnect master2; +"Table t1 should be listed" +SHOW TABLES; +Tables_in_test +t1 +connection master; +UNLOCK TABLES; +SET debug_sync='reset'; +# DROP TABLE command with multiple tables fails the command should be written into the binary log. +DROP TABLE t1,t2; +ERROR 42S02: Unknown table 'test.t2' +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (A INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */ +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test new file mode 100644 index 00000000000..e8eaeb493c7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.test @@ -0,0 +1,81 @@ +# ==== Purpose ==== +# +# Check that when the execution of a DROP TABLE command with single table +# fails it should not be written to the binary log. Also test that when the +# execution of DROP TABLE command with multiple tables fails the command +# should be written into the binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create table named t1. +# 1 - Simulate a scenario where DROP TABLE command waits for an exclusive +# MDL lock to drop the table. +# 2 - Kill the query from another session. +# 3 - The DROP TABLE query execution will be interrupted. Ensure that the +# failed DROP TABLE command is not written to the binary log. +# 4 - Execute DROP TABLE t1, t2 statement. It will fail as 't2' table is +# not present. It should error out with unknown table error. +# 5 - The command should be written to binary log as it has already dropped +# table t1. +# +# ==== References ==== +# +# MENT-325: DROP TABLE IF EXISTS killed on master but was replicated. +# + +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +connect (master2,localhost,root,,); + +--connection master +CREATE TABLE t1 (A INT); +# Save master position +--let $saved_master_pos=query_get_value('SHOW MASTER STATUS', Position, 1) +--sync_slave_with_master + +--connection master +--let id=`select connection_id()` +LOCK TABLE t1 WRITE; +SET debug_sync='rm_table_no_locks_before_delete_table WAIT_FOR go'; +--send DROP TABLE IF EXISTS t1 + +--connection master1 +--let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE like "debug sync point: rm_table_no_locks_before_delete_table%" +--source include/wait_condition.inc +SET debug_sync='open_tables_after_open_and_process_table SIGNAL go WAIT_FOR go2'; +--send PREPARE x FROM "INSERT t1 VALUES (10)" + +--connection master2 +--let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE like "debug sync point: open_tables_after_open_and_process_table%" +--source include/wait_condition.inc +eval KILL QUERY $id; +SET debug_sync='now SIGNAL go2'; + +--connection master +--error ER_QUERY_INTERRUPTED +reap; + +--let $current_master_pos=query_get_value('SHOW MASTER STATUS', Position, 1) +--let $assert_text= Drop with single table should not be written to the binary log if the query execution fails +--let $assert_cond= $current_master_pos = $saved_master_pos +--source include/assert.inc + +--source include/show_binlog_events.inc +disconnect master2; + +--echo "Table t1 should be listed" +SHOW TABLES; + +--connection master +UNLOCK TABLES; +SET debug_sync='reset'; +--echo # DROP TABLE command with multiple tables fails the command should be written into the binary log. +--error ER_BAD_TABLE_ERROR +DROP TABLE t1,t2; +--source include/show_binlog_events.inc +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 41f62de2a70..6f2fbb66fe6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2187,6 +2187,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool non_tmp_error= 0; bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; bool non_tmp_table_deleted= 0; + bool write_non_tmp_table_drop_in_binlog= false; bool is_drop_tmp_if_exists_added= 0; bool was_view= 0; String built_query; @@ -2265,7 +2266,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } } - for (table= tables; table; table= table->next_local) + for (table= tables; table && !thd->killed; table= table->next_local) { bool is_trans= 0; bool table_creation_was_logged= 0; @@ -2372,11 +2373,21 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (!dont_log_query) { /* - Note that unless if_exists is TRUE or a temporary table was deleted, + Note that unless if_exists is TRUE or a temporary table was deleted, there is no means to know if the statement should be written to the binary log. See further information on this variable in what follows. */ non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted); + } + } + DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); + error= 0; + if (drop_temporary || + (ha_table_exists(thd, db, alias, &table_type) == 0 && table_type == 0) || + (!drop_view && (was_view= (table_type == view_pseudo_hton)))) + { + if (non_tmp_table_deleted) + { /* Don't write the database name if it is the current one (or if thd->db is NULL). @@ -2390,14 +2401,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, append_identifier(thd, &built_query, table->table_name, table->table_name_length); built_query.append(","); + write_non_tmp_table_drop_in_binlog= true; } - } - DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); - error= 0; - if (drop_temporary || - (ha_table_exists(thd, db, alias, &table_type) == 0 && table_type == 0) || - (!drop_view && (was_view= (table_type == view_pseudo_hton)))) - { /* One of the following cases happened: . "DROP TEMPORARY" but a temporary table was not found. @@ -2499,6 +2504,28 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, error= 1; else if (frm_delete_error && if_exists) thd->clear_error(); + + /* + Upon successful deletion of the table include the table name as + part of DROP TABLE command which will be written to the binary log. + */ + if(non_tmp_table_deleted) + { + /* + Don't write the database name if it is the current one (or if + thd->db is NULL). + */ + if (thd->db == NULL || strcmp(db,thd->db) != 0) + { + append_identifier(thd, &built_query, db, db_length); + built_query.append("."); + } + + append_identifier(thd, &built_query, table->table_name, + table->table_name_length); + built_query.append(","); + write_non_tmp_table_drop_in_binlog= true; + } } non_tmp_error|= MY_TEST(error); } @@ -2586,7 +2613,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, is_drop_tmp_if_exists_added, 0); } - if (non_tmp_table_deleted) + if (non_tmp_table_deleted && + (write_non_tmp_table_drop_in_binlog == true)) { /* Chop of the last comma */ built_query.chop();
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • ...
  • 1461
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.