BUG#50312 Warnings for unsafe sub-statement not returned to client
After BUG#36649, warnings for sub-statements are cleared when a new sub-statement is started. This is problematic since it suppresses warnings for unsafe statements in some cases. It is important that we always give a warning to the client, because the user needs to know when there is a risk that the slave goes out of sync. We fixed the problem by generating warning messages for unsafe statements while returning from a stored procedure, function, trigger or while executing a top level statement. We also started checking unsafeness when both performance and log tables are used. This is necessary after the performance schema which does a distinction between performance and log tables.
This commit is contained in:
parent
89ad5fa810
commit
bd3aa7eb78
@ -200,7 +200,7 @@ if (`SELECT $CRC_ARG_type = 1`) {
|
||||
if (`SELECT $CRC_ARG_type = 2`) {
|
||||
# It will be unsafe to call this procedure.
|
||||
--let $CRC_name= proc_$CRC_ARG_level
|
||||
--let $CRC_create= CREATE PROCEDURE $CRC_name() BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); $CRC_ARG_stmt_sidef; END
|
||||
--let $CRC_create= CREATE PROCEDURE $CRC_name() BEGIN $CRC_ARG_stmt_sidef; INSERT INTO ta$CRC_ARG_level VALUES (47); END
|
||||
--let $CRC_RET_stmt_sidef= CALL $CRC_name()
|
||||
--let $CRC_RET_value=
|
||||
--let $CRC_RET_sel_retval=
|
||||
@ -344,25 +344,8 @@ if (`SELECT '$CRC_RET_stmt_sidef' != ''`) {
|
||||
if (`SELECT '$event_type' != 'Table_map'`) {
|
||||
--enable_query_log
|
||||
--echo ******** Failure! Event number 3 was a '$event_type', not a 'Table_map'. ********
|
||||
|
||||
# Currently, there is a bug causing some statements to be logged
|
||||
# partially in statement format. Hence, we don't fail here, we
|
||||
# just print the events (masking out nondeterministic components
|
||||
# of the output) and continue. When binloggging works perfectly,
|
||||
# we should instead execute:
|
||||
#--enable_query_log
|
||||
#SHOW BINLOG EVENTS;
|
||||
#--die Wrong events in binlog.
|
||||
|
||||
# Here, we should really source
|
||||
# include/show_binlog_events.inc. But due to BUG#41913, that
|
||||
# doesn't work, and we have to inline the entire file here. Sigh
|
||||
# :-(
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR 107 <binlog_start>
|
||||
--replace_column 2 # 4 # 5 #
|
||||
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/
|
||||
--eval SHOW BINLOG EVENTS FROM 107
|
||||
--disable_query_log
|
||||
SHOW BINLOG EVENTS;
|
||||
--die Wrong events in binlog.
|
||||
}
|
||||
SET binlog_format = STATEMENT;
|
||||
|
||||
|
@ -28,6 +28,25 @@ INSERT INTO t1 VALUES (1,2), (2,3);
|
||||
UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
|
||||
UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(1000));
|
||||
INSERT INTO t1 VALUES (CURRENT_USER());
|
||||
INSERT INTO t1 VALUES (FOUND_ROWS());
|
||||
INSERT INTO t1 VALUES (GET_LOCK('tmp', 1));
|
||||
INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp'));
|
||||
INSERT INTO t1 VALUES (IS_USED_LOCK('tmp'));
|
||||
INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat'));
|
||||
INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
|
||||
INSERT INTO t1 VALUES (RELEASE_LOCK('tmp'));
|
||||
INSERT INTO t1 VALUES (ROW_COUNT());
|
||||
INSERT INTO t1 VALUES (SESSION_USER());
|
||||
INSERT INTO t1 VALUES (SLEEP(1));
|
||||
INSERT INTO t1 VALUES (SYSDATE());
|
||||
INSERT INTO t1 VALUES (SYSTEM_USER());
|
||||
INSERT INTO t1 VALUES (USER());
|
||||
INSERT INTO t1 VALUES (UUID());
|
||||
INSERT INTO t1 VALUES (UUID_SHORT());
|
||||
INSERT INTO t1 VALUES (VERSION());
|
||||
INSERT INTO t1 VALUES (RAND());
|
||||
DROP DATABASE b42851;
|
||||
USE test;
|
||||
#
|
||||
@ -67,8 +86,11 @@ Note 1592 Unsafe statement written to the binary log using statement format sinc
|
||||
SELECT sf_bug50192();
|
||||
sf_bug50192()
|
||||
1
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
|
||||
DROP FUNCTION sf_bug50192;
|
||||
DROP TRIGGER tr_bug50192;
|
||||
DROP TABLE t1, t2;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -72,6 +72,26 @@ UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
|
||||
UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a VARCHAR(1000));
|
||||
INSERT INTO t1 VALUES (CURRENT_USER()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (FOUND_ROWS()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (GET_LOCK('tmp', 1)); #marked unsafe in BUG#47995
|
||||
INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp')); #marked unsafe in BUG#47995
|
||||
INSERT INTO t1 VALUES (IS_USED_LOCK('tmp')); #marked unsafe in BUG#47995
|
||||
INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe in BUG#39701
|
||||
INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
|
||||
INSERT INTO t1 VALUES (RELEASE_LOCK('tmp')); #marked unsafe in BUG#47995
|
||||
INSERT INTO t1 VALUES (ROW_COUNT()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (SESSION_USER()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (SLEEP(1)); #marked unsafe in BUG#47995
|
||||
INSERT INTO t1 VALUES (SYSDATE()); #marked unsafe in BUG#47995
|
||||
INSERT INTO t1 VALUES (SYSTEM_USER()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (USER()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995
|
||||
INSERT INTO t1 VALUES (VERSION()); #marked unsafe in BUG#47995
|
||||
INSERT INTO t1 VALUES (RAND()); #marked unsafe in BUG#49222
|
||||
|
||||
# clean up
|
||||
DROP DATABASE b42851;
|
||||
|
||||
|
@ -468,6 +468,7 @@ BEGIN
|
||||
END|
|
||||
DELIMITER ;|
|
||||
--echo "One unsafe warning should be issued in the following statement"
|
||||
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN
|
||||
SELECT fun_check_log_bin();
|
||||
--echo "SQL_LOG_BIN should be ON still"
|
||||
SHOW VARIABLES LIKE "SQL_LOG_BIN";
|
||||
|
@ -11,5 +11,4 @@
|
||||
##############################################################################
|
||||
|
||||
binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763
|
||||
binlog_unsafe : BUG#50312 2010-01-13 lsoares Warnings for unsafe sub-statement not returned to client
|
||||
binlog_spurious_ddl_errors : BUG#54195 2010-06-03 alik binlog_spurious_ddl_errors.test fails, thus disabled
|
||||
|
@ -72,6 +72,8 @@ before call db1.p1()
|
||||
INSERT INTO db1.t2 VALUES ('before call db1.p2()');
|
||||
BEGIN;
|
||||
CALL db1.p2();
|
||||
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.
|
||||
ROLLBACK;
|
||||
INSERT INTO db1.t2 VALUES ('after call db1.p2()');
|
||||
SELECT * FROM db1.t1;
|
||||
|
@ -3661,6 +3661,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (135, 4);
|
||||
fc_i_nt_5_suc (135, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -3689,6 +3691,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (136, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -3781,6 +3785,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (139, 4);
|
||||
fc_i_nt_5_suc (139, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -3809,6 +3815,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (140, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -3907,6 +3915,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (143, 4);
|
||||
fc_i_nt_5_suc (143, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -3937,6 +3947,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (144, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4033,6 +4045,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (147, 4);
|
||||
fc_i_nt_5_suc (147, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4063,6 +4077,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (148, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4295,6 +4311,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (155, 4);
|
||||
fc_i_nt_5_suc (155, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4325,6 +4343,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (156, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4423,6 +4443,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (159, 4);
|
||||
fc_i_nt_5_suc (159, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4453,6 +4475,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (160, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4557,6 +4581,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (163, 4);
|
||||
fc_i_nt_5_suc (163, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4589,6 +4615,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (164, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4691,6 +4719,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
SELECT fc_i_nt_5_suc (167, 4);
|
||||
fc_i_nt_5_suc (167, 4)
|
||||
fc_i_nt_5_suc
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -4723,6 +4753,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (168, 4);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
@ -5291,6 +5323,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (185, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',185), NAME_CONST('in_stmt_id',1))
|
||||
@ -5329,6 +5363,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (186, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',186), NAME_CONST('in_stmt_id',1))
|
||||
@ -5367,6 +5403,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (187, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',187), NAME_CONST('in_stmt_id',1))
|
||||
@ -5407,6 +5445,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (188, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',188), NAME_CONST('in_stmt_id',1))
|
||||
@ -5885,6 +5925,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (201, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',201), NAME_CONST('in_stmt_id',1))
|
||||
@ -5925,6 +5967,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (202, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',202), NAME_CONST('in_stmt_id',1))
|
||||
@ -5967,6 +6011,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (203, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',203), NAME_CONST('in_stmt_id',1))
|
||||
@ -6007,6 +6053,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
|
||||
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
|
||||
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
|
||||
CALL pc_i_nt_5_suc (204, 2);
|
||||
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.
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',204), NAME_CONST('in_stmt_id',1))
|
||||
|
@ -39,6 +39,8 @@ INSERT INTO t2 VALUES (NULL);
|
||||
RETURN i;
|
||||
END//
|
||||
CALL p1();
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
@ -123,6 +125,8 @@ SELECT * FROM t2;
|
||||
id
|
||||
DROP TRIGGER tr1;
|
||||
CALL p2();
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
|
@ -4704,7 +4704,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
||||
file= cache_mngr->get_binlog_cache_log(is_trans_cache);
|
||||
cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache);
|
||||
|
||||
if (thd->stmt_accessed_non_trans_temp_table())
|
||||
if (thd->lex->stmt_accessed_non_trans_temp_table())
|
||||
cache_data->set_changes_to_non_trans_temp_table();
|
||||
|
||||
thd->binlog_start_trans_and_stmt();
|
||||
|
@ -679,7 +679,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
|
||||
server_id= thd->server_id;
|
||||
when= thd->start_time;
|
||||
cache_type= ((using_trans || stmt_has_updated_trans_table(thd) ||
|
||||
(thd->stmt_accessed_temp_table() &&
|
||||
(thd->lex->stmt_accessed_temp_table() &&
|
||||
trans_has_updated_trans_table(thd)))
|
||||
? Log_event::EVENT_TRANSACTIONAL_CACHE :
|
||||
Log_event::EVENT_STMT_CACHE);
|
||||
@ -2573,7 +2573,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||
else
|
||||
{
|
||||
cache_type= ((using_trans || stmt_has_updated_trans_table(thd) || trx_cache ||
|
||||
(thd->stmt_accessed_temp_table() &&
|
||||
(thd->lex->stmt_accessed_temp_table() &&
|
||||
trans_has_updated_trans_table(thd)))
|
||||
? Log_event::EVENT_TRANSACTIONAL_CACHE :
|
||||
Log_event::EVENT_STMT_CACHE);
|
||||
|
@ -1950,6 +1950,14 @@ err_with_cleanup:
|
||||
free_root(&call_mem_root, MYF(0));
|
||||
thd->spcont= octx;
|
||||
|
||||
/*
|
||||
If not insided a procedure and a function printing warning
|
||||
messsages.
|
||||
*/
|
||||
if (need_binlog_call &&
|
||||
thd->spcont == NULL && !thd->binlog_evt_union.do_union)
|
||||
thd->issue_unsafe_warnings();
|
||||
|
||||
DBUG_RETURN(err_status);
|
||||
}
|
||||
|
||||
@ -2195,6 +2203,17 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
||||
thd->spcont= save_spcont;
|
||||
thd->utime_after_lock= utime_before_sp_exec;
|
||||
|
||||
/*
|
||||
If not insided a procedure and a function printing warning
|
||||
messsages.
|
||||
*/
|
||||
bool need_binlog_call= mysql_bin_log.is_open() &&
|
||||
(thd->variables.option_bits & OPTION_BIN_LOG) &&
|
||||
!thd->is_current_stmt_binlog_format_row();
|
||||
if (need_binlog_call && thd->spcont == NULL &&
|
||||
!thd->binlog_evt_union.do_union)
|
||||
thd->issue_unsafe_warnings();
|
||||
|
||||
DBUG_RETURN(err_status);
|
||||
}
|
||||
|
||||
|
122
sql/sql_class.cc
122
sql/sql_class.cc
@ -492,7 +492,6 @@ THD::THD()
|
||||
rli_fake(0),
|
||||
user_time(0), in_sub_stmt(0),
|
||||
binlog_unsafe_warning_flags(0),
|
||||
stmt_accessed_table_flag(0),
|
||||
binlog_table_maps(0),
|
||||
table_map_for_update(0),
|
||||
arg_of_last_insert_id_function(FALSE),
|
||||
@ -3675,8 +3674,17 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
Innodb and Falcon; Innodb and MyIsam.
|
||||
*/
|
||||
my_bool multi_access_engine= FALSE;
|
||||
|
||||
/*
|
||||
Identifies if a table is changed.
|
||||
*/
|
||||
my_bool is_write= FALSE;
|
||||
/*
|
||||
A pointer to a previous table that was changed.
|
||||
*/
|
||||
TABLE* prev_write_table= NULL;
|
||||
/*
|
||||
A pointer to a previous table that was accessed.
|
||||
*/
|
||||
TABLE* prev_access_table= NULL;
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
@ -3700,7 +3708,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
if (table->placeholder())
|
||||
continue;
|
||||
|
||||
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
|
||||
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE ||
|
||||
table->table->s->table_category == TABLE_CATEGORY_LOG)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE);
|
||||
|
||||
handler::Table_flags const flags= table->table->file->ha_table_flags();
|
||||
@ -3716,16 +3725,18 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
my_bool trans= table->table->file->has_transactions();
|
||||
|
||||
if (table->table->s->tmp_table)
|
||||
set_stmt_accessed_table(trans ? STMT_WRITES_TEMP_TRANS_TABLE :
|
||||
STMT_WRITES_TEMP_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TEMP_TRANS_TABLE :
|
||||
LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE);
|
||||
else
|
||||
set_stmt_accessed_table(trans ? STMT_WRITES_TRANS_TABLE :
|
||||
STMT_WRITES_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TRANS_TABLE :
|
||||
LEX::STMT_WRITES_NON_TRANS_TABLE);
|
||||
|
||||
flags_write_all_set &= flags;
|
||||
flags_write_some_set |= flags;
|
||||
is_write= TRUE;
|
||||
|
||||
prev_write_table= table->table;
|
||||
|
||||
}
|
||||
flags_access_some_set |= flags;
|
||||
|
||||
@ -3736,11 +3747,11 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
my_bool trans= table->table->file->has_transactions();
|
||||
|
||||
if (table->table->s->tmp_table)
|
||||
set_stmt_accessed_table(trans ? STMT_READS_TEMP_TRANS_TABLE :
|
||||
STMT_READS_TEMP_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TEMP_TRANS_TABLE :
|
||||
LEX::STMT_READS_TEMP_NON_TRANS_TABLE);
|
||||
else
|
||||
set_stmt_accessed_table(trans ? STMT_READS_TRANS_TABLE :
|
||||
STMT_READS_NON_TRANS_TABLE);
|
||||
lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TRANS_TABLE :
|
||||
LEX::STMT_READS_NON_TRANS_TABLE);
|
||||
}
|
||||
|
||||
if (prev_access_table && prev_access_table->file->ht !=
|
||||
@ -3812,24 +3823,24 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
my_bool non_trans_unsafe= FALSE;
|
||||
|
||||
/* Case 1. */
|
||||
if (stmt_accessed_table(STMT_WRITES_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 2. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 3. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 4. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 5. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TRANS_TABLE) &&
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE) &&
|
||||
tx_isolation < ISO_REPEATABLE_READ)
|
||||
/*
|
||||
By default, InnoDB operates in REPEATABLE READ and with the option
|
||||
@ -3847,28 +3858,28 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
if (trans_has_updated_trans_table(this))
|
||||
{
|
||||
/* Case 6. */
|
||||
if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TRANS_TABLE))
|
||||
if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 7. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TEMP_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TEMP_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 8. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_TEMP_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_TEMP_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 9. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 10. */
|
||||
else if (stmt_accessed_table(STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
|
||||
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
|
||||
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
|
||||
mixed_unsafe= TRUE;
|
||||
/* Case 11. */
|
||||
else if (!variables.binlog_direct_non_trans_update &&
|
||||
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
|
||||
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
|
||||
non_trans_unsafe= TRUE;
|
||||
}
|
||||
|
||||
@ -3959,13 +3970,14 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
*/
|
||||
my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), "");
|
||||
}
|
||||
else if ((unsafe_flags= lex->get_stmt_unsafe_flags()) != 0)
|
||||
else if (is_write && (unsafe_flags= lex->get_stmt_unsafe_flags()) != 0)
|
||||
{
|
||||
/*
|
||||
7. Warning: Unsafe statement logged as statement due to
|
||||
binlog_format = STATEMENT
|
||||
*/
|
||||
binlog_unsafe_warning_flags|= unsafe_flags;
|
||||
|
||||
DBUG_PRINT("info", ("Scheduling warning to be issued by "
|
||||
"binlog_query: '%s'",
|
||||
ER(ER_BINLOG_UNSAFE_STATEMENT)));
|
||||
@ -4441,23 +4453,10 @@ void THD::issue_unsafe_warnings()
|
||||
Ensure that binlog_unsafe_warning_flags is big enough to hold all
|
||||
bits. This is actually a constant expression.
|
||||
*/
|
||||
DBUG_ASSERT(2 * LEX::BINLOG_STMT_UNSAFE_COUNT <=
|
||||
DBUG_ASSERT(LEX::BINLOG_STMT_UNSAFE_COUNT <=
|
||||
sizeof(binlog_unsafe_warning_flags) * CHAR_BIT);
|
||||
|
||||
uint32 unsafe_type_flags= binlog_unsafe_warning_flags;
|
||||
|
||||
/*
|
||||
Clear: (1) bits above BINLOG_STMT_UNSAFE_COUNT; (2) bits for
|
||||
warnings that have been printed already.
|
||||
*/
|
||||
unsafe_type_flags &= (LEX::BINLOG_STMT_UNSAFE_ALL_FLAGS ^
|
||||
(unsafe_type_flags >> LEX::BINLOG_STMT_UNSAFE_COUNT));
|
||||
/* If all warnings have been printed already, return. */
|
||||
if (unsafe_type_flags == 0)
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
DBUG_PRINT("info", ("unsafe_type_flags: 0x%x", unsafe_type_flags));
|
||||
|
||||
/*
|
||||
For each unsafe_type, check if the statement is unsafe in this way
|
||||
and issue a warning.
|
||||
@ -4481,12 +4480,6 @@ void THD::issue_unsafe_warnings()
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Mark these unsafe types as already printed, to avoid printing
|
||||
warnings for them again.
|
||||
*/
|
||||
binlog_unsafe_warning_flags|=
|
||||
unsafe_type_flags << LEX::BINLOG_STMT_UNSAFE_COUNT;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -4540,19 +4533,32 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
|
||||
|
||||
/*
|
||||
Warnings for unsafe statements logged in statement format are
|
||||
printed here instead of in decide_logging_format(). This is
|
||||
because the warnings should be printed only if the statement is
|
||||
actually logged. When executing decide_logging_format(), we cannot
|
||||
know for sure if the statement will be logged.
|
||||
printed in three places instead of in decide_logging_format().
|
||||
This is because the warnings should be printed only if the statement
|
||||
is actually logged. When executing decide_logging_format(), we cannot
|
||||
know for sure if the statement will be logged:
|
||||
|
||||
1 - sp_head::execute_procedure which prints out warnings for calls to
|
||||
stored procedures.
|
||||
|
||||
2 - sp_head::execute_function which prints out warnings for calls
|
||||
involving functions.
|
||||
|
||||
3 - THD::binlog_query (here) which prints warning for top level
|
||||
statements not covered by the two cases above: i.e., if not insided a
|
||||
procedure and a function.
|
||||
|
||||
Besides, we should not try to print these warnings if it is not
|
||||
possible to write statements to the binary log as it happens when
|
||||
the execution is inside a function, or generaly speaking, when
|
||||
the variables.option_bits & OPTION_BIN_LOG is false.
|
||||
|
||||
*/
|
||||
if (variables.option_bits & OPTION_BIN_LOG)
|
||||
if ((variables.option_bits & OPTION_BIN_LOG) &&
|
||||
spcont == NULL && !binlog_evt_union.do_union)
|
||||
issue_unsafe_warnings();
|
||||
|
||||
|
||||
switch (qtype) {
|
||||
/*
|
||||
ROW_QUERY_TYPE means that the statement may be logged either in
|
||||
|
149
sql/sql_class.h
149
sql/sql_class.h
@ -1566,125 +1566,6 @@ public:
|
||||
return current_stmt_binlog_format == BINLOG_FORMAT_ROW;
|
||||
}
|
||||
|
||||
enum enum_stmt_accessed_table
|
||||
{
|
||||
/*
|
||||
If a transactional table is about to be read. Note that
|
||||
a write implies a read.
|
||||
*/
|
||||
STMT_READS_TRANS_TABLE= 0,
|
||||
/*
|
||||
If a transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_TRANS_TABLE,
|
||||
/*
|
||||
If a non-transactional table is about to be read. Note that
|
||||
a write implies a read.
|
||||
*/
|
||||
STMT_READS_NON_TRANS_TABLE,
|
||||
/*
|
||||
If a non-transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_NON_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary transactional table is about to be read. Note
|
||||
that a write implies a read.
|
||||
*/
|
||||
STMT_READS_TEMP_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_TEMP_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary non-transactional table is about to be read. Note
|
||||
that a write implies a read.
|
||||
*/
|
||||
STMT_READS_TEMP_NON_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary non-transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_TEMP_NON_TRANS_TABLE,
|
||||
/*
|
||||
The last element of the enumeration. Please, if necessary add
|
||||
anything before this.
|
||||
*/
|
||||
STMT_ACCESS_TABLE_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
Sets the type of table that is about to be accessed while executing a
|
||||
statement.
|
||||
|
||||
@param accessed_table Enumeration type that defines the type of table,
|
||||
e.g. temporary, transactional, non-transactional.
|
||||
*/
|
||||
inline void set_stmt_accessed_table(enum_stmt_accessed_table accessed_table)
|
||||
{
|
||||
DBUG_ENTER("THD::set_stmt_accessed_table");
|
||||
|
||||
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
|
||||
stmt_accessed_table_flag |= (1U << accessed_table);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if a type of table is about to be accessed while executing a
|
||||
statement.
|
||||
|
||||
@param accessed_table Enumeration type that defines the type of table,
|
||||
e.g. temporary, transactional, non-transactional.
|
||||
|
||||
@return
|
||||
@retval TRUE if the type of the table is about to be accessed
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
inline bool stmt_accessed_table(enum_stmt_accessed_table accessed_table)
|
||||
{
|
||||
DBUG_ENTER("THD::stmt_accessed_table");
|
||||
|
||||
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
|
||||
|
||||
DBUG_RETURN((stmt_accessed_table_flag & (1U << accessed_table)) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if a temporary table is about to be accessed while executing a
|
||||
statement.
|
||||
|
||||
@return
|
||||
@retval TRUE if a temporary table is about to be accessed
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
inline bool stmt_accessed_temp_table()
|
||||
{
|
||||
DBUG_ENTER("THD::stmt_accessed_temp_table");
|
||||
|
||||
DBUG_RETURN((stmt_accessed_table_flag &
|
||||
((1U << STMT_READS_TEMP_TRANS_TABLE) |
|
||||
(1U << STMT_WRITES_TEMP_TRANS_TABLE) |
|
||||
(1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
|
||||
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if a temporary non-transactional table is about to be accessed
|
||||
while executing a statement.
|
||||
|
||||
@return
|
||||
@retval TRUE if a temporary non-transactional table is about to be
|
||||
accessed
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
inline bool stmt_accessed_non_trans_temp_table()
|
||||
{
|
||||
DBUG_ENTER("THD::stmt_accessed_non_trans_temp_table");
|
||||
|
||||
DBUG_RETURN((stmt_accessed_table_flag &
|
||||
((1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
|
||||
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
Indicates the format in which the current statement will be
|
||||
@ -1695,24 +1576,8 @@ private:
|
||||
/**
|
||||
Bit field for the state of binlog warnings.
|
||||
|
||||
There are two groups of bits:
|
||||
|
||||
- The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of
|
||||
unsafeness that the current statement has.
|
||||
|
||||
- The following Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types
|
||||
of unsafeness that the current statement has issued warnings
|
||||
for.
|
||||
|
||||
Hence, this variable must be big enough to hold
|
||||
2*Lex::BINLOG_STMT_UNSAFE_COUNT bits. This is asserted in @c
|
||||
issue_unsafe_warnings().
|
||||
|
||||
The first and second groups of bits are set by @c
|
||||
decide_logging_format() when it detects that a warning should be
|
||||
issued. The third group of bits is set from @c binlog_query()
|
||||
when a warning is issued. All bits are cleared at the end of the
|
||||
top-level statement.
|
||||
The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of
|
||||
unsafeness that the current statement has.
|
||||
|
||||
This must be a member of THD and not of LEX, because warnings are
|
||||
detected and issued in different places (@c
|
||||
@ -1722,20 +1587,14 @@ private:
|
||||
*/
|
||||
uint32 binlog_unsafe_warning_flags;
|
||||
|
||||
/**
|
||||
Bit field that determines the type of tables that are about to be
|
||||
be accessed while executing a statement.
|
||||
*/
|
||||
uint32 stmt_accessed_table_flag;
|
||||
|
||||
void issue_unsafe_warnings();
|
||||
|
||||
/*
|
||||
Number of outstanding table maps, i.e., table maps in the
|
||||
transaction cache.
|
||||
*/
|
||||
uint binlog_table_maps;
|
||||
public:
|
||||
void issue_unsafe_warnings();
|
||||
|
||||
uint get_binlog_table_maps() const {
|
||||
return binlog_table_maps;
|
||||
}
|
||||
|
@ -2300,6 +2300,7 @@ void Query_tables_list::reset_query_tables_list(bool init)
|
||||
sroutines_list_own_last= sroutines_list.next;
|
||||
sroutines_list_own_elements= 0;
|
||||
binlog_stmt_flags= 0;
|
||||
stmt_accessed_table_flag= 0;
|
||||
}
|
||||
|
||||
|
||||
|
125
sql/sql_lex.h
125
sql/sql_lex.h
@ -1276,6 +1276,125 @@ public:
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
enum enum_stmt_accessed_table
|
||||
{
|
||||
/*
|
||||
If a transactional table is about to be read. Note that
|
||||
a write implies a read.
|
||||
*/
|
||||
STMT_READS_TRANS_TABLE= 0,
|
||||
/*
|
||||
If a transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_TRANS_TABLE,
|
||||
/*
|
||||
If a non-transactional table is about to be read. Note that
|
||||
a write implies a read.
|
||||
*/
|
||||
STMT_READS_NON_TRANS_TABLE,
|
||||
/*
|
||||
If a non-transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_NON_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary transactional table is about to be read. Note
|
||||
that a write implies a read.
|
||||
*/
|
||||
STMT_READS_TEMP_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_TEMP_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary non-transactional table is about to be read. Note
|
||||
that a write implies a read.
|
||||
*/
|
||||
STMT_READS_TEMP_NON_TRANS_TABLE,
|
||||
/*
|
||||
If a temporary non-transactional table is about to be updated.
|
||||
*/
|
||||
STMT_WRITES_TEMP_NON_TRANS_TABLE,
|
||||
/*
|
||||
The last element of the enumeration. Please, if necessary add
|
||||
anything before this.
|
||||
*/
|
||||
STMT_ACCESS_TABLE_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
Sets the type of table that is about to be accessed while executing a
|
||||
statement.
|
||||
|
||||
@param accessed_table Enumeration type that defines the type of table,
|
||||
e.g. temporary, transactional, non-transactional.
|
||||
*/
|
||||
inline void set_stmt_accessed_table(enum_stmt_accessed_table accessed_table)
|
||||
{
|
||||
DBUG_ENTER("THD::set_stmt_accessed_table");
|
||||
|
||||
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
|
||||
stmt_accessed_table_flag |= (1U << accessed_table);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if a type of table is about to be accessed while executing a
|
||||
statement.
|
||||
|
||||
@param accessed_table Enumeration type that defines the type of table,
|
||||
e.g. temporary, transactional, non-transactional.
|
||||
|
||||
@return
|
||||
@retval TRUE if the type of the table is about to be accessed
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
inline bool stmt_accessed_table(enum_stmt_accessed_table accessed_table)
|
||||
{
|
||||
DBUG_ENTER("THD::stmt_accessed_table");
|
||||
|
||||
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
|
||||
|
||||
DBUG_RETURN((stmt_accessed_table_flag & (1U << accessed_table)) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if a temporary table is about to be accessed while executing a
|
||||
statement.
|
||||
|
||||
@return
|
||||
@retval TRUE if a temporary table is about to be accessed
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
inline bool stmt_accessed_temp_table()
|
||||
{
|
||||
DBUG_ENTER("THD::stmt_accessed_temp_table");
|
||||
|
||||
DBUG_RETURN((stmt_accessed_table_flag &
|
||||
((1U << STMT_READS_TEMP_TRANS_TABLE) |
|
||||
(1U << STMT_WRITES_TEMP_TRANS_TABLE) |
|
||||
(1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
|
||||
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if a temporary non-transactional table is about to be accessed
|
||||
while executing a statement.
|
||||
|
||||
@return
|
||||
@retval TRUE if a temporary non-transactional table is about to be
|
||||
accessed
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
inline bool stmt_accessed_non_trans_temp_table()
|
||||
{
|
||||
DBUG_ENTER("THD::stmt_accessed_non_trans_temp_table");
|
||||
|
||||
DBUG_RETURN((stmt_accessed_table_flag &
|
||||
((1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
|
||||
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
true if the parsed tree contains references to stored procedures
|
||||
or functions, false otherwise
|
||||
@ -1317,6 +1436,12 @@ private:
|
||||
stored procedure has its own LEX object (but no own THD object).
|
||||
*/
|
||||
uint32 binlog_stmt_flags;
|
||||
|
||||
/**
|
||||
Bit field that determines the type of tables that are about to be
|
||||
be accessed while executing a statement.
|
||||
*/
|
||||
uint32 stmt_accessed_table_flag;
|
||||
};
|
||||
|
||||
|
||||
|
@ -5640,7 +5640,6 @@ void THD::reset_for_next_command()
|
||||
|
||||
thd->reset_current_stmt_binlog_format_row();
|
||||
thd->binlog_unsafe_warning_flags= 0;
|
||||
thd->stmt_accessed_table_flag= 0;
|
||||
|
||||
DBUG_PRINT("debug",
|
||||
("is_current_stmt_binlog_format_row(): %d",
|
||||
|
Loading…
x
Reference in New Issue
Block a user