1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00
Fix replication for multi-update
  new test - rpl_multi_update2
This commit is contained in:
acurtis@pcgem.rdg.cyberkinetica.com
2005-01-30 10:24:03 +00:00
parent f003fb1f9c
commit 500fbf5c0f
6 changed files with 192 additions and 19 deletions

View File

@ -56,6 +56,8 @@ static int check_for_max_user_connections(USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
static bool check_multi_update_lock(THD *thd, TABLE_LIST *tables,
List<Item> *fields);
static void mysql_init_query(THD *thd);
static void remove_escape(char *name);
static void refresh_status(void);
@ -1338,10 +1340,28 @@ mysql_execute_command(void)
LEX *lex= &thd->lex;
TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
SELECT_LEX *select_lex = lex->select;
bool slave_fake_lock= 0;
MYSQL_LOCK *fake_prev_lock= 0;
DBUG_ENTER("mysql_execute_command");
if (thd->slave_thread)
{
if (lex->sql_command == SQLCOM_MULTI_UPDATE)
{
DBUG_PRINT("info",("need faked locked tables"));
if (check_multi_update_lock(thd, tables, &select_lex->item_list))
goto error;
/* Fix for replication, the tables are opened and locked,
now we pretend that we have performed a LOCK TABLES action */
fake_prev_lock= thd->locked_tables;
if (thd->lock)
thd->locked_tables= thd->lock;
thd->lock= 0;
slave_fake_lock= 1;
}
/*
Skip if we are in the slave thread, some table rules have been
given and the table list says the query should not be replicated
@ -1949,7 +1969,7 @@ mysql_execute_command(void)
if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
DBUG_VOID_RETURN;
goto error;
}
{
const char *msg= 0;
@ -2641,6 +2661,14 @@ mysql_execute_command(void)
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0);
error:
if (unlikely(slave_fake_lock))
{
DBUG_PRINT("info",("undoing faked lock"));
thd->lock= thd->locked_tables;
thd->locked_tables= fake_prev_lock;
if (thd->lock == thd->locked_tables)
thd->lock= 0;
}
DBUG_VOID_RETURN;
}
@ -3907,3 +3935,54 @@ bool check_simple_select()
}
return 0;
}
/*
Setup locking for multi-table updates. Used by the replication slave.
Replication slave SQL thread examines (all_tables_not_ok()) the
locking state of referenced tables to determine if the query has to
be executed or ignored. Since in multi-table update, the
'default' lock is read-only, this lock is corrected early enough by
calling this function, before the slave decides to execute/ignore.
SYNOPSIS
check_multi_update_lock()
thd Current thread
tables List of user-supplied tables
fields List of fields requiring update
RETURN VALUES
0 ok
1 error
*/
static bool check_multi_update_lock(THD *thd, TABLE_LIST *tables,
List<Item> *fields)
{
bool res= 1;
TABLE_LIST *table;
DBUG_ENTER("check_multi_update_lock");
if (check_db_used(thd, tables))
goto error;
/*
Ensure that we have UPDATE or SELECT privilege for each table
The exact privilege is checked in mysql_multi_update()
*/
for (table= tables ; table ; table= table->next)
{
TABLE_LIST *save= table->next;
table->next= 0;
if (check_one_table_access(thd, UPDATE_ACL, table, 1) &&
check_one_table_access(thd, SELECT_ACL, table, 0))
goto error;
table->next= save;
}
if (mysql_multi_update_lock(thd, tables, fields))
goto error;
res= 0;
error:
DBUG_RETURN(res);
}