Commit f19b3a43 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

merge

parents 2980cd60 b6ece6aa
# BUG #36763: TRUNCATE TABLE fails to replicate when stmt-based
# binlogging is not supported.
# This should always be logged as a statement, even when executed as a
# row-by-row deletion.
# $before_truncate A statement to execute (just) before issuing the
# TRUNCATE TABLE
eval CREATE TABLE t1 (a INT) ENGINE=$engine;
eval CREATE TABLE t2 (a INT) ENGINE=$engine;
INSERT INTO t2 VALUES (1),(2),(3);
let $binlog_start = query_get_value("SHOW MASTER STATUS", Position, 1);
if (`select length('$before_truncate') > 0`) {
eval $before_truncate;
}
--echo **** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
if (`select length('$before_truncate') > 0`) {
eval $before_truncate;
}
TRUNCATE TABLE t2;
source include/show_binlog_events.inc;
DROP TABLE t1,t2;
......@@ -9,27 +9,8 @@
--source include/master-slave.inc
let $format = STATEMENT;
let $stmt = TRUNCATE TABLE;
let $trunc_stmt = TRUNCATE TABLE;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = MIXED;
let $stmt = TRUNCATE TABLE;
let $trunc_stmt = DELETE FROM;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = ROW;
let $stmt = TRUNCATE TABLE;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = STATEMENT;
let $stmt = DELETE FROM;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = MIXED;
let $stmt = DELETE FROM;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = ROW;
let $stmt = DELETE FROM;
--source extra/rpl_tests/rpl_truncate_helper.test
connection slave;
STOP SLAVE;
source include/wait_for_slave_to_stop.inc;
connection master;
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
connection slave;
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
RESET SLAVE;
START SLAVE;
source include/reset_master_and_slave.inc;
--echo **** On Master ****
connection master;
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
eval SET SESSION BINLOG_FORMAT=$format;
eval SET GLOBAL BINLOG_FORMAT=$format;
eval CREATE TABLE t1 (a INT, b LONG) ENGINE=$engine;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
--echo **** On Slave ****
sync_slave_with_master;
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
--echo **** On Master ****
connection master;
eval $stmt t1;
SELECT * FROM t1;
--echo **** On Slave ****
eval $trunc_stmt t1;
sync_slave_with_master;
# Should be empty
SELECT * FROM t1;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
--echo ==== Test using a table with delete triggers ====
--echo **** On Master ****
connection master;
DROP TABLE t1;
let $SERVER_VERSION=`select version()`;
source include/show_binlog_events.inc;
SET @count := 1;
eval CREATE TABLE t2 (a INT, b LONG) ENGINE=$engine;
CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
sync_slave_with_master;
--echo **** On Master ****
connection master;
eval $trunc_stmt t1;
sync_slave_with_master;
let $diff_table_1=master:test.t2;
let $diff_table_2=slave:test.t2;
source include/diff_tables.inc;
connection master;
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
DROP TABLE t1,t2;
sync_slave_with_master;
......@@ -45,8 +45,8 @@ BEGIN {
print "=======================================================\n";
print " WARNING: Using mysql-test-run.pl version 1! \n";
print "=======================================================\n";
require "lib/v1/mysql-test-run.pl";
exit(1);
# Should use exec() here on *nix but this appears not to work on Windows
exit(system($^X, "lib/v1/mysql-test-run.pl", @ARGV) >> 8);
}
elsif ( $version == 2 )
{
......
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2),(3);
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
......@@ -220,3 +220,10 @@ Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
DROP PROCEDURE p1;
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a VARCHAR(100), b VARCHAR(100));
INSERT INTO t1 VALUES ('a','b');
UPDATE t1 SET b = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s' WHERE a = 'a' LIMIT 1;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
DROP TABLE t1;
--loose-innodb
\ No newline at end of file
source include/have_log_bin.inc;
source include/have_innodb.inc;
let $engine = InnoDB;
source extra/binlog_tests/binlog_truncate.test;
# Under transaction isolation level READ UNCOMMITTED and READ
# COMMITTED, InnoDB does not permit statement-based replication of
# row-deleting statement. In these cases, TRUNCATE TABLE should still
# be replicated as a statement.
let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
source extra/binlog_tests/binlog_truncate.test;
let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
source extra/binlog_tests/binlog_truncate.test;
let $before_truncate = SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
source extra/binlog_tests/binlog_truncate.test;
let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
source extra/binlog_tests/binlog_truncate.test;
source include/have_log_bin.inc;
let $engine = MyISAM;
source extra/binlog_tests/binlog_truncate.test;
......@@ -257,3 +257,17 @@ delimiter ;|
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
#
# Bug#42634: % character in query can cause mysqld signal 11 segfault
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a VARCHAR(100), b VARCHAR(100));
INSERT INTO t1 VALUES ('a','b');
UPDATE t1 SET b = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s' WHERE a = 'a' LIMIT 1;
DROP TABLE t1;
......@@ -9,3 +9,5 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763
......@@ -4,265 +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;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
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
**** 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;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
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
**** 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;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
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
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`; 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;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
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;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
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
**** 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;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
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
**** 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;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
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
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
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;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
Comparing tables master:test.t2 and slave:test.t2
DROP TABLE t1,t2;
......@@ -4,283 +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;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
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=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
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=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
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=InnoDB;
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=InnoDB
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 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
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;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
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
**** 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=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
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=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
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=InnoDB;
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
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=InnoDB
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 # Xid # # COMMIT /* XID */
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 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
Comparing tables master:test.t2 and slave:test.t2
DROP TABLE t1,t2;
......@@ -5103,8 +5103,15 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
{
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
{
handler::Table_flags flags_some_set= handler::Table_flags();
handler::Table_flags flags_all_set= ~handler::Table_flags();
/*
Compute the starting vectors for the computations by creating a
set with all the capabilities bits set and one with no
capabilities bits set.
*/
handler::Table_flags flags_some_set= 0;
handler::Table_flags flags_all_set=
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE;
my_bool multi_engine= FALSE;
void* prev_ht= NULL;
for (TABLE_LIST *table= tables; table; table= table->next_global)
......
......@@ -3660,16 +3660,14 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
if (lex->is_stmt_unsafe() &&
variables.binlog_format == BINLOG_FORMAT_STMT)
{
DBUG_ASSERT(this->query != NULL);
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_UNSAFE_STATEMENT,
ER(ER_BINLOG_UNSAFE_STATEMENT));
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
{
char warn_buf[MYSQL_ERRMSG_SIZE];
my_snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s",
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
sql_print_warning(warn_buf);
sql_print_warning("%s Statement: %.*s",
ER(ER_BINLOG_UNSAFE_STATEMENT),
MYSQL_ERRMSG_SIZE, query_arg);
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
}
}
......
......@@ -51,6 +51,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
THD::killed_state killed_status= THD::NOT_KILLED;
DBUG_ENTER("mysql_delete");
THD::enum_binlog_query_type query_type=
thd->lex->sql_command == SQLCOM_TRUNCATE ?
THD::STMT_QUERY_TYPE :
THD::ROW_QUERY_TYPE;
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
if (!(table= table_list->table))
......@@ -135,6 +140,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
if (!(error=table->file->ha_delete_all_rows()))
{
/*
If delete_all_rows() is used, it is not possible to log the
query in row format, so we have to log it in statement format.
*/
query_type= THD::STMT_QUERY_TYPE;
error= -1; // ok
deleted= maybe_deleted;
goto cleanup;
......@@ -374,6 +384,11 @@ cleanup:
{
if (mysql_bin_log.is_open())
{
bool const is_trans=
thd->lex->sql_command == SQLCOM_TRUNCATE ?
FALSE :
transactional_table;
if (error < 0)
thd->clear_error();
/*
......@@ -381,10 +396,13 @@ cleanup:
storage engine does not inject the rows itself, we replicate
statement-based; otherwise, 'ha_delete_row()' was used to
delete specific rows which we might log row-based.
Note that TRUNCATE TABLE is not transactional and should
therefore be treated as a DDL.
*/
int log_result= thd->binlog_query(THD::ROW_QUERY_TYPE,
int log_result= thd->binlog_query(query_type,
thd->query, thd->query_length,
transactional_table, FALSE, killed_status);
is_trans, FALSE, killed_status);
if (log_result && transactional_table)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment