mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
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.
This commit is contained in:
@ -2978,6 +2978,7 @@ 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)
|
||||
@ -3073,6 +3074,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
@ -3088,7 +3090,11 @@ 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 */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3101,6 +3107,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||
if (simple_open_n_lock_tables(thd,tables))
|
||||
{ // Should never happen
|
||||
close_thread_tables(thd); /* purecov: deadcode */
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(TRUE); /* purecov: deadcode */
|
||||
}
|
||||
|
||||
@ -3227,6 +3235,8 @@ 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 */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
@ -3255,6 +3265,7 @@ 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)
|
||||
@ -3290,6 +3301,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
@ -3305,13 +3317,19 @@ 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 */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (simple_open_n_lock_tables(thd,tables))
|
||||
{ // Should never happen
|
||||
close_thread_tables(thd);
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
@ -3387,6 +3405,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
|
||||
}
|
||||
|
||||
rw_unlock(&LOCK_grant);
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
|
||||
/* Tables are automatically closed */
|
||||
DBUG_RETURN(result);
|
||||
@ -3401,6 +3421,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
|
||||
char tmp_db[NAME_LEN+1];
|
||||
bool create_new_users=0;
|
||||
TABLE_LIST tables[2];
|
||||
bool save_binlog_row_based;
|
||||
DBUG_ENTER("mysql_grant");
|
||||
if (!initialized)
|
||||
{
|
||||
@ -3429,6 +3450,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
@ -3444,13 +3466,19 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
|
||||
*/
|
||||
tables[0].updating= tables[1].updating= 1;
|
||||
if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
|
||||
{
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (simple_open_n_lock_tables(thd,tables))
|
||||
{ // This should never happen
|
||||
close_thread_tables(thd); /* purecov: deadcode */
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(TRUE); /* purecov: deadcode */
|
||||
}
|
||||
|
||||
@ -3510,6 +3538,8 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
|
||||
|
||||
if (!result)
|
||||
my_ok(thd);
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
@ -5666,6 +5696,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
|
||||
List_iterator <LEX_USER> user_list(list);
|
||||
TABLE_LIST tables[GRANT_TABLES];
|
||||
bool some_users_created= FALSE;
|
||||
bool save_binlog_row_based;
|
||||
DBUG_ENTER("mysql_create_user");
|
||||
|
||||
/*
|
||||
@ -5673,11 +5704,16 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
/* CREATE USER may be skipped on replication client. */
|
||||
if ((result= open_grant_tables(thd, tables)))
|
||||
{
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result != 1);
|
||||
}
|
||||
|
||||
rw_wrlock(&LOCK_grant);
|
||||
VOID(pthread_mutex_lock(&acl_cache->lock));
|
||||
@ -5720,6 +5756,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
|
||||
|
||||
rw_unlock(&LOCK_grant);
|
||||
close_thread_tables(thd);
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
@ -5746,6 +5784,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
|
||||
TABLE_LIST tables[GRANT_TABLES];
|
||||
bool some_users_deleted= FALSE;
|
||||
ulong old_sql_mode= thd->variables.sql_mode;
|
||||
bool save_binlog_row_based;
|
||||
DBUG_ENTER("mysql_drop_user");
|
||||
|
||||
/*
|
||||
@ -5753,11 +5792,16 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
/* DROP USER may be skipped on replication client. */
|
||||
if ((result= open_grant_tables(thd, tables)))
|
||||
{
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result != 1);
|
||||
}
|
||||
|
||||
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
|
||||
|
||||
@ -5794,6 +5838,8 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
|
||||
rw_unlock(&LOCK_grant);
|
||||
close_thread_tables(thd);
|
||||
thd->variables.sql_mode= old_sql_mode;
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
@ -5820,6 +5866,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
|
||||
List_iterator <LEX_USER> user_list(list);
|
||||
TABLE_LIST tables[GRANT_TABLES];
|
||||
bool some_users_renamed= FALSE;
|
||||
bool save_binlog_row_based;
|
||||
DBUG_ENTER("mysql_rename_user");
|
||||
|
||||
/*
|
||||
@ -5827,11 +5874,16 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
/* RENAME USER may be skipped on replication client. */
|
||||
if ((result= open_grant_tables(thd, tables)))
|
||||
{
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result != 1);
|
||||
}
|
||||
|
||||
rw_wrlock(&LOCK_grant);
|
||||
VOID(pthread_mutex_lock(&acl_cache->lock));
|
||||
@ -5878,6 +5930,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
|
||||
|
||||
rw_unlock(&LOCK_grant);
|
||||
close_thread_tables(thd);
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
@ -5902,6 +5956,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
int result;
|
||||
ACL_DB *acl_db;
|
||||
TABLE_LIST tables[GRANT_TABLES];
|
||||
bool save_binlog_row_based;
|
||||
DBUG_ENTER("mysql_revoke_all");
|
||||
|
||||
/*
|
||||
@ -5909,10 +5964,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
if ((result= open_grant_tables(thd, tables)))
|
||||
{
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
DBUG_RETURN(result != 1);
|
||||
}
|
||||
|
||||
rw_wrlock(&LOCK_grant);
|
||||
VOID(pthread_mutex_lock(&acl_cache->lock));
|
||||
@ -6063,6 +6123,8 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
|
||||
if (result)
|
||||
my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
@ -6146,6 +6208,7 @@ 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)))
|
||||
@ -6162,6 +6225,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
|
||||
row-based replication. The flag will be reset at the end of the
|
||||
statement.
|
||||
*/
|
||||
save_binlog_row_based= thd->current_stmt_binlog_row_based;
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
/* Remove procedure access */
|
||||
@ -6198,6 +6262,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
|
||||
close_thread_tables(thd);
|
||||
|
||||
thd->pop_internal_handler();
|
||||
/* Restore the state of binlog format */
|
||||
thd->current_stmt_binlog_row_based= save_binlog_row_based;
|
||||
|
||||
DBUG_RETURN(error_handler.has_errors());
|
||||
}
|
||||
|
Reference in New Issue
Block a user