diff options
author | sachin <sachin.setiya@mariadb.com> | 2018-05-14 12:15:38 +0530 |
---|---|---|
committer | Sachin <sachin.setiya@mariadb.com> | 2018-06-21 15:22:32 +0530 |
commit | f11b86cc4eeb4d24ee352925f9bdd7193936f6be (patch) | |
tree | deedcd776b7a4109ad8365ce9d7d1538780cb2e7 | |
parent | 635c5e32815389bff928c3141e418b3cd2c5b887 (diff) | |
download | mariadb-git-bb-10.2-14472.tar.gz |
MDEV-14472 Assertion `is_current_stmt_binlog_format_row()' failed...bb-10.2-14472
in THD::binlog_write_table_map
Problem:- So the issue is when the test case (mdev_14472) is run with debug
build , Assert DBUG_ASSERT(is_current_stmt_binlog_format_row()); is fired
in binlog_write_table_map.
Analysis:- When we lock table t1, and if t1 has some trigger which updates
another table then all other tables are also locked. So in the case of lock
t1(in mdev_14472 test case) we will lock t1, t2, t3 and t4. In next insert
command (t2 insert), we call handler->check_table_row_based from
write_locked_table_maps which updates the table handler
check_table_binlog_row_based_done to 1 and check_table_binlog_row_based_result
to 1 , it is set to one because this particular insert stmt is unsafe(because
of trigger on t4). The next insert stmt(insert t3) is safe so we will write
that in stmt format , but since we havent cleared the previous
check_table_binlog_row_based_result so it is logged in row format while
thd->is_current_stmt_binlog_format_row() is still 0, and this fires the
assert. So the question is why check_table_binlog_row_based_result is not
reseted because mark_used_tables_as_free_for_reuse skips locked tables
Solution:- We make mark_used_tables_as_free_for_reuse to reset
check_table_binlog_row_based_result even when table is locked
-rw-r--r-- | mysql-test/suite/binlog/r/mdev_14472.result | 12 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/mdev_14472.test | 22 | ||||
-rw-r--r-- | sql/sql_base.cc | 6 |
3 files changed, 40 insertions, 0 deletions
diff --git a/mysql-test/suite/binlog/r/mdev_14472.result b/mysql-test/suite/binlog/r/mdev_14472.result new file mode 100644 index 00000000000..0a2483678f1 --- /dev/null +++ b/mysql-test/suite/binlog/r/mdev_14472.result @@ -0,0 +1,12 @@ +CREATE TABLE t1 (f1 INT); +CREATE TABLE t2 (f2 INT); +CREATE TABLE t3 (f3 INT); +CREATE TABLE t4 (pk INT AUTO_INCREMENT PRIMARY KEY); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (); +CREATE TRIGGER tr2 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t3 VALUES (); +CREATE TRIGGER tr3 BEFORE INSERT ON t2 FOR EACH ROW INSERT INTO t4 VALUES (); +LOCK TABLE t1 WRITE; +INSERT INTO t2 () VALUES (); +INSERT INTO t3 VALUES (); +UNLOCK TABLES; +DROP TABLE t1, t2, t3, t4; diff --git a/mysql-test/suite/binlog/t/mdev_14472.test b/mysql-test/suite/binlog/t/mdev_14472.test new file mode 100644 index 00000000000..fd892a44f5c --- /dev/null +++ b/mysql-test/suite/binlog/t/mdev_14472.test @@ -0,0 +1,22 @@ +--source include/have_log_bin.inc +--source include/have_binlog_format_mixed.inc + +# Reproducible with MyISAM, InnoDB, Aria + +CREATE TABLE t1 (f1 INT); +CREATE TABLE t2 (f2 INT); +CREATE TABLE t3 (f3 INT); +CREATE TABLE t4 (pk INT AUTO_INCREMENT PRIMARY KEY); + +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (); +CREATE TRIGGER tr2 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t3 VALUES (); +CREATE TRIGGER tr3 BEFORE INSERT ON t2 FOR EACH ROW INSERT INTO t4 VALUES (); + +LOCK TABLE t1 WRITE; +INSERT INTO t2 () VALUES (); +INSERT INTO t3 VALUES (); + +# Cleanup + +UNLOCK TABLES; +DROP TABLE t1, t2, t3, t4; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9dfaf82758c..a93a1b3ef17 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -603,6 +603,12 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table) table->query_id= 0; table->file->ha_reset(); } + else + { + // table of exlict LOCK TABLE + table->file->check_table_binlog_row_based_done= + table->file->check_table_binlog_row_based_result= 0; + } } } |