1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00
TRUNCATE TABLE fails to replicate when stmt-based binlogging is not supported.

There were two separate problems with the code, both of which are fixed with
this patch:

1. An error was printed by InnoDB for TRUNCATE TABLE in statement mode when
   the in isolation levels READ COMMITTED and READ UNCOMMITTED since InnoDB
   does permit statement-based replication for DML statements. However,
   the TRUNCATE TABLE is not transactional, but is a DDL, and should therefore
   be allowed to be replicated as a statement.

2. The statement was not logged in mixed mode because of the error above, but
   the error was not reported to the client.

This patch fixes the problem by treating TRUNCATE TABLE a DDL, that is, it is
always logged as a statement and not reporting an error from InnoDB for TRUNCATE
TABLE.


mysql-test/extra/binlog_tests/binlog_truncate.test:
  Adding new test to check that TRUNCATE TABLE is written correctly
  to the binary log.
mysql-test/extra/rpl_tests/rpl_truncate.test:
  Removing redundant testing by eliminating settings of BINLOG_FORMAT.
mysql-test/extra/rpl_tests/rpl_truncate_helper.test:
  Replacing slave and master reset code with include file.
  Removing settings of BINLOG_FORMAT.
  Replacing printing of table contents to compare master and slave
  with diff_tables.inc.
mysql-test/suite/binlog/t/binlog_truncate_innodb.test:
  Adding test for testing that TRUNCATE TABLE is logged correctly for InnoDB
  in all isolation levels.
mysql-test/suite/binlog/t/binlog_truncate_myisam.test:
  Adding test for testing that TRUNCATE TABLE is logged correctly for MyISAM.
mysql-test/suite/binlog/t/disabled.def:
  Disabling binlog_truncate_innodb since it does not work (yet).
sql/sql_base.cc:
  Correcting setting of capabilities flags to make the comparison with 0
  later in the code work correctly.
sql/sql_delete.cc:
  Re-organizing code to ensure that TRUNCATE TABLE is logged in statement
  format and that row format is not used unless there are rows to log (which
  there are not when delete_all_rows() is called, so this has to be logged
  as a statement).
This commit is contained in:
Mats Kindahl
2009-02-06 17:06:41 +01:00
parent 75e1ed9618
commit bd53d21417
13 changed files with 219 additions and 504 deletions

View File

@ -4,241 +4,43 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
**** Resetting master and slave ****
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
RESET MASTER;
START SLAVE;
**** On Master ****
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
TRUNCATE TABLE t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
Comparing tables master:test.t1 and slave:test.t1
==== Test using a table with delete triggers ====
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
SET @count := 1;
CREATE TABLE t2 (a INT, b LONG) ENGINE=MyISAM;
CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
**** On Master ****
TRUNCATE TABLE t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
Comparing tables master:test.t2 and slave:test.t2
DROP TABLE t1,t2;
**** Resetting master and slave ****
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
RESET MASTER;
START SLAVE;
**** On Master ****
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
TRUNCATE TABLE t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
DELETE FROM t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
Comparing tables master:test.t1 and slave:test.t1
==== Test using a table with delete triggers ====
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
SET @count := 1;
CREATE TABLE t2 (a INT, b LONG) ENGINE=MyISAM;
CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
**** On Master ****
DELETE FROM t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
DELETE FROM t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
3 3
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
Comparing tables master:test.t2 and slave:test.t2
DROP TABLE t1,t2;