Commit 68598c47 authored by Alfranio Correia's avatar Alfranio Correia

BUG#53075 SBR: Strange warning around CONNECTION_ID

Statements with CONNECTION_ID were forced to be kept in the transactional
cache and by consequence non-transactional changes that were supposed to
be flushed ahead of the transaction were kept in the transactional cache.

This happened because after BUG#51894 any statement whose thd's
thread_specific_used was set was kept in the transactional cache. The idea
was to keep changes on temporary tables in the transactional cache. However,
the thread_specific_used was set not only for statements that accessed
temporary tables but also when the CONNECTION_ID was used.

To fix the problem, we created a new variable to keep track of updates
to temporary tables.


mysql-test/suite/rpl/r/rpl_temp_temporary.result:
  Added a test case.
mysql-test/suite/rpl/t/rpl_temp_temporary.test:
  Added a test case.
sql/log_event.cc:
  Uses the thread_temporary_used to decide if a statement should
  be kept in the transactional cache or not.
sql/sql_class.cc:
  Sets the thread_temporary_used while calling the decide_logging_format.
sql/sql_class.h:
  Defines the thread_temporary_used.
sql/sql_parse.cc:
  Resets the thread_temporary_used.
parent 17aa4173
...@@ -174,6 +174,48 @@ master-bin.000001 # Query # # BEGIN ...@@ -174,6 +174,48 @@ 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 `tmp2` /* generated by server */
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp3` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tmp3` /* generated by server */
master-bin.000001 # Query # # ROLLBACK 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 binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
INSERT INTO t_innodb VALUES(1);
INSERT INTO t_myisam VALUES(CONNECTION_ID());
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Non-transactional reads or writes are unsafe if they occur after transactional reads or writes inside a transaction.
INSERT INTO t_innodb VALUES(1);
COMMIT;
DROP TABLE t_myisam;
DROP TABLE t_innodb;
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 */
master-bin.000001 # Query # # use `test`; DROP TABLE t_myisam
master-bin.000001 # Query # # use `test`; DROP TABLE t_innodb
################################################################################### ###################################################################################
# CHECK CONSISTENCY # CHECK CONSISTENCY
################################################################################### ###################################################################################
...@@ -34,6 +34,10 @@ ...@@ -34,6 +34,10 @@
# the CREATE TEMPORARY is not logged and the DROP TEMPORARY is extended with # the CREATE TEMPORARY is not logged and the DROP TEMPORARY is extended with
# the IF EXISTS clause. # the IF EXISTS clause.
# #
# 7 - It also verifies if the CONNECTION_ID along with a non-transactional
# table is written outside the transaction boundaries and is not classified
# as unsafe. See BUG#53075.
#
################################################################################ ################################################################################
source include/master-slave.inc; source include/master-slave.inc;
...@@ -163,6 +167,29 @@ DROP TEMPORARY TABLE tmp3; ...@@ -163,6 +167,29 @@ DROP TEMPORARY TABLE tmp3;
ROLLBACK; ROLLBACK;
source include/show_binlog_events.inc; source include/show_binlog_events.inc;
--echo ########################################################################
--echo # VERIFY ITEM 7
--echo ########################################################################
SET BINLOG_FORMAT=STATEMENT;
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
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);
INSERT INTO t_innodb VALUES(1);
INSERT INTO t_myisam VALUES(CONNECTION_ID());
INSERT INTO t_innodb VALUES(1);
COMMIT;
DROP TABLE t_myisam;
DROP TABLE t_innodb;
source include/show_binlog_events.inc;
--echo ################################################################################### --echo ###################################################################################
--echo # CHECK CONSISTENCY --echo # CHECK CONSISTENCY
--echo ################################################################################### --echo ###################################################################################
...@@ -172,3 +199,5 @@ sync_slave_with_master; ...@@ -172,3 +199,5 @@ sync_slave_with_master;
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
--diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql --diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
...@@ -679,7 +679,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) ...@@ -679,7 +679,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
server_id= thd->server_id; server_id= thd->server_id;
when= thd->start_time; when= thd->start_time;
cache_type= (using_trans || stmt_has_updated_trans_table(thd) cache_type= (using_trans || stmt_has_updated_trans_table(thd)
|| thd->thread_specific_used || thd->thread_temporary_used
? Log_event::EVENT_TRANSACTIONAL_CACHE : ? Log_event::EVENT_TRANSACTIONAL_CACHE :
Log_event::EVENT_STMT_CACHE); Log_event::EVENT_STMT_CACHE);
} }
...@@ -2553,7 +2553,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, ...@@ -2553,7 +2553,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
else else
{ {
cache_type= ((using_trans || stmt_has_updated_trans_table(thd) || cache_type= ((using_trans || stmt_has_updated_trans_table(thd) ||
force_trans || thd->thread_specific_used) force_trans || thd->thread_temporary_used)
? Log_event::EVENT_TRANSACTIONAL_CACHE : ? Log_event::EVENT_TRANSACTIONAL_CACHE :
Log_event::EVENT_STMT_CACHE); Log_event::EVENT_STMT_CACHE);
} }
......
...@@ -3736,6 +3736,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) ...@@ -3736,6 +3736,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
trans_non_trans_access_engines= (prev_trans != act_trans); trans_non_trans_access_engines= (prev_trans != act_trans);
multi_access_engine= TRUE; multi_access_engine= TRUE;
} }
thread_temporary_used |= table->table->s->tmp_table;
prev_access_table= table->table; prev_access_table= table->table;
} }
......
...@@ -2108,6 +2108,11 @@ public: ...@@ -2108,6 +2108,11 @@ public:
/** is set if some thread specific value(s) used in a statement. */ /** is set if some thread specific value(s) used in a statement. */
bool thread_specific_used; bool thread_specific_used;
/**
is set if a statement accesses a temporary table created through
CREATE TEMPORARY TABLE.
*/
bool thread_temporary_used;
bool charset_is_system_charset, charset_is_collation_connection; bool charset_is_system_charset, charset_is_collation_connection;
bool charset_is_character_set_filesystem; bool charset_is_character_set_filesystem;
bool enable_slow_log; /* enable slow log for current statement */ bool enable_slow_log; /* enable slow log for current statement */
......
...@@ -5530,7 +5530,7 @@ void THD::reset_for_next_command() ...@@ -5530,7 +5530,7 @@ void THD::reset_for_next_command()
thd->transaction.all.modified_non_trans_table= FALSE; thd->transaction.all.modified_non_trans_table= FALSE;
} }
DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx); DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
thd->thread_specific_used= FALSE; thd->thread_specific_used= thd->thread_temporary_used= FALSE;
if (opt_bin_log) if (opt_bin_log)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment