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

Bug #34707: Row based replication: slave creates table within wrong database

The failure was caused by executing a CREATE-SELECT statement that creates a
table in another database than the current one. In row-based logging, the
CREATE statement was written to the binary log without the database, hence
creating the table in the wrong database, causing the following inserts to
fail since the table didn't exist in the given database.

Fixed the bug by adding a parameter to store_create_info() that will make
the function print the database name before the table name and used that
in the calls that write the CREATE statement to the binary log. The database
name is only printed if it is different than the currently selected database.

The output of SHOW CREATE TABLE has not changed and is still printed without
the database name.
This commit is contained in:
Mats Kindahl
2008-10-08 11:15:00 +02:00
parent e05be97a75
commit 70b18065d0
11 changed files with 118 additions and 10 deletions

View File

@@ -619,7 +619,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
if ((table_list->view ?
view_store_create_info(thd, table_list, &buffer) :
store_create_info(thd, table_list, &buffer, NULL)))
store_create_info(thd, table_list, &buffer, NULL,
FALSE /* show_database */)))
DBUG_RETURN(TRUE);
List<Item> field_list;
@@ -810,7 +811,8 @@ mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name.str));
protocol->prepare_for_resend();
if (store_create_info(thd, table_list, packet, NULL))
if (store_create_info(thd, table_list, packet, NULL,
FALSE /* show_database */))
DBUG_RETURN(-1);
if (fd < 0)
@@ -1062,7 +1064,7 @@ static bool get_field_default_value(THD *thd, TABLE *table,
*/
int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
HA_CREATE_INFO *create_info_arg)
HA_CREATE_INFO *create_info_arg, bool show_database)
{
List<Item> field_list;
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
@@ -1110,6 +1112,25 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
alias= share->table_name.str;
}
}
/*
Print the database before the table name if told to do that. The
database name is only printed in the event that it is different
from the current database. The main reason for doing this is to
avoid having to update gazillions of tests and result files, but
it also saves a few bytes of the binary log.
*/
if (show_database)
{
const LEX_STRING *const db=
table_list->schema_table ? &INFORMATION_SCHEMA_NAME : &table->s->db;
if (strcmp(db->str, thd->db) != 0)
{
append_identifier(thd, packet, db->str, db->length);
packet->append(STRING_WITH_LEN("."));
}
}
append_identifier(thd, packet, alias, strlen(alias));
packet->append(STRING_WITH_LEN(" (\n"));
/*