diff --git a/mysql-test/r/rpl_innodb.result b/mysql-test/r/rpl_innodb.result index 765de8af458..6dc2c25247f 100644 --- a/mysql-test/r/rpl_innodb.result +++ b/mysql-test/r/rpl_innodb.result @@ -35,3 +35,73 @@ SELECT * FROM t4; id name number 3 XXX 12345 4 XXY 12345 +FLUSH LOGS; +FLUSH LOGS; +DROP DATABASE IF EXISTS mysqltest1; +CREATE DATABASE mysqltest1; +CREATE TEMPORARY TABLE mysqltest1.tmp (f1 BIGINT); +CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE="InnoDB"; +SET AUTOCOMMIT = 0; +-------- switch to slave -------- +SHOW CREATE TABLE mysqltest1.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` bigint(20) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +-------- switch to master -------- +INSERT INTO mysqltest1.t1 SET f1= 1; +DROP TEMPORARY TABLE mysqltest1.tmp; +ROLLBACK; +SHOW CREATE TABLE mysqltest1.tmp; +ERROR 42S02: Table 'mysqltest1.tmp' doesn't exist +SELECT COUNT(*) FROM mysqltest1.t1; +COUNT(*) +0 +INSERT INTO mysqltest1.t1 SET f1= 2; +CREATE TEMPORARY TABLE mysqltest1.tmp2(a INT); +ROLLBACK; +SHOW CREATE TABLE mysqltest1.tmp2; +Table Create Table +tmp2 CREATE TEMPORARY TABLE `tmp2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT COUNT(*) FROM mysqltest1.t1; +COUNT(*) +0 +-------- switch to slave -------- +SHOW CREATE TABLE mysqltest1.tmp; +ERROR 42S02: Table 'mysqltest1.tmp' doesn't exist +SHOW CREATE TABLE mysqltest1.tmp2; +ERROR 42S02: Table 'mysqltest1.tmp2' doesn't exist +SELECT COUNT(*) FROM mysqltest1.t1; +COUNT(*) +2 +FLUSH LOGS; +SHOW BINLOG EVENTS IN 'slave-bin.000002' LIMIT 1,8; +Log_name Pos Event_type Server_id End_log_pos Info +x x x x x DROP DATABASE IF EXISTS mysqltest1 +x x x x x CREATE DATABASE mysqltest1 +x x x x x use `test`; CREATE TEMPORARY TABLE mysqltest1.tmp (f1 BIGINT) +x x x x x use `test`; CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE="InnoDB" +x x x x x use `test`; INSERT INTO mysqltest1.t1 SET f1= 1 +x x x x x use `test`; DROP TEMPORARY TABLE mysqltest1.tmp +x x x x x use `test`; INSERT INTO mysqltest1.t1 SET f1= 2 +x x x x x use `test`; CREATE TEMPORARY TABLE mysqltest1.tmp2(a INT) +-------- switch to master -------- +FLUSH LOGS; +SHOW BINLOG EVENTS IN 'master-bin.000002' LIMIT 1,12; +Log_name Pos Event_type Server_id End_log_pos Info +x x x x x DROP DATABASE IF EXISTS mysqltest1 +x x x x x CREATE DATABASE mysqltest1 +x x x x x use `test`; CREATE TEMPORARY TABLE mysqltest1.tmp (f1 BIGINT) +x x x x x use `test`; CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE="InnoDB" +x x x x x use `test`; BEGIN +x x x x x use `test`; INSERT INTO mysqltest1.t1 SET f1= 1 +x x x x x use `test`; DROP TEMPORARY TABLE mysqltest1.tmp +x x x x x use `test`; ROLLBACK +x x x x x use `test`; BEGIN +x x x x x use `test`; INSERT INTO mysqltest1.t1 SET f1= 2 +x x x x x use `test`; CREATE TEMPORARY TABLE mysqltest1.tmp2(a INT) +x x x x x use `test`; ROLLBACK +DROP DATABASE mysqltest1; +End of 5.1 tests diff --git a/mysql-test/t/rpl_innodb.test b/mysql-test/t/rpl_innodb.test index b88276e2107..f13889349f7 100644 --- a/mysql-test/t/rpl_innodb.test +++ b/mysql-test/t/rpl_innodb.test @@ -44,5 +44,76 @@ connection master; DROP TABLE t4; --enable_query_log sync_slave_with_master; +connection master; # End of 4.1 tests + +# +# Bug #26418: Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK +# on master +# +#Note Matthias: to be merged to rpl_ddl.test + +--source include/not_ndb_default.inc + +FLUSH LOGS; +sync_slave_with_master; +FLUSH LOGS; +connection master; +let $engine_type= "InnoDB"; + +--disable_warnings +DROP DATABASE IF EXISTS mysqltest1; +--enable_warnings + +CREATE DATABASE mysqltest1; +CREATE TEMPORARY TABLE mysqltest1.tmp (f1 BIGINT); +eval CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE=$engine_type; +SET AUTOCOMMIT = 0; + +sync_slave_with_master; +--echo -------- switch to slave -------- +connection slave; +SHOW CREATE TABLE mysqltest1.t1; + +--echo -------- switch to master -------- +connection master; +INSERT INTO mysqltest1.t1 SET f1= 1; +DROP TEMPORARY TABLE mysqltest1.tmp; +ROLLBACK; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE mysqltest1.tmp; +# Must return no rows here +SELECT COUNT(*) FROM mysqltest1.t1; + +INSERT INTO mysqltest1.t1 SET f1= 2; +CREATE TEMPORARY TABLE mysqltest1.tmp2(a INT); +ROLLBACK; +SHOW CREATE TABLE mysqltest1.tmp2; +# Must return no rows here +SELECT COUNT(*) FROM mysqltest1.t1; + +sync_slave_with_master; +--echo -------- switch to slave -------- +connection slave; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE mysqltest1.tmp; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE mysqltest1.tmp2; +# has two rows here : as the default is MyISAM and +# it can't be rolled back by the master's ROLLBACK. +SELECT COUNT(*) FROM mysqltest1.t1; +FLUSH LOGS; +--replace_column 1 x 2 x 3 x 4 x 5 x +SHOW BINLOG EVENTS IN 'slave-bin.000002' LIMIT 1,8; + +--echo -------- switch to master -------- +connection master; +FLUSH LOGS; +--replace_column 1 x 2 x 3 x 4 x 5 x +SHOW BINLOG EVENTS IN 'master-bin.000002' LIMIT 1,12; + +DROP DATABASE mysqltest1; +-- source include/master-slave-end.inc + +--echo End of 5.1 tests diff --git a/sql/events.cc b/sql/events.cc index 7838972a5d6..2d1b3c59a4c 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -425,12 +425,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, event_queue->create_event(thd, new_element, &created); /* Binlog the create event. */ DBUG_ASSERT(thd->query && thd->query_length); - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } } pthread_mutex_unlock(&LOCK_event_metadata); @@ -551,12 +546,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, new_element); /* Binlog the alter event. */ DBUG_ASSERT(thd->query && thd->query_length); - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } } pthread_mutex_unlock(&LOCK_event_metadata); @@ -631,12 +621,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) event_queue->drop_event(thd, dbname, name); /* Binlog the drop event. */ DBUG_ASSERT(thd->query && thd->query_length); - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } pthread_mutex_unlock(&LOCK_event_metadata); DBUG_RETURN(ret); diff --git a/sql/sp.cc b/sql/sp.cc index 49e86f9d07e..0118169ff7c 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -650,13 +650,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) if (ret == SP_OK) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } - + write_bin_log(thd, TRUE, thd->query, thd->query_length); sp_cache_invalidate(); } @@ -723,13 +717,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) if (ret == SP_OK) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } - + write_bin_log(thd, TRUE, thd->query, thd->query_length); sp_cache_invalidate(); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1b57e9363e4..e295b47e525 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3143,12 +3143,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (!result) /* success */ { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } rw_unlock(&LOCK_grant); @@ -3315,12 +3310,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, pthread_mutex_unlock(&acl_cache->lock); if (!result && !no_error) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } rw_unlock(&LOCK_grant); @@ -3435,12 +3425,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (!result) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } rw_unlock(&LOCK_grant); @@ -5469,11 +5454,7 @@ bool mysql_create_user(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - if (mysql_bin_log.is_open()) - { - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, FALSE, thd->query, thd->query_length); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5539,11 +5520,7 @@ bool mysql_drop_user(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - if (mysql_bin_log.is_open()) - { - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, FALSE, thd->query, thd->query_length); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5622,11 +5599,7 @@ bool mysql_rename_user(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - if (mysql_bin_log.is_open()) - { - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, FALSE, thd->query, thd->query_length); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5810,11 +5783,7 @@ bool mysql_revoke_all(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - if (mysql_bin_log.is_open()) - { - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, FALSE, thd->query, thd->query_length); rw_unlock(&LOCK_grant); close_thread_tables(thd); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9dbc79344a9..5b9c9259434 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3028,15 +3028,6 @@ int THD::binlog_flush_pending_rows_event(bool stmt_end) } -void THD::binlog_delete_pending_rows_event() -{ - if (Rows_log_event *pending= binlog_get_pending_rows_event()) - { - delete pending; - binlog_set_pending_rows_event(0); - } -} - /* Member function that will log query, either row-based or statement-based depending on the value of the 'current_stmt_binlog_row_based' diff --git a/sql/sql_class.h b/sql/sql_class.h index de7aaafbe3b..1c719eb9734 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1096,7 +1096,6 @@ public: Rows_log_event* binlog_get_pending_rows_event() const; void binlog_set_pending_rows_event(Rows_log_event* ev); int binlog_flush_pending_rows_event(bool stmt_end); - void binlog_delete_pending_rows_event(); private: uint binlog_table_maps; // Number of table maps currently in the binlog diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index fe54a12e4dc..8581803a9ad 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -975,16 +975,11 @@ end: { if (!error) { - if (mysql_bin_log.is_open()) - { - /* - TRUNCATE must always be statement-based binlogged (not row-based) so - we don't test current_stmt_binlog_row_based. - */ - thd->clear_error(); - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + /* + TRUNCATE must always be statement-based binlogged (not row-based) so + we don't test current_stmt_binlog_row_based. + */ + write_bin_log(thd, TRUE, thd->query, thd->query_length); send_ok(thd); // This should return record count } VOID(pthread_mutex_lock(&LOCK_open)); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e7ed02f333e..43c157cd1f6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2506,12 +2506,7 @@ end_with_restore_list: /* Presumably, REPAIR and binlog writing doesn't require synchronization */ - if (mysql_bin_log.is_open()) - { - thd->clear_error(); // No binlog error generated - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, 0, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } select_lex->table_list.first= (uchar*) first_table; lex->query_tables=all_tables; @@ -2541,12 +2536,7 @@ end_with_restore_list: /* Presumably, ANALYZE and binlog writing doesn't require synchronization */ - if (mysql_bin_log.is_open()) - { - thd->clear_error(); // No binlog error generated - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, 0, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } select_lex->table_list.first= (uchar*) first_table; lex->query_tables=all_tables; @@ -2568,12 +2558,7 @@ end_with_restore_list: /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */ - if (mysql_bin_log.is_open()) - { - thd->clear_error(); // No binlog error generated - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, 0, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); } select_lex->table_list.first= (uchar*) first_table; lex->query_tables=all_tables; @@ -3473,11 +3458,7 @@ end_with_restore_list: */ if (!lex->no_write_to_binlog && write_to_binlog) { - if (mysql_bin_log.is_open()) - { - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, 0, FALSE); - } + write_bin_log(thd, FALSE, thd->query, thd->query_length); } send_ok(thd); } diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index f34ec83b29c..866d82377c0 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -174,12 +174,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) /* Lets hope this doesn't fail as the result will be messy */ if (!silent && !error) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); send_ok(thd); } diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc index b4a03a370ba..9fec0e3bc63 100644 --- a/sql/sql_tablespace.cc +++ b/sql/sql_tablespace.cc @@ -66,10 +66,6 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info) ha_resolve_storage_engine_name(hton), "TABLESPACE or LOGFILE GROUP"); } - if (mysql_bin_log.is_open()) - { - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, FALSE, TRUE); - } + write_bin_log(thd, FALSE, thd->query, thd->query_length); DBUG_RETURN(FALSE); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index e15003ab243..6e8a40e68a2 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -306,14 +306,7 @@ end: if (!result) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - - /* Such a statement can always go directly to binlog, no trans cache. */ - thd->binlog_query(THD::STMT_QUERY_TYPE, - stmt_query.ptr(), stmt_query.length(), FALSE, FALSE); - } + write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length()); } VOID(pthread_mutex_unlock(&LOCK_open)); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 20ce614f361..8361fc64f33 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -493,12 +493,7 @@ int mysql_create_function(THD *thd,udf_func *udf) rw_unlock(&THR_LOCK_udf); /* Binlog the create function. */ - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); DBUG_RETURN(0); @@ -569,12 +564,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) rw_unlock(&THR_LOCK_udf); /* Binlog the drop function. */ - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); DBUG_RETURN(0); err: diff --git a/sql/sql_view.cc b/sql/sql_view.cc index c1e4006555f..ba13ac3520f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1467,12 +1467,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) DBUG_RETURN(TRUE); } - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } + write_bin_log(thd, TRUE, thd->query, thd->query_length); send_ok(thd); VOID(pthread_mutex_unlock(&LOCK_open));