diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 0eb65cff91e..21e3634f6c7 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -1112,17 +1112,15 @@ update_timing_fields_for_event(THD *thd, TABLE *table= NULL; Field **fields; int ret= 1; - bool save_binlog_row_based; + enum_binlog_format save_binlog_format; MYSQL_TIME time; - DBUG_ENTER("Event_db_repository::update_timing_fields_for_event"); /* Turn off row binlogging of event timing updates. These are not used for RBR of events replicated to the slave. */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_format= thd->set_current_stmt_binlog_format_stmt(); DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL); @@ -1157,10 +1155,7 @@ end: if (table) close_mysql_tables(thd); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(test(ret)); } diff --git a/sql/events.cc b/sql/events.cc index 8b4bab9e3a6..d8caa059c64 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -306,7 +306,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) { bool ret; - bool save_binlog_row_based, event_already_exists; + bool event_already_exists; + enum_binlog_format save_binlog_format; DBUG_ENTER("Events::create_event"); if (check_if_system_tables_error()) @@ -338,8 +339,7 @@ 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 ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_format= thd->set_current_stmt_binlog_format_stmt(); if (lock_object_name(thd, MDL_key::EVENT, parse_data->dbname.str, parse_data->name.str)) @@ -398,10 +398,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, } } } - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + + thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(ret); } @@ -431,7 +429,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; + enum_binlog_format save_binlog_format; Event_queue_element *new_element; DBUG_ENTER("Events::update_event"); @@ -478,8 +476,7 @@ 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 ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_format= thd->set_current_stmt_binlog_format_stmt(); if (lock_object_name(thd, MDL_key::EVENT, parse_data->dbname.str, parse_data->name.str)) @@ -513,11 +510,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } } - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(ret); } @@ -550,7 +544,7 @@ bool Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) { int ret; - bool save_binlog_row_based; + enum_binlog_format save_binlog_format; DBUG_ENTER("Events::drop_event"); if (check_if_system_tables_error()) @@ -563,8 +557,7 @@ 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 ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_format= thd->set_current_stmt_binlog_format_stmt(); if (lock_object_name(thd, MDL_key::EVENT, dbname.str, name.str)) @@ -578,10 +571,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) DBUG_ASSERT(thd->query() && thd->query_length()); ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + + thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(ret); } diff --git a/sql/sp.cc b/sql/sp.cc index 93cd64b4104..a1ff4db375b 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -984,9 +984,6 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) enum_check_fields saved_count_cuted_fields; bool store_failed= FALSE; - - bool save_binlog_row_based; - DBUG_ENTER("sp_create_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", (int) type, (int) sp->m_name.length, @@ -1004,14 +1001,6 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) /* Reset sql_mode during data dictionary operations. */ thd->variables.sql_mode= 0; - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - saved_count_cuted_fields= thd->count_cuted_fields; thd->count_cuted_fields= CHECK_FIELD_WARN; @@ -1217,10 +1206,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) done: thd->count_cuted_fields= saved_count_cuted_fields; thd->variables.sql_mode= saved_mode; - /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); } @@ -1245,7 +1231,6 @@ sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name) { TABLE *table; int ret; - bool save_binlog_row_based; MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? MDL_key::FUNCTION : MDL_key::PROCEDURE; DBUG_ENTER("sp_drop_routine"); @@ -1267,9 +1252,6 @@ sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name) row-based replication. The flag will be reset at the end of the statement. */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK) { if (table->file->ha_delete_row(table->record[0])) @@ -1296,10 +1278,7 @@ sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name) sp_cache_flush_obsolete(spc, &sp); } } - /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); } @@ -1327,7 +1306,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, { TABLE *table; int ret; - bool save_binlog_row_based; MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? MDL_key::FUNCTION : MDL_key::PROCEDURE; DBUG_ENTER("sp_update_routine"); @@ -1345,14 +1323,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, if (!(table= open_proc_table_for_update(thd))) DBUG_RETURN(SP_OPEN_TABLE_FAILED); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK) { if (type == TYPE_ENUM_FUNCTION && ! trust_function_creators && @@ -1406,10 +1376,7 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, sp_cache_invalidate(); } err: - /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8f27c45247e..139d761a78e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1877,7 +1877,7 @@ bool change_password(THD *thd, const char *host, const char *user, /* Buffer should be extended when password length is extended. */ char buff[512]; ulong query_length; - bool save_binlog_row_based; + enum_binlog_format save_binlog_format; uint new_password_len= (uint) strlen(new_password); bool result= 1; DBUG_ENTER("change_password"); @@ -1914,9 +1914,10 @@ bool change_password(THD *thd, const char *host, const char *user, This statement will be replicated as a statement, even when using row-based replication. The flag will be reset at the end of the statement. + This has to be handled here as it's called by set_var.cc, which is + not automaticly handled by sql_parse.cc */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_format= thd->set_current_stmt_binlog_format_stmt(); mysql_mutex_lock(&acl_cache->lock); ACL_USER *acl_user; @@ -1965,11 +1966,7 @@ bool change_password(THD *thd, const char *host, const char *user, } end: close_mysql_tables(thd); - - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + thd->restore_stmt_binlog_format(save_binlog_format); DBUG_RETURN(result); } @@ -3540,7 +3537,6 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, TABLE_LIST tables[3]; bool create_new_users=0; char *db_name, *table_name; - bool save_binlog_row_based; DBUG_ENTER("mysql_table_grant"); if (!initialized) @@ -3630,14 +3626,6 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (column_priv || (revoke_grant && ((rights & COL_ACLS) || columns.elements))) tables[1].next_local= tables[1].next_global= tables+2; - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - #ifdef HAVE_REPLICATION /* GRANT and REVOKE are applied the slave in/exclusion rules as they are @@ -3651,13 +3639,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, */ tables[0].updating= tables[1].updating= tables[2].updating= 1; if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(FALSE); - } } #endif @@ -3675,11 +3657,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, thd->lex->sql_command= backup.sql_command; if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT)) { // Should never happen - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); thd->lex->restore_backup_query_tables_list(&backup); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(TRUE); /* purecov: deadcode */ } @@ -3807,9 +3785,6 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, /* Tables are automatically closed */ thd->lex->restore_backup_query_tables_list(&backup); /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result); } @@ -3838,7 +3813,6 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, TABLE_LIST tables[2]; bool create_new_users=0, result=0; char *db_name, *table_name; - bool save_binlog_row_based; DBUG_ENTER("mysql_routine_grant"); if (!initialized) @@ -3868,14 +3842,6 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, C_STRING_WITH_LEN("procs_priv"), "procs_priv", TL_WRITE); tables[0].next_local= tables[0].next_global= tables+1; - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - #ifdef HAVE_REPLICATION /* GRANT and REVOKE are applied the slave in/exclusion rules as they are @@ -3890,23 +3856,15 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, tables[0].updating= tables[1].updating= 1; if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(FALSE); } } #endif if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT)) - { // Should never happen - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(TRUE); - } + + DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); if (!revoke_grant) create_new_users= test_if_create_new_users(thd); @@ -3981,10 +3939,6 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, } mysql_rwlock_unlock(&LOCK_grant); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); /* Tables are automatically closed */ DBUG_RETURN(result); @@ -3999,8 +3953,8 @@ bool mysql_grant(THD *thd, const char *db, List &list, char tmp_db[SAFE_NAME_LEN+1]; bool create_new_users=0; TABLE_LIST tables[2]; - bool save_binlog_row_based; DBUG_ENTER("mysql_grant"); + if (!initialized) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), @@ -4037,14 +3991,6 @@ bool mysql_grant(THD *thd, const char *db, List &list, TL_WRITE); tables[0].next_local= tables[0].next_global= tables+1; - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - #ifdef HAVE_REPLICATION /* GRANT and REVOKE are applied the slave in/exclusion rules as they are @@ -4058,24 +4004,14 @@ bool mysql_grant(THD *thd, const char *db, List &list, */ tables[0].updating= tables[1].updating= 1; if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(FALSE); - } } #endif if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT)) - { // This should never happen - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(TRUE); /* purecov: deadcode */ - } + + DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); if (!revoke_grant) create_new_users= test_if_create_new_users(thd); @@ -4139,10 +4075,6 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (!result) my_ok(thd); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result); } @@ -6453,26 +6385,11 @@ bool mysql_create_user(THD *thd, List &list) List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; bool some_users_created= FALSE; - bool save_binlog_row_based; DBUG_ENTER("mysql_create_user"); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - /* CREATE USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result != 1); - } mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); @@ -6513,10 +6430,6 @@ bool mysql_create_user(THD *thd, List &list) result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); mysql_rwlock_unlock(&LOCK_grant); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result); } @@ -6543,26 +6456,11 @@ bool mysql_drop_user(THD *thd, List &list) TABLE_LIST tables[GRANT_TABLES]; bool some_users_deleted= FALSE; ulonglong old_sql_mode= thd->variables.sql_mode; - bool save_binlog_row_based; DBUG_ENTER("mysql_drop_user"); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - /* DROP USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result != 1); - } thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; @@ -6598,10 +6496,6 @@ bool mysql_drop_user(THD *thd, List &list) mysql_rwlock_unlock(&LOCK_grant); thd->variables.sql_mode= old_sql_mode; - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result); } @@ -6628,26 +6522,13 @@ bool mysql_rename_user(THD *thd, List &list) List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; bool some_users_renamed= FALSE; - bool save_binlog_row_based; DBUG_ENTER("mysql_rename_user"); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - /* RENAME USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result != 1); - } + + DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); @@ -6693,10 +6574,6 @@ bool mysql_rename_user(THD *thd, List &list) result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); mysql_rwlock_unlock(&LOCK_grant); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result); } @@ -6721,25 +6598,12 @@ bool mysql_revoke_all(THD *thd, List &list) int result; ACL_DB *acl_db; TABLE_LIST tables[GRANT_TABLES]; - bool save_binlog_row_based; DBUG_ENTER("mysql_revoke_all"); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - if ((result= open_grant_tables(thd, tables))) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result != 1); - } + + DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); @@ -6890,10 +6754,6 @@ bool mysql_revoke_all(THD *thd, List &list) write_bin_log(thd, FALSE, thd->query(), thd->query_length()); mysql_rwlock_unlock(&LOCK_grant); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(result); } @@ -6985,26 +6845,19 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, TABLE_LIST tables[GRANT_TABLES]; HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; Silence_routine_definer_errors error_handler; - bool save_binlog_row_based; DBUG_ENTER("sp_revoke_privileges"); if ((result= open_grant_tables(thd, tables))) DBUG_RETURN(result != 1); + DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); + /* Be sure to pop this before exiting this scope! */ thd->push_internal_handler(&error_handler); mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - /* Remove procedure access */ do { @@ -7038,10 +6891,6 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, mysql_rwlock_unlock(&LOCK_grant); thd->pop_internal_handler(); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(error_handler.has_errors()); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 845c2115922..054f267ed01 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2722,6 +2722,27 @@ public: void set_n_backup_active_arena(Query_arena *set, Query_arena *backup); void restore_active_arena(Query_arena *set, Query_arena *backup); + inline void get_binlog_format(enum_binlog_format *format, + enum_binlog_format *current_format) + { + *format= (enum_binlog_format) variables.binlog_format; + *current_format= current_stmt_binlog_format; + } + inline void set_binlog_format(enum_binlog_format format, + enum_binlog_format current_format) + { + DBUG_ENTER("set_binlog_format"); + variables.binlog_format= format; + current_stmt_binlog_format= current_format; + DBUG_VOID_RETURN; + } + inline void set_binlog_format_stmt() + { + DBUG_ENTER("set_binlog_format_stmt"); + variables.binlog_format= BINLOG_FORMAT_STMT; + current_stmt_binlog_format= BINLOG_FORMAT_STMT; + DBUG_VOID_RETURN; + } /* @todo Make these methods private or remove them completely. Only decide_logging_format should call them. /Sven @@ -2752,16 +2773,26 @@ public: DBUG_VOID_RETURN; } + inline void set_current_stmt_binlog_format_row() { DBUG_ENTER("set_current_stmt_binlog_format_row"); current_stmt_binlog_format= BINLOG_FORMAT_ROW; DBUG_VOID_RETURN; } - inline void clear_current_stmt_binlog_format_row() + /* Set binlog format temporarily to statement. Returns old format */ + inline enum_binlog_format set_current_stmt_binlog_format_stmt() { - DBUG_ENTER("clear_current_stmt_binlog_format_row"); + enum_binlog_format orig_format= current_stmt_binlog_format; + DBUG_ENTER("set_current_stmt_binlog_format_stmt"); current_stmt_binlog_format= BINLOG_FORMAT_STMT; + DBUG_RETURN(orig_format); + } + inline void restore_stmt_binlog_format(enum_binlog_format format) + { + DBUG_ENTER("restore_stmt_binlog_format"); + DBUG_ASSERT(!is_current_stmt_binlog_format_row()); + current_stmt_binlog_format= format; DBUG_VOID_RETURN; } inline void reset_current_stmt_binlog_format_row() @@ -2791,7 +2822,7 @@ public: if (variables.binlog_format == BINLOG_FORMAT_ROW) set_current_stmt_binlog_format_row(); else if (temporary_tables == NULL) - clear_current_stmt_binlog_format_row(); + set_current_stmt_binlog_format_stmt(); } DBUG_VOID_RETURN; } @@ -4085,6 +4116,11 @@ public: */ #define CF_CAN_GENERATE_ROW_EVENTS (1U << 9) +/** + Statement that need the binlog format to be unchanged. +*/ +#define CF_FORCE_ORIGINAL_BINLOG_FORMAT (1U << 10) + /* Bits in server_command_flags */ /** diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6f157c89ee2..91bdad3da62 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -350,7 +350,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND; - sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT]= CF_STATUS_COMMAND | CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_SHOW_CLIENT_STATS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_USER_STATS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_TABLE_STATS]= CF_STATUS_COMMAND; @@ -385,6 +385,19 @@ void init_update_queries(void) CF_CAN_GENERATE_ROW_EVENTS; sql_command_flags[SQLCOM_EXECUTE]= CF_CAN_GENERATE_ROW_EVENTS; + /* + We don't want to change to statement based replication for these commands + */ + sql_command_flags[SQLCOM_ROLLBACK]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + /* We don't want to replicate ALTER TABLE for temp tables in row format */ + sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + /* We don't want to replicate TRUNCATE for temp tables in row format */ + sql_command_flags[SQLCOM_TRUNCATE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + /* We don't want to replicate DROP for temp tables in row format */ + sql_command_flags[SQLCOM_DROP_TABLE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + /* One can change replication mode with SET */ + sql_command_flags[SQLCOM_SET_OPTION]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + /* The following admin table operations are allowed on log tables. @@ -2102,6 +2115,22 @@ mysql_execute_command(THD *thd) DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE); + /* store old value of binlog format */ + enum_binlog_format orig_binlog_format,orig_current_stmt_binlog_format; + + thd->get_binlog_format(&orig_binlog_format, + &orig_current_stmt_binlog_format); + + /* + Force statement logging for DDL commands to allow us to update + privilege, system or statistic tables directly without the updates + getting logged. + */ + if (!(sql_command_flags[lex->sql_command] & + (CF_CAN_GENERATE_ROW_EVENTS | CF_FORCE_ORIGINAL_BINLOG_FORMAT | + CF_STATUS_COMMAND))) + thd->set_binlog_format_stmt(); + /* End a active transaction so that this command will have it's own transaction and will also sync the binary log. If a DDL is @@ -4529,6 +4558,11 @@ finish: if (lex->sql_command != SQLCOM_SET_OPTION && ! thd->in_sub_stmt) DEBUG_SYNC(thd, "execute_command_after_close_tables"); #endif + if (!(sql_command_flags[lex->sql_command] & + (CF_CAN_GENERATE_ROW_EVENTS | CF_FORCE_ORIGINAL_BINLOG_FORMAT | + CF_STATUS_COMMAND))) + thd->set_binlog_format(orig_binlog_format, + orig_current_stmt_binlog_format); if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END)) { diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 169e0d9e418..9069d876609 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -428,7 +428,6 @@ int mysql_create_function(THD *thd,udf_func *udf) TABLE *table; TABLE_LIST tables; udf_func *u_d; - bool save_binlog_row_based; DBUG_ENTER("mysql_create_function"); if (!initialized) @@ -459,13 +458,6 @@ int mysql_create_function(THD *thd,udf_func *udf) DBUG_RETURN(1); } - /* - Turn off row binlogging of this statement and use statement-based - so that all supporting tables are updated for CREATE FUNCTION command. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - mysql_rwlock_wrlock(&THR_LOCK_udf); if ((my_hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length))) { @@ -533,27 +525,14 @@ int mysql_create_function(THD *thd,udf_func *udf) /* Binlog the create function. */ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(1); - } - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + DBUG_RETURN(0); err: if (new_dl) dlclose(dl); mysql_rwlock_unlock(&THR_LOCK_udf); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(1); } @@ -565,7 +544,6 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) udf_func *udf; char *exact_name_str; uint exact_name_len; - bool save_binlog_row_based; DBUG_ENTER("mysql_drop_function"); if (!initialized) @@ -577,13 +555,6 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) DBUG_RETURN(1); } - /* - Turn off row binlogging of this statement and use statement-based - so that all supporting tables are updated for DROP FUNCTION command. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - mysql_rwlock_wrlock(&THR_LOCK_udf); if (!(udf=(udf_func*) my_hash_search(&udf_hash,(uchar*) udf_name->str, (uint) udf_name->length))) @@ -623,24 +594,12 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) while binlogging, to avoid binlog inconsistency. */ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) - { - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(1); - } - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); + DBUG_RETURN(0); + err: mysql_rwlock_unlock(&THR_LOCK_udf); - /* Restore the state of binlog format */ - DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(1); }