rbr and savepoint in a subtatement
Apply MySQL fix for bug#76727: https://github.com/mysql/mysql-server/commit/69d4e72c Bug#20901025: SLAVE ASSERTION IN UNPACK_ROW WITH ROLLBACK TO SAVEPOINT IN ERROR HANDLER
This commit is contained in:
parent
33ab30dfe2
commit
4046ed12bc
53
mysql-test/include/sync_slave_sql_with_master.inc
Normal file
53
mysql-test/include/sync_slave_sql_with_master.inc
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# ==== Purpose ====
|
||||||
|
#
|
||||||
|
# Waits until the slave SQL thread has been synced, i.e., all events
|
||||||
|
# have been copied over to slave. This is like mtr's built-in command
|
||||||
|
# sync_slave_with_master, but more flexible (e.g., you can set a
|
||||||
|
# custom timeout and you can force it to use GTIDs instead of filename
|
||||||
|
# and offset).
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# ==== Usage ====
|
||||||
|
#
|
||||||
|
# [--let $sync_slave_connection= <connection_name>]
|
||||||
|
# [--let $use_gtids= 1]
|
||||||
|
# [--let $slave_timeout= NUMBER]
|
||||||
|
# [--let $rpl_debug= 1]
|
||||||
|
# --source include/sync_slave_io_with_master.inc
|
||||||
|
#
|
||||||
|
# Must be called on the master. Will change connection to the slave.
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
#
|
||||||
|
# $use_gtids
|
||||||
|
# If set, uses GTIDs instead of filename and offset for positions.
|
||||||
|
#
|
||||||
|
# $sync_slave_connection
|
||||||
|
# By default, this script switches connection to 'slave'. If
|
||||||
|
# $sync_slave_connection is set, then '$sync_slave_connection' is
|
||||||
|
# used instead of 'slave'.
|
||||||
|
#
|
||||||
|
# $slave_timeout
|
||||||
|
# See include/wait_for_slave_param.inc.
|
||||||
|
#
|
||||||
|
# $rpl_debug
|
||||||
|
# See include/rpl_init.inc
|
||||||
|
|
||||||
|
|
||||||
|
--let $include_filename= sync_slave_sql_with_master.inc
|
||||||
|
--source include/begin_include_file.inc
|
||||||
|
|
||||||
|
save_master_pos;
|
||||||
|
|
||||||
|
--let $rpl_connection_name= slave
|
||||||
|
if ($sync_slave_connection)
|
||||||
|
{
|
||||||
|
--let $rpl_connection_name= $sync_slave_connection
|
||||||
|
}
|
||||||
|
--source include/rpl_connection.inc
|
||||||
|
|
||||||
|
sync_with_master;
|
||||||
|
|
||||||
|
--let $include_filename= sync_slave_sql_with_master.inc
|
||||||
|
--let $skip_restore_connection= 1
|
||||||
|
--source include/end_include_file.inc
|
502
mysql-test/suite/rpl/r/rpl_row_rollback_to_savepoint.result
Normal file
502
mysql-test/suite/rpl/r/rpl_row_rollback_to_savepoint.result
Normal file
@ -0,0 +1,502 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
#Test case 1:
|
||||||
|
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t3 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB;
|
||||||
|
CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK TO event_logging_1;
|
||||||
|
INSERT t3 VALUES (1);
|
||||||
|
END;
|
||||||
|
SAVEPOINT event_logging_1;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
RELEASE SAVEPOINT event_logging_1;
|
||||||
|
END|
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t3 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK TO event_logging_1;
|
||||||
|
INSERT t3 VALUES (1);
|
||||||
|
END;
|
||||||
|
SAVEPOINT event_logging_1;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
RELEASE SAVEPOINT event_logging_1;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t3)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `event_logging_1`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t3)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
[connection master]
|
||||||
|
DROP TRIGGER tr1;
|
||||||
|
DELETE FROM t1;
|
||||||
|
DELETE FROM t2;
|
||||||
|
DELETE FROM t3;
|
||||||
|
# Test case 2:
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK TO event_logging_2;
|
||||||
|
INSERT t3 VALUES (3);
|
||||||
|
END;
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
RELEASE SAVEPOINT event_logging_2;
|
||||||
|
END|
|
||||||
|
CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW CALL p1()|
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t3 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK TO event_logging_1;
|
||||||
|
INSERT t3 VALUES (1);
|
||||||
|
END;
|
||||||
|
SAVEPOINT event_logging_1;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
RELEASE SAVEPOINT event_logging_1;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t3)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `event_logging_1`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t3)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; DROP TRIGGER tr1
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Delete_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Delete_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t3)
|
||||||
|
master-bin.000001 # Delete_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK TO event_logging_2;
|
||||||
|
INSERT t3 VALUES (3);
|
||||||
|
END;
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
RELEASE SAVEPOINT event_logging_2;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW CALL p1()
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t3)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `event_logging_2`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t3)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
[connection master]
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t3;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
# Test case 3:
|
||||||
|
include/rpl_reset.inc
|
||||||
|
[connection master]
|
||||||
|
CREATE TABLE t (f1 int(10) unsigned NOT NULL, PRIMARY KEY (f1)) ENGINE=InnoDB;
|
||||||
|
CREATE TRIGGER t_insert_trig AFTER INSERT ON t FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
ROLLBACK TO savepoint_1;
|
||||||
|
END |
|
||||||
|
INSERT INTO t VALUES (2);
|
||||||
|
INSERT INTO t VALUES (3);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t (f1 int(10) unsigned NOT NULL, PRIMARY KEY (f1)) ENGINE=InnoDB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER t_insert_trig AFTER INSERT ON t FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
ROLLBACK TO savepoint_1;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `savepoint_1`
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `savepoint_1`
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
SELECT * FROM t;
|
||||||
|
f1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t;
|
||||||
|
f1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
[connection master]
|
||||||
|
DROP TABLE t;
|
||||||
|
# Test case 4:
|
||||||
|
include/rpl_reset.inc
|
||||||
|
[connection master]
|
||||||
|
CREATE TABLE t (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t1 (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
CREATE TRIGGER t_insert_trig BEFORE INSERT ON t FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
INSERT INTO t1 VALUES (5);
|
||||||
|
END |
|
||||||
|
INSERT INTO t VALUES (2), (3);
|
||||||
|
INSERT INTO t1 VALUES (30);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER t_insert_trig BEFORE INSERT ON t FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
INSERT INTO t1 VALUES (5);
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `savepoint_1`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
SELECT * FROM t;
|
||||||
|
f1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
5
|
||||||
|
5
|
||||||
|
30
|
||||||
|
include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t;
|
||||||
|
f1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
5
|
||||||
|
5
|
||||||
|
30
|
||||||
|
[connection master]
|
||||||
|
DROP TABLE t;
|
||||||
|
DROP TABLE t1;
|
||||||
|
# Test case 5:
|
||||||
|
include/rpl_reset.inc
|
||||||
|
[connection master]
|
||||||
|
CREATE TABLE t (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t1 (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
CREATE TRIGGER t_insert_trig BEFORE INSERT ON t
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
END |
|
||||||
|
INSERT INTO t VALUES (2), (3);
|
||||||
|
INSERT INTO t1 VALUES (30);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER t_insert_trig BEFORE INSERT ON t
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `savepoint_1`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
SELECT * FROM t;
|
||||||
|
f1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
30
|
||||||
|
include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t;
|
||||||
|
f1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
30
|
||||||
|
[connection master]
|
||||||
|
DROP TABLE t;
|
||||||
|
DROP TABLE t1;
|
||||||
|
# Test case 6:
|
||||||
|
include/rpl_reset.inc
|
||||||
|
[connection master]
|
||||||
|
CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
CREATE FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
ROLLBACK TO event_logging_2;
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t2 VALUES (1), (f1()), (2), (4);
|
||||||
|
COMMIT;
|
||||||
|
INSERT INTO t2 VALUES (10);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f1 INTEGER ) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
ROLLBACK TO event_logging_2;
|
||||||
|
RETURN 0;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `event_logging_2`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
[connection master]
|
||||||
|
SELECT * FROM t2;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
4
|
||||||
|
10
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t2;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
4
|
||||||
|
10
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
[connection master]
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
# Test case 7:
|
||||||
|
include/rpl_reset.inc
|
||||||
|
[connection master]
|
||||||
|
CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
CREATE FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t2 VALUES (1), (f1()), (2), (4);
|
||||||
|
COMMIT;
|
||||||
|
INSERT INTO t2 VALUES (10);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f1 INTEGER ) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
RETURN 0;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `event_logging_2`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: #
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
[connection master]
|
||||||
|
SELECT * FROM t2;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
4
|
||||||
|
10
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t2;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
4
|
||||||
|
10
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
[connection master]
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
# Test case 8:
|
||||||
|
include/rpl_reset.inc
|
||||||
|
[connection master]
|
||||||
|
CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
CREATE FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (1), (f1()), (2), (4);
|
||||||
|
COMMIT;
|
||||||
|
INSERT INTO t1 VALUES (10);
|
||||||
|
include/show_binlog_events.inc
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB
|
||||||
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
RETURN 0;
|
||||||
|
END
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Query # # SAVEPOINT `event_logging_2`
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||||
|
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
|
||||||
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
||||||
|
[connection master]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
4
|
||||||
|
10
|
||||||
|
include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t1;
|
||||||
|
f1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
4
|
||||||
|
10
|
||||||
|
[connection master]
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
include/rpl_end.inc
|
312
mysql-test/suite/rpl/t/rpl_row_rollback_to_savepoint.test
Normal file
312
mysql-test/suite/rpl/t/rpl_row_rollback_to_savepoint.test
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Bug#76727: SLAVE ASSERTION IN UNPACK_ROW WITH ROLLBACK TO
|
||||||
|
# SAVEPOINT IN ERROR HANDLER
|
||||||
|
#
|
||||||
|
# Problem:
|
||||||
|
# ========
|
||||||
|
# "SAVEPOINT", "ROLLBACK TO savepoint" wipe out table map on slave during
|
||||||
|
# execution binary log events. For trigger the map is written to binary log once
|
||||||
|
# for all trigger body and if trigger contains "SAVEPOINT" or
|
||||||
|
# "ROLLBACK TO savepoint" statements any trigger's events after these
|
||||||
|
# statements will not have table map. This results in an assert on slave.
|
||||||
|
#
|
||||||
|
# Test:
|
||||||
|
# =====
|
||||||
|
# Test case 1:
|
||||||
|
# Create a trigger with exception handler which rolls back to a savepoint.
|
||||||
|
# Test proves that there will not be any assert during execution of rolling
|
||||||
|
# back to savepoint.
|
||||||
|
#
|
||||||
|
# Test case 2:
|
||||||
|
# Create a trigger which calls a procedure which in turn calls an exception
|
||||||
|
# handler which rolls back to a savepoint. Prove that it doesn't cause any
|
||||||
|
# assertion during execution.
|
||||||
|
#
|
||||||
|
# Test case 3:
|
||||||
|
# Create a simple trigger which does SAVEPOINT and ROLLBACK TO SAVEPOINT
|
||||||
|
# and doesn't follow with any other DML statement. Prove that it doesn't cause
|
||||||
|
# any assertion during execution.
|
||||||
|
#
|
||||||
|
# Test case 4:
|
||||||
|
# Create a trigger with SAVEPOINT and follows with a DML without ROLLBACK TO
|
||||||
|
# savepoint. Ensure that data is replicated properly.
|
||||||
|
#
|
||||||
|
# Test case 5:
|
||||||
|
# Create a trigger with SAVEPOINT and it does nothing. Do few DMLs following
|
||||||
|
# the trigger ensure that the data is replicated properly
|
||||||
|
#
|
||||||
|
# Test case 6:
|
||||||
|
# Create a stored function which does SAVEPOINT and ROLLBACK TO
|
||||||
|
# SAVEPOINT. Do few inserts following the stored function call and ensure that
|
||||||
|
# no assert is generated on slave and all the rows are replicated to slave.
|
||||||
|
#
|
||||||
|
# Test case 7:
|
||||||
|
# Create a stored function which creates a SAVEPOINT alone and follows with
|
||||||
|
# DMLs without ROLLBACK TO savepoint. Ensure that data is replicated properly.
|
||||||
|
#
|
||||||
|
# Test case 8:
|
||||||
|
# Create a stored function which has SAVEPOINT inside it and does noting. It
|
||||||
|
# should follow with other DMLs. Ensure that data is replicated properly.
|
||||||
|
###############################################################################
|
||||||
|
--source include/have_binlog_format_row.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
--echo #Test case 1:
|
||||||
|
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t3 (f1 INTEGER PRIMARY KEY) ENGINE=INNODB;
|
||||||
|
DELIMITER |;
|
||||||
|
|
||||||
|
CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK TO event_logging_1;
|
||||||
|
INSERT t3 VALUES (1);
|
||||||
|
END;
|
||||||
|
SAVEPOINT event_logging_1;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
RELEASE SAVEPOINT event_logging_1;
|
||||||
|
END|
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
|
||||||
|
DROP TRIGGER tr1;
|
||||||
|
DELETE FROM t1;
|
||||||
|
DELETE FROM t2;
|
||||||
|
DELETE FROM t3;
|
||||||
|
|
||||||
|
--echo # Test case 2:
|
||||||
|
|
||||||
|
DELIMITER |;
|
||||||
|
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK TO event_logging_2;
|
||||||
|
INSERT t3 VALUES (3);
|
||||||
|
END;
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
RELEASE SAVEPOINT event_logging_2;
|
||||||
|
END|
|
||||||
|
|
||||||
|
CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW CALL p1()|
|
||||||
|
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t3;
|
||||||
|
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
|
||||||
|
--echo # Test case 3:
|
||||||
|
--source include/rpl_reset.inc
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
|
||||||
|
CREATE TABLE t (f1 int(10) unsigned NOT NULL, PRIMARY KEY (f1)) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
--delimiter |
|
||||||
|
CREATE TRIGGER t_insert_trig AFTER INSERT ON t FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
ROLLBACK TO savepoint_1;
|
||||||
|
END |
|
||||||
|
--delimiter ;
|
||||||
|
|
||||||
|
INSERT INTO t VALUES (2);
|
||||||
|
INSERT INTO t VALUES (3);
|
||||||
|
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
SELECT * FROM t;
|
||||||
|
|
||||||
|
--source include/sync_slave_sql_with_master.inc
|
||||||
|
|
||||||
|
SELECT * FROM t;
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
DROP TABLE t;
|
||||||
|
|
||||||
|
--echo # Test case 4:
|
||||||
|
--source include/rpl_reset.inc
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
CREATE TABLE t (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t1 (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
--delimiter |
|
||||||
|
CREATE TRIGGER t_insert_trig BEFORE INSERT ON t FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
INSERT INTO t1 VALUES (5);
|
||||||
|
END |
|
||||||
|
--delimiter ;
|
||||||
|
|
||||||
|
INSERT INTO t VALUES (2), (3);
|
||||||
|
INSERT INTO t1 VALUES (30);
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
SELECT * FROM t;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--source include/sync_slave_sql_with_master.inc
|
||||||
|
|
||||||
|
SELECT * FROM t;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
DROP TABLE t;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo # Test case 5:
|
||||||
|
--source include/rpl_reset.inc
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
CREATE TABLE t (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t1 (f1 int(10) unsigned NOT NULL) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
--delimiter |
|
||||||
|
CREATE TRIGGER t_insert_trig BEFORE INSERT ON t
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
SAVEPOINT savepoint_1;
|
||||||
|
END |
|
||||||
|
|
||||||
|
--delimiter ;
|
||||||
|
|
||||||
|
INSERT INTO t VALUES (2), (3);
|
||||||
|
INSERT INTO t1 VALUES (30);
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
SELECT * FROM t;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--source include/sync_slave_sql_with_master.inc
|
||||||
|
|
||||||
|
SELECT * FROM t;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
DROP TABLE t;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo # Test case 6:
|
||||||
|
--source include/rpl_reset.inc
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
|
||||||
|
--delimiter |
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
ROLLBACK TO event_logging_2;
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
|
||||||
|
--delimiter ;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t2 VALUES (1), (f1()), (2), (4);
|
||||||
|
COMMIT;
|
||||||
|
INSERT INTO t2 VALUES (10);
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--source include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
|
--echo # Test case 7:
|
||||||
|
--source include/rpl_reset.inc
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
|
||||||
|
--delimiter |
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
|
||||||
|
--delimiter ;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t2 VALUES (1), (f1()), (2), (4);
|
||||||
|
COMMIT;
|
||||||
|
INSERT INTO t2 VALUES (10);
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--source include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
|
--echo # Test case 8:
|
||||||
|
--source include/rpl_reset.inc
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
CREATE TABLE t1 (f1 INTEGER ) ENGINE=INNODB;
|
||||||
|
|
||||||
|
--delimiter |
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
SAVEPOINT event_logging_2;
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
|
||||||
|
--delimiter ;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES (1), (f1()), (2), (4);
|
||||||
|
COMMIT;
|
||||||
|
INSERT INTO t1 VALUES (10);
|
||||||
|
--source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--source include/sync_slave_sql_with_master.inc
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--source include/rpl_connection_master.inc
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
|
--source include/rpl_end.inc
|
25
sql/log.cc
25
sql/log.cc
@ -2218,6 +2218,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
String log_query(buf, sizeof(buf), &my_charset_bin);
|
String log_query(buf, sizeof(buf), &my_charset_bin);
|
||||||
if (log_query.copy(STRING_WITH_LEN("SAVEPOINT "), &my_charset_bin) ||
|
if (log_query.copy(STRING_WITH_LEN("SAVEPOINT "), &my_charset_bin) ||
|
||||||
append_identifier(thd, &log_query,
|
append_identifier(thd, &log_query,
|
||||||
@ -2272,6 +2273,17 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
|
|||||||
|
|
||||||
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
|
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
|
||||||
|
|
||||||
|
/*
|
||||||
|
When a SAVEPOINT is executed inside a stored function/trigger we force the
|
||||||
|
pending event to be flushed with a STMT_END_F flag and clear the table maps
|
||||||
|
as well to ensure that following DMLs will have a clean state to start
|
||||||
|
with. ROLLBACK inside a stored routine has to finalize possibly existing
|
||||||
|
current row-based pending event with cleaning up table maps. That ensures
|
||||||
|
that following DMLs will have a clean state to start with.
|
||||||
|
*/
|
||||||
|
if (thd->in_sub_stmt)
|
||||||
|
thd->clear_binlog_table_maps();
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6043,10 +6055,17 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
|
|||||||
/*
|
/*
|
||||||
We only end the statement if we are in a top-level statement. If
|
We only end the statement if we are in a top-level statement. If
|
||||||
we are inside a stored function, we do not end the statement since
|
we are inside a stored function, we do not end the statement since
|
||||||
this will close all tables on the slave.
|
this will close all tables on the slave. But there can be a special case
|
||||||
|
where we are inside a stored function/trigger and a SAVEPOINT is being
|
||||||
|
set in side the stored function/trigger. This SAVEPOINT execution will
|
||||||
|
force the pending event to be flushed without an STMT_END_F flag. This
|
||||||
|
will result in a case where following DMLs will be considered as part of
|
||||||
|
same statement and result in data loss on slave. Hence in this case we
|
||||||
|
force the end_stmt to be true.
|
||||||
*/
|
*/
|
||||||
bool const end_stmt=
|
bool const end_stmt= (thd->in_sub_stmt && thd->lex->sql_command ==
|
||||||
thd->locked_tables_mode && thd->lex->requires_prelocking();
|
SQLCOM_SAVEPOINT) ? true :
|
||||||
|
(thd->locked_tables_mode && thd->lex->requires_prelocking());
|
||||||
if (thd->binlog_flush_pending_rows_event(end_stmt, using_trans))
|
if (thd->binlog_flush_pending_rows_event(end_stmt, using_trans))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user