diff options
author | unknown <Dao-Gang.Qu@sun.com> | 2010-01-22 17:38:21 +0800 |
---|---|---|
committer | unknown <Dao-Gang.Qu@sun.com> | 2010-01-22 17:38:21 +0800 |
commit | 3cae7d1187795a8089b6f54ac60cf2a0e579cf89 (patch) | |
tree | 38a04f7b1df366f29044950c701f98334c2d062b /sql/events.cc | |
parent | 132b46e96eb48b8d9d993583ed7b9ecd87e53674 (diff) | |
download | mariadb-git-3cae7d1187795a8089b6f54ac60cf2a0e579cf89.tar.gz |
Bug #49132 Replication failure on temporary table + DDL
In RBR, DDL statement will change binlog format to non row-based
format before it is binlogged, but the binlog format was not be
restored, and then manipulating a temporary table can not reset binlog
format to row-based format rightly. So that the manipulated statement
is binlogged with statement-based format.
To fix the problem, restore the state of binlog format after the DDL
statement is binlogged.
mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test:
Added the test file to verify if executing DDL statement before
trying to manipulate a temporary table causes row-based replication
to break with error 'table does not exist'.
mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result:
Correct the test result, all the above binlog event
should be row-based after the bug49132 is fixed IN RBR.
mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result:
Test result for bug#49132 base on ndb engine.
mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test:
Added the test file to verify if executing DDL statement before
trying to manipulate a temporary table causes row-based replication
to break with error 'table does not exist' base on ndb engine.
mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result:
Test result for bug#49132 base on myisam engine.
mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test:
Added the test file to verify if executing DDL statement before
trying to manipulate a temporary table causes row-based replication
to break with error 'table does not exist' base on myisam engine.
sql/event_db_repository.cc:
Added code to restore the state of binlog format after the DDL
statement is binlogged.
sql/events.cc:
Added code to restore the state of binlog format after the DDL
statement is binlogged.
sql/sp.cc:
Added code to restore the state of binlog format after the DDL
statement is binlogged.
sql/sql_acl.cc:
Added code to restore the state of binlog format after the DDL
statement is binlogged.
sql/sql_udf.cc:
Added code to restore the state of binlog format after the DDL
statement is binlogged.
Diffstat (limited to 'sql/events.cc')
-rw-r--r-- | sql/events.cc | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/sql/events.cc b/sql/events.cc index 790e6a61699..c3a57578f2b 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -389,6 +389,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) { int ret; + bool save_binlog_row_based; DBUG_ENTER("Events::create_event"); /* @@ -431,8 +432,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for CREATE EVENT command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); pthread_mutex_lock(&LOCK_event_metadata); @@ -472,6 +473,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, { sql_print_error("Event Error: An error occurred while creating query string, " "before writing it into binary log."); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(TRUE); } /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER @@ -480,6 +483,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, } } pthread_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -509,6 +514,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname, LEX_STRING *new_name) { int ret; + bool save_binlog_row_based; Event_queue_element *new_element; DBUG_ENTER("Events::update_event"); @@ -565,8 +571,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for UPDATE EVENT command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); pthread_mutex_lock(&LOCK_event_metadata); @@ -602,6 +608,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, } } pthread_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -635,6 +643,7 @@ bool Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) { int ret; + bool save_binlog_row_based; DBUG_ENTER("Events::drop_event"); /* @@ -662,8 +671,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for DROP EVENT command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); pthread_mutex_lock(&LOCK_event_metadata); /* On error conditions my_error() is called so no need to handle here */ @@ -676,6 +685,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } pthread_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } |