1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

Fix for BUG#2983 "If statement was killed on master, slave errors despite replicate-wild-ignore-t"

We introduce a new function mysql_test_parse_for_slave().
If the slave sees that the query got a really bad error on master
(killed e.g.), then it calls this function to know if this query
can be ignored because of replicate-*-table rules (do not worry
about replicate-*-db rules: they are checked so early that they have
no bug). If the answer is yes, it skips the query and continues. If
it's no, then it stops and say "fix your slave data manually" (like it
did before this change).


mysql-test/r/rpl_error_ignored_table.result:
  result update
mysql-test/t/rpl_error_ignored_table-slave.opt:
  ignore more tables
mysql-test/t/rpl_error_ignored_table.test:
  we test if a killed query on the master, is ignored on the slave
  if the tables it involves should be excluded because of replicate-*-table
  rules.
sql/log_event.cc:
  If the query got a really bad error on the master (thread killed etc),
  parse it to test the table names: if the replicate-*-do|ignore-table
  rules say "this query must be ignored" then we exit gracefully;
  otherwise we warn about the bad error and tell DBA to check/fix it.
  Before this change, we always warned and stopped.
sql/mysql_priv.h:
  new function
sql/slave.cc:
  don't print error immediately as we need to do one more test to
  be sure.
sql/sql_parse.cc:
  we add a function mysql_test_parse_for_slave(), to be used only
  by the slave if it wants to know if the query should be ignored or not;
  so this function only parses the query, does not execute it.
This commit is contained in:
unknown
2004-03-11 17:38:19 +01:00
parent b1e0a38f18
commit bd6c4ef400
7 changed files with 182 additions and 85 deletions

View File

@@ -65,6 +65,7 @@ static bool create_total_list(THD *thd, LEX *lex,
TABLE_LIST **result, bool skip_first);
static bool check_one_table_access(THD *thd, ulong want_access,
TABLE_LIST *table, bool no_errors);
static inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables);
const char *any_db="*any*"; // Special symbol for check_access
@@ -1332,9 +1333,7 @@ mysql_execute_command(void)
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
*/
if (table_rules_on && tables && !tables_ok(thd,tables) &&
((lex->sql_command != SQLCOM_DELETE_MULTI) ||
!tables_ok(thd,(TABLE_LIST *)thd->lex.auxilliary_table_list.first)))
if (all_tables_not_ok(thd,tables))
{
/* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
@@ -2968,9 +2967,18 @@ void mysql_init_multi_delete(LEX *lex)
lex->select->table_list.save_and_clear(&lex->auxilliary_table_list);
}
static inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
{
return (table_rules_on && tables && !tables_ok(thd,tables) &&
((thd->lex.sql_command != SQLCOM_DELETE_MULTI) ||
!tables_ok(thd,(TABLE_LIST *)thd->lex.auxilliary_table_list.first)));
}
void
mysql_parse(THD *thd,char *inBuf,uint length)
/*
When you modify mysql_parse(), you may need to mofify
mysql_test_parse_for_slave() in this same file.
*/
void mysql_parse(THD *thd, char *inBuf, uint length)
{
DBUG_ENTER("mysql_parse");
@@ -3005,6 +3013,31 @@ mysql_parse(THD *thd,char *inBuf,uint length)
DBUG_VOID_RETURN;
}
/*
Usable by the replication SQL thread only: just parse a query to know if it
can be ignored because of replicate-*-table rules.
RETURN VALUES
0 cannot be ignored
1 can be ignored
*/
bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
{
LEX *lex;
bool error= 0;
mysql_init_query(thd);
lex= lex_start(thd, (uchar*) inBuf, length);
if (!yyparse() && ! thd->fatal_error &&
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
error= 1; /* Ignore question */
free_items(thd); /* Free strings used by items */
lex_end(lex);
return error;
}
/*****************************************************************************
** Store field definition for create