mirror of
https://github.com/MariaDB/server.git
synced 2025-01-27 01:04:19 +01:00
2fb387b084
errors In the fix of BUG#39934 in 5.1-rep+3, errors are generated when binlog_format=row and a statement modifies a table restricted to statement-logging (ER_BINLOG_ROW_MODE_AND_STMT_ENGINE); or if binlog_format=statement and a statement modifies a table restricted to row-logging (ER_BINLOG_STMT_MODE_AND_ROW_ENGINE). However, some DDL statements that lock tables (e.g. ALTER TABLE, CREATE INDEX and CREATE TRIGGER) were causing spurious errors, although no row might be inserted into the binary log. To fix the problem, we tagged statements that may generate rows into the binary log and thence the warning messages are only printed out when the appropriate conditions hold and rows might be changed. sql/log_event.cc: Reorganized the Query_log_event's constructor based on the CF_CAN_GENERATE_ROW_EVENTS flag and as such any statement that has the associated flag should go through a cache before being written to the binary log. sql/share/errmsg-utf8.txt: Improved the error message ER_BINLOG_UNSAFE_MIXED_STATEMENT according to Paul's suggestion. sql/sql_class.cc: Created a hook to be used by innodb that checks if a statement may write rows to the binary log. In other words, if it has the CF_CAN_GENERATE_ROW_EVENTS flag associated. sql/sql_class.h: Defined the CF_CAN_GENERATE_ROW_EVENTS flag. sql/sql_parse.cc: Updated the sql_command_flags and added a function to check the CF_CAN_GENERATE_ROW_EVENTS. sql/sql_parse.h: Added a function to check the CF_CAN_GENERATE_ROW_EVENTS. storage/innobase/handler/ha_innodb.cc: Added a call to the hook thd_generates_rows(). storage/innobase/handler/ha_innodb.h: Defined an external reference to the hook thd_generates_rows().
240 lines
12 KiB
Text
240 lines
12 KiB
Text
stop slave;
|
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
|
reset master;
|
|
reset slave;
|
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
|
start slave;
|
|
CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
|
########################################################################
|
|
# VERIFY ITEMS 1 and 2
|
|
########################################################################
|
|
#
|
|
# Create temporary tables to verify when statements involving temporary
|
|
# tables are classified as safe or unsafe by printing out the warning
|
|
# messages.
|
|
#
|
|
CREATE TABLE t_myisam(id int) engine= MyIsam;
|
|
INSERT INTO t_myisam VALUES(1);
|
|
CREATE TABLE t_innodb(id int) engine= Innodb;
|
|
INSERT INTO t_innodb VALUES(1);
|
|
CREATE TEMPORARY TABLE t_myisam_temp(id int) engine= MyIsam;
|
|
INSERT INTO t_myisam_temp VALUES(1);
|
|
CREATE TEMPORARY TABLE t_innodb_temp(id int) engine= Innodb;
|
|
INSERT INTO t_innodb_temp VALUES(1);
|
|
BEGIN;
|
|
INSERT INTO t_myisam SELECT * FROM t_myisam_temp;
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them.
|
|
INSERT INTO t_innodb SELECT * FROM t_myisam_temp;
|
|
INSERT INTO t_innodb SELECT * FROM t_innodb_temp;
|
|
ROLLBACK;
|
|
Warnings:
|
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
BEGIN;
|
|
INSERT INTO t_myisam SELECT * FROM t_innodb_temp;
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them.
|
|
INSERT INTO t_innodb SELECT * FROM t_myisam_temp;
|
|
INSERT INTO t_innodb SELECT * FROM t_innodb_temp;
|
|
ROLLBACK;
|
|
Warnings:
|
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
########################################################################
|
|
# VERIFY ITEM 3
|
|
########################################################################
|
|
#
|
|
# When there is a temporary table we can switch between the mixed and
|
|
# row formats. However, we cannot switch to the statement format.
|
|
#
|
|
SET BINLOG_FORMAT=MIXED;
|
|
SET BINLOG_FORMAT=ROW;
|
|
SET BINLOG_FORMAT=MIXED;
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
|
|
#
|
|
# When there is a temporary table we can switch between the mixed and
|
|
# row formats. However, we cannot swith to the statement format.
|
|
#
|
|
SET BINLOG_FORMAT=MIXED;
|
|
DROP TABLE t_myisam_temp, t_innodb_temp, t_myisam, t_innodb;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam SELECT * FROM t_myisam_temp
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb SELECT * FROM t_myisam_temp
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb SELECT * FROM t_innodb_temp
|
|
master-bin.000001 # Query # # ROLLBACK
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam SELECT * FROM t_innodb_temp
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb SELECT * FROM t_myisam_temp
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb SELECT * FROM t_innodb_temp
|
|
master-bin.000001 # Query # # ROLLBACK
|
|
master-bin.000001 # Query # # use `test`; DROP TABLE `t_myisam`,`t_innodb` /* generated by server */
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t_myisam_temp`,`t_innodb_temp` /* generated by server */
|
|
########################################################################
|
|
# VERIFY ITEMS 4 and 5
|
|
########################################################################
|
|
#
|
|
BEGIN;
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
INSERT INTO tmp1 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp1;
|
|
DROP TEMPORARY TABLE tmp2;
|
|
DROP TEMPORARY TABLE tmp3;
|
|
COMMIT;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO tmp1 VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 LIKE tmp1
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO tmp2 VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO tmp3 VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE tmp1
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE tmp2
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE tmp3
|
|
master-bin.000001 # Query # # COMMIT
|
|
BEGIN;
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
INSERT INTO tmp1 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp1;
|
|
DROP TEMPORARY TABLE tmp2;
|
|
DROP TEMPORARY TABLE tmp3;
|
|
ROLLBACK;
|
|
Warnings:
|
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO tmp1 VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 LIKE tmp1
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO tmp2 VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO tmp3 VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE tmp1
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE tmp2
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE tmp3
|
|
master-bin.000001 # Query # # ROLLBACK
|
|
########################################################################
|
|
# VERIFY ITEM 6
|
|
########################################################################
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
SET BINLOG_FORMAT=ROW;
|
|
DROP TEMPORARY TABLE tmp1;
|
|
BEGIN;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp2;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp3;
|
|
COMMIT;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 LIKE tmp1
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp1` /* generated by server */
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp2` /* generated by server */
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp3` /* generated by server */
|
|
master-bin.000001 # Query # # COMMIT
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
SET BINLOG_FORMAT=ROW;
|
|
DROP TEMPORARY TABLE tmp1;
|
|
BEGIN;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp2;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp3;
|
|
ROLLBACK;
|
|
Warnings:
|
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 LIKE tmp1
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp1` /* generated by server */
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp2` /* generated by server */
|
|
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp3` /* generated by server */
|
|
master-bin.000001 # Query # # ROLLBACK
|
|
########################################################################
|
|
# VERIFY ITEM 7
|
|
########################################################################
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
CREATE TABLE t_myisam (f1 BIGINT) ENGINE = MyISAM;
|
|
CREATE TABLE t_innodb (f1 BIGINT) ENGINE = Innodb;
|
|
BEGIN;
|
|
INSERT INTO t_myisam VALUES(CONNECTION_ID());
|
|
INSERT INTO tmp1 VALUES(1);
|
|
INSERT INTO t_myisam VALUES(1);
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
|
|
INSERT INTO t_innodb VALUES(1);
|
|
INSERT INTO t_myisam VALUES(CONNECTION_ID());
|
|
Warnings:
|
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
|
|
INSERT INTO t_innodb VALUES(1);
|
|
COMMIT;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam
|
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t_myisam (f1 BIGINT) ENGINE = MyISAM
|
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t_innodb (f1 BIGINT) ENGINE = Innodb
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam VALUES(CONNECTION_ID())
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam VALUES(1)
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam VALUES(CONNECTION_ID())
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO tmp1 VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb VALUES(1)
|
|
master-bin.000001 # Xid # # COMMIT /* XID */
|
|
########################################################################
|
|
# VERIFY ITEM 8
|
|
########################################################################
|
|
SET BINLOG_FORMAT=MIXED;
|
|
BEGIN;
|
|
CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb;
|
|
INSERT INTO t_innodb VALUES(1);
|
|
INSERT INTO t_innodb VALUES(1);
|
|
ROLLBACK;
|
|
Warnings:
|
|
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb VALUES(1)
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb VALUES(1)
|
|
master-bin.000001 # Query # # ROLLBACK
|
|
###################################################################################
|
|
# CHECK CONSISTENCY
|
|
###################################################################################
|
|
###################################################################################
|
|
# CLEAN UP
|
|
###################################################################################
|
|
DROP TABLE t_myisam;
|
|
DROP TABLE t_innodb;
|