1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

BUG#37051 Replication rules not evaluated correctly

Backporting patch to 5.0.
This commit is contained in:
He Zhenxing
2009-03-05 18:10:44 +08:00
parent 62d5d85c5d
commit b4fdb8aec1
15 changed files with 594 additions and 27 deletions

View File

@ -2584,6 +2584,10 @@ mysql_execute_command(THD *thd)
TABLE_LIST *all_tables;
/* most outer SELECT_LEX_UNIT of query */
SELECT_LEX_UNIT *unit= &lex->unit;
#ifdef HAVE_REPLICATION
/* have table map for update for multi-update statement (BUG#37051) */
bool have_table_map_for_update= FALSE;
#endif
/* Saved variable value */
DBUG_ENTER("mysql_execute_command");
thd->net.no_send_error= 0;
@ -2663,6 +2667,48 @@ mysql_execute_command(THD *thd)
// force searching in slave.cc:tables_ok()
all_tables->updating= 1;
}
/*
For fix of BUG#37051, the master stores the table map for update
in the Query_log_event, and the value is assigned to
thd->variables.table_map_for_update before executing the update
query.
If thd->variables.table_map_for_update is set, then we are
replicating from a new master, we can use this value to apply
filter rules without opening all the tables. However If
thd->variables.table_map_for_update is not set, then we are
replicating from an old master, so we just skip this and
continue with the old method. And of course, the bug would still
exist for old masters.
*/
if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
thd->table_map_for_update)
{
have_table_map_for_update= TRUE;
table_map table_map_for_update= thd->table_map_for_update;
uint nr= 0;
TABLE_LIST *table;
for (table=all_tables; table; table=table->next_global, nr++)
{
if (table_map_for_update & ((table_map)1 << nr))
table->updating= TRUE;
else
table->updating= FALSE;
}
if (all_tables_not_ok(thd, all_tables))
{
/* we warn the slave SQL thread */
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
if (thd->one_shot_set)
reset_one_shot_variables(thd);
DBUG_RETURN(0);
}
for (table=all_tables; table; table=table->next_global)
table->updating= TRUE;
}
/*
Check if statment should be skipped because of slave filtering
@ -3608,7 +3654,7 @@ end_with_restore_list:
#ifdef HAVE_REPLICATION
/* Check slave filtering rules */
if (unlikely(thd->slave_thread))
if (unlikely(thd->slave_thread && !have_table_map_for_update))
{
if (all_tables_not_ok(thd, all_tables))
{