Commit b17a310a authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

merge

parents 20e57195 46f91045
# 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 @@ ...@@ -9,27 +9,8 @@
--source include/master-slave.inc --source include/master-slave.inc
let $format = STATEMENT; let $trunc_stmt = TRUNCATE TABLE;
let $stmt = TRUNCATE TABLE;
--source extra/rpl_tests/rpl_truncate_helper.test --source extra/rpl_tests/rpl_truncate_helper.test
let $format = MIXED; let $trunc_stmt = DELETE FROM;
let $stmt = TRUNCATE TABLE;
--source extra/rpl_tests/rpl_truncate_helper.test --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; source include/reset_master_and_slave.inc;
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;
--echo **** On Master **** --echo **** On Master ****
connection 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; eval CREATE TABLE t1 (a INT, b LONG) ENGINE=$engine;
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
--echo **** On Slave ****
sync_slave_with_master; sync_slave_with_master;
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
--echo **** On Master **** --echo **** On Master ****
connection master; connection master;
eval $stmt t1; eval $trunc_stmt t1;
SELECT * FROM t1;
--echo **** On Slave ****
sync_slave_with_master; 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 **** --echo **** On Master ****
connection master; connection master;
DROP TABLE t1; SET @count := 1;
let $SERVER_VERSION=`select version()`; eval CREATE TABLE t2 (a INT, b LONG) ENGINE=$engine;
source include/show_binlog_events.inc; 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; connection master;
RESET MASTER; DROP TABLE t1,t2;
SET @@session.binlog_format= @old_session_binlog_format; sync_slave_with_master;
SET @@global.binlog_format= @old_global_binlog_format;
...@@ -45,8 +45,8 @@ BEGIN { ...@@ -45,8 +45,8 @@ BEGIN {
print "=======================================================\n"; print "=======================================================\n";
print " WARNING: Using mysql-test-run.pl version 1! \n"; print " WARNING: Using mysql-test-run.pl version 1! \n";
print "=======================================================\n"; print "=======================================================\n";
require "lib/v1/mysql-test-run.pl"; # Should use exec() here on *nix but this appears not to work on Windows
exit(1); exit(system($^X, "lib/v1/mysql-test-run.pl", @ARGV) >> 8);
} }
elsif ( $version == 2 ) 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. ...@@ -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. Warning 1592 Statement is not safe to log in statement format.
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1; 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 ;| ...@@ -257,3 +257,17 @@ delimiter ;|
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1; 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 @@ ...@@ -9,3 +9,5 @@
# Do not use any TAB characters for whitespace. # 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; ...@@ -4,265 +4,43 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
**** Resetting master and slave ****
STOP SLAVE; STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE; 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; 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; START SLAVE;
**** On Master **** **** 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; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2); 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 **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=MyISAM;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
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
**** On Master **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** On Slave **** **** Resetting master and 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;
STOP SLAVE; STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE; 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; 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; START SLAVE;
**** On Master **** **** 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; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2); 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 **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=MyISAM;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
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
**** On Master **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** 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;
...@@ -4,283 +4,43 @@ reset master; ...@@ -4,283 +4,43 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
**** Resetting master and slave ****
STOP SLAVE; STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE; 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; 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; START SLAVE;
**** On Master **** **** 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; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2); 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 **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=InnoDB;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
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
**** On Master **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** On Slave **** **** Resetting master and 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;
STOP SLAVE; STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE; 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; 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; START SLAVE;
**** On Master **** **** 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; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2); 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 **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=InnoDB;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
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
**** On Master **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** 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;
...@@ -5103,8 +5103,15 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) ...@@ -5103,8 +5103,15 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
{ {
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) 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; my_bool multi_engine= FALSE;
void* prev_ht= NULL; void* prev_ht= NULL;
for (TABLE_LIST *table= tables; table; table= table->next_global) 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, ...@@ -3660,16 +3660,14 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
if (lex->is_stmt_unsafe() && if (lex->is_stmt_unsafe() &&
variables.binlog_format == BINLOG_FORMAT_STMT) variables.binlog_format == BINLOG_FORMAT_STMT)
{ {
DBUG_ASSERT(this->query != NULL);
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BINLOG_UNSAFE_STATEMENT, ER_BINLOG_UNSAFE_STATEMENT,
ER(ER_BINLOG_UNSAFE_STATEMENT)); ER(ER_BINLOG_UNSAFE_STATEMENT));
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED)) if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
{ {
char warn_buf[MYSQL_ERRMSG_SIZE]; sql_print_warning("%s Statement: %.*s",
my_snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s", ER(ER_BINLOG_UNSAFE_STATEMENT),
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query); MYSQL_ERRMSG_SIZE, query_arg);
sql_print_warning(warn_buf);
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED; binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
} }
} }
......
...@@ -51,6 +51,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -51,6 +51,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
THD::killed_state killed_status= THD::NOT_KILLED; THD::killed_state killed_status= THD::NOT_KILLED;
DBUG_ENTER("mysql_delete"); 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)) if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (!(table= table_list->table)) if (!(table= table_list->table))
...@@ -135,6 +140,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -135,6 +140,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_PRINT("debug", ("Trying to use delete_all_rows()")); DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
if (!(error=table->file->ha_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 error= -1; // ok
deleted= maybe_deleted; deleted= maybe_deleted;
goto cleanup; goto cleanup;
...@@ -374,6 +384,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -374,6 +384,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{ {
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
bool const is_trans=
thd->lex->sql_command == SQLCOM_TRUNCATE ?
FALSE :
transactional_table;
if (error < 0) if (error < 0)
thd->clear_error(); thd->clear_error();
/* /*
...@@ -381,10 +396,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -381,10 +396,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
storage engine does not inject the rows itself, we replicate storage engine does not inject the rows itself, we replicate
statement-based; otherwise, 'ha_delete_row()' was used to statement-based; otherwise, 'ha_delete_row()' was used to
delete specific rows which we might log row-based. 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, thd->query, thd->query_length,
transactional_table, FALSE, killed_status); is_trans, FALSE, killed_status);
if (log_result && transactional_table) 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