1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug #11765416 (former 58381)

FAILED DROP DATABASE CAN BREAK STATEMENT BASED REPLICATION

The first phase of DROP DATABASE is to delete the tables in the database.
If deletion of one or more of the tables fail (e.g. due to a FOREIGN KEY
constraint), DROP DATABASE will be aborted. However, some tables could
still have been deleted. The problem was that nothing would be written
to the binary log in this case, so any slaves would not delete these tables.
Therefore the master and the slaves would get out of sync.

This patch fixes the problem by making sure that DROP TABLE is written
to the binary log for the tables that were in fact deleted by the failed
DROP DATABASE statement.

Test case added to binlog.binlog_database.test.
This commit is contained in:
Jon Olav Hauglid
2011-03-15 11:49:14 +01:00
parent dd14e37661
commit f94e7288e3
3 changed files with 108 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -833,12 +833,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
}
thd->push_internal_handler(&err_handler);
if (thd->killed ||
(tables && mysql_rm_table_no_locks(thd, tables, true, false, true, true)))
{
tables= NULL;
}
else
if (!thd->killed &&
!(tables &&
mysql_rm_table_no_locks(thd, tables, true, false, true, true)))
{
/*
We temporarily disable the binary log while dropping the objects
@ -923,7 +920,7 @@ update_binlog:
thd->server_status|= SERVER_STATUS_DB_DROPPED;
my_ok(thd, deleted_tables);
}
else if (mysql_bin_log.is_open())
else if (mysql_bin_log.is_open() && !silent)
{
char *query, *query_pos, *query_end, *query_data_start;
TABLE_LIST *tbl;
@ -938,6 +935,16 @@ update_binlog:
for (tbl= tables; tbl; tbl= tbl->next_local)
{
uint tbl_name_len;
bool exists;
// Only write drop table to the binlog for tables that no longer exist.
if (check_if_table_exists(thd, tbl, &exists))
{
error= true;
goto exit;
}
if (exists)
continue;
/* 3 for the quotes and the comma*/
tbl_name_len= strlen(tbl->table_name) + 3;