summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
authorSujatha Sivakumar <sujatha.sivakumar@oracle.com>2014-04-15 15:17:25 +0530
committerSujatha Sivakumar <sujatha.sivakumar@oracle.com>2014-04-15 15:17:25 +0530
commit58b9807826971bf9dd0552cd860f341ff5854142 (patch)
tree23a4a9122231307ef4549e9187e0f1d979933d27 /mysql-test
parentdb2403cd09855634dbe415d83791e27dfbd94756 (diff)
downloadmariadb-git-58b9807826971bf9dd0552cd860f341ff5854142.tar.gz
Bug#17942050:KILL OF TRUNCATE TABLE WILL LEAD TO BINARY LOG
WRITTEN WHILE ROWS REMAINS Problem: ======== When truncate table fails while using transactional based engines even though the operation errors out we still continue and log it to binlog. Because of this master has data but the truncate will be written to binary log which will cause inconsistency. Analysis: ======== Truncate table can happen either through drop and create of table or by deleting rows. In the second case the existing code is written in such a way that even if an error occurs the truncate statement will always be binlogged. Which is not correct. Binlogging of TRUNCATE TABLE statement should check whether truncate is executed "transactionally or not". If the table is transaction based we log the TRUNCATE TABLE only on successful completion. If table is non transactional there are possibilities that on error we could have partial changes done hence in such cases we do log in spite of errors as some of the lines might have been removed, so the statement has to be sent to slave. Fix: === Using table handler whether truncate table is being executed in transaction based mode or not is identified and statement is binlogged accordingly.
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/suite/binlog/r/binlog_truncate_kill.result33
-rw-r--r--mysql-test/suite/binlog/t/binlog_truncate_kill.test56
2 files changed, 89 insertions, 0 deletions
diff --git a/mysql-test/suite/binlog/r/binlog_truncate_kill.result b/mysql-test/suite/binlog/r/binlog_truncate_kill.result
new file mode 100644
index 00000000000..c2ea2e8d404
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_truncate_kill.result
@@ -0,0 +1,33 @@
+RESET MASTER;
+connection default;
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB;
+INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10);
+SET DEBUG_SYNC = "open_and_process_table signal truncate_before_lock wait_for forever";
+TRUNCATE t1;
+connect con1,localhost,root,,;
+SET DEBUG_SYNC = "now wait_for truncate_before_lock";
+SELECT ((@id := id) - id) FROM information_schema.processlist WHERE processlist.info LIKE '%TRUNCATE t1%' AND state LIKE '%open_and_process_table%';
+((@id := id) - id)
+0
+KILL QUERY @id;
+connection default;
+ERROR 70100: Query execution was interrupted
+connection con1;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=1
+master-bin.000001 # Query # # use `test`; INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10)
+master-bin.000001 # Xid # # COMMIT /* XID */
+disconnect con1;
+connection default;
+SELECT * FROM t1;
+id a b
+1 1 2
+2 2 4
+3 3 6
+4 4 8
+5 5 10
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/suite/binlog/t/binlog_truncate_kill.test b/mysql-test/suite/binlog/t/binlog_truncate_kill.test
new file mode 100644
index 00000000000..ffbccfa536f
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_truncate_kill.test
@@ -0,0 +1,56 @@
+###############################################################################
+# Bug#17942050:KILL OF TRUNCATE TABLE WILL LEAD TO BINARY LOG WRITTEN WHILE
+# ROWS REMAINS
+#
+# Problem:
+# ========
+# When truncate table fails while using transactional based engines even
+# though the operation errors out we still continue and log it to binlog.
+# Because of this master has data but the truncate will be written to binary
+# log which will cause inconsistency.
+#
+# Test:
+# =====
+# Make master to wait in "open_table" call during the execution of truncate
+# table command and kill the truncate table from other connection. This causes
+# open table to return an error saying truncate failed during open table. This
+# statement should not be binlogged.
+###############################################################################
+--source include/have_debug_sync.inc
+--source include/have_binlog_format_statement.inc
+RESET MASTER;
+--enable_connect_log
+--connection default
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB;
+INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10);
+SET DEBUG_SYNC = "open_and_process_table signal truncate_before_lock wait_for forever";
+--send TRUNCATE t1
+
+connect(con1,localhost,root,,);
+SET DEBUG_SYNC = "now wait_for truncate_before_lock";
+# Wait for one connection to reach open_and_process_table.
+--let $show_statement= SHOW PROCESSLIST
+--let $field= State
+--let $condition= 'debug sync point: open_and_process_table';
+--source include/wait_show_condition.inc
+
+SELECT ((@id := id) - id) FROM information_schema.processlist WHERE processlist.info LIKE '%TRUNCATE t1%' AND state LIKE '%open_and_process_table%';
+# Test killing from mysql server
+KILL QUERY @id;
+
+connection default;
+--ERROR ER_QUERY_INTERRUPTED
+--reap
+
+connection con1;
+--source include/show_binlog_events.inc
+
+disconnect con1;
+--source include/wait_until_disconnected.inc
+connection default;
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';
+--disable_connect_log