summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorLuis Soares <luis.soares@sun.com>2009-07-26 22:48:24 +0100
committerLuis Soares <luis.soares@sun.com>2009-07-26 22:48:24 +0100
commit6b2c3ff568f98963676a9c416556ffa20fd252aa (patch)
tree3c0b18a6e2b864bf57586f4621b7343d5689aad8 /sql/sql_table.cc
parent97ff334b371331e34ec741a021d8aa0b5449480e (diff)
downloadmariadb-git-6b2c3ff568f98963676a9c416556ffa20fd252aa.tar.gz
BUG#43046: mixed mode switch to row format with temp table lead
to wrong result When using MIXED mode and issuing 'CREATE TEMPORARY TABLE t_tmp', the statement is logged if the current binlogging mode is STATEMENT. This causes the slave to replay the instruction and create the temporary table as well. If there is no switch to ROW mode, and later on a 'DROP TEMPORARY TABLE t_tmp' is issued, then this statement will also be logged and the slave will remove/close the temporary table. However, if there is a switch to ROW mode between the CREATE and DROP TEMPORARY table, the DROP statement will not be logged, leaving the slave with a dangling temporary table. This patch addresses this, by always logging a DROP TEMPORARY TABLE IF EXISTS when in mixed mode and a drop statement is issued for temporary table(s).
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc75
1 files changed, 59 insertions, 16 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index e752421223a..ad9671c444b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1799,6 +1799,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
int non_temp_tables_count= 0;
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
String built_query;
+ String built_tmp_query;
DBUG_ENTER("mysql_rm_table_part2");
LINT_INIT(alias);
@@ -1866,6 +1867,25 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
case 0:
// removed temporary table
tmp_table_deleted= 1;
+ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
+ thd->current_stmt_binlog_row_based)
+ {
+ if (built_tmp_query.is_empty())
+ {
+ built_tmp_query.set_charset(system_charset_info);
+ built_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS ");
+ }
+
+ built_tmp_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+ built_tmp_query.append(db);
+ built_tmp_query.append("`.`");
+ }
+ built_tmp_query.append(table->table_name);
+ built_tmp_query.append("`,");
+ }
+
continue;
case -1:
DBUG_ASSERT(thd->in_sub_stmt);
@@ -2023,29 +2043,52 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
write_bin_log(thd, !error, thd->query, thd->query_length);
}
else if (thd->current_stmt_binlog_row_based &&
- non_temp_tables_count > 0 &&
tmp_table_deleted)
{
+ if (non_temp_tables_count > 0)
+ {
+ /*
+ In this case we have deleted both temporary and
+ non-temporary tables, so:
+ - since we have deleted a non-temporary table we have to
+ binlog the statement, but
+ - since we have deleted a temporary table we cannot binlog
+ the statement (since the table may have not been created on the
+ slave - check "if" branch below, this might cause the slave to
+ stop).
+
+ Instead, we write a built statement, only containing the
+ non-temporary tables, to the binary log
+ */
+ built_query.chop(); // Chop of the last comma
+ built_query.append(" /* generated by server */");
+ write_bin_log(thd, !error, built_query.ptr(), built_query.length());
+ }
+
/*
- In this case we have deleted both temporary and
- non-temporary tables, so:
- - since we have deleted a non-temporary table we have to
- binlog the statement, but
- - since we have deleted a temporary table we cannot binlog
- the statement (since the table has not been created on the
- slave, this might cause the slave to stop).
-
- Instead, we write a built statement, only containing the
- non-temporary tables, to the binary log
+ One needs to always log any temporary table drop, if:
+ 1. thread logging format is mixed mode; AND
+ 2. current statement logging format is set to row.
*/
- built_query.chop(); // Chop of the last comma
- built_query.append(" /* generated by server */");
- write_bin_log(thd, !error, built_query.ptr(), built_query.length());
+ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED)
+ {
+ /*
+ In this case we have deleted some temporary tables but we are using
+ row based logging for the statement. However, thread uses mixed mode
+ format, thence we need to log the dropping as we cannot tell for
+ sure whether the create was logged as statement previously or not, ie,
+ before switching to row mode.
+ */
+ built_tmp_query.chop(); // Chop of the last comma
+ built_tmp_query.append(" /* generated by server */");
+ write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length());
+ }
}
+
/*
The remaining cases are:
- - no tables where deleted and
- - only temporary tables where deleted and row-based
+ - no tables were deleted and
+ - only temporary tables were deleted and row-based
replication is used.
In both these cases, nothing should be written to the binary
log.