Bug #13004581 BLACKHOLE BINARY LOG WITH ROW IGNORES UPDATE AND DELETE STATEMENTS

When logging to the binary log in row, updates and deletes to a BLACKHOLE
engine table are skipped.
  
It is impossible to log binary log in row format for updates and deletes to
a BLACKHOLE engine table, as no row events can be generated in these cases.
After fix, generate a warning for UPDATE/DELETE statements that modify a
BLACKHOLE table, as row events are not logged in row format.
This commit is contained in:
Bill Qu 2013-04-27 16:04:54 +08:00
parent 2557f2c4ca
commit 975968e245
5 changed files with 40 additions and 0 deletions

0
sql-bench/example.bat Normal file → Executable file
View file

0
sql-bench/pwd.bat Normal file → Executable file
View file

0
sql-bench/uname.bat Normal file → Executable file
View file

View file

@ -6506,6 +6506,8 @@ ER_UNSUPPORTED_ENGINE
ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
eng "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe."
WARN_ON_BLOCKHOLE_IN_RBR
eng "Row events are not logged for %s statements that modify BLACKHOLE tables in row format. Table(s): '%-.192s'"
#
# End of 5.5 error messages.
#

View file

@ -4411,6 +4411,44 @@ int THD::decide_logging_format(TABLE_LIST *tables)
DBUG_PRINT("info", ("decision: logging in %s format",
is_current_stmt_binlog_format_row() ?
"ROW" : "STATEMENT"));
if (variables.binlog_format == BINLOG_FORMAT_ROW &&
(lex->sql_command == SQLCOM_UPDATE ||
lex->sql_command == SQLCOM_UPDATE_MULTI ||
lex->sql_command == SQLCOM_DELETE ||
lex->sql_command == SQLCOM_DELETE_MULTI))
{
String table_names;
/*
Generate a warning for UPDATE/DELETE statements that modify a
BLACKHOLE table, as row events are not logged in row format.
*/
for (TABLE_LIST *table= tables; table; table= table->next_global)
{
if (table->placeholder())
continue;
if (table->table->file->ht->db_type == DB_TYPE_BLACKHOLE_DB &&
table->lock_type >= TL_WRITE_ALLOW_WRITE)
{
table_names.append(table->table_name);
table_names.append(",");
}
}
if (!table_names.is_empty())
{
bool is_update= (lex->sql_command == SQLCOM_UPDATE ||
lex->sql_command == SQLCOM_UPDATE_MULTI);
/*
Replace the last ',' with '.' for table_names
*/
table_names.replace(table_names.length()-1, 1, ".", 1);
push_warning_printf(this, MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_ON_BLOCKHOLE_IN_RBR,
ER(WARN_ON_BLOCKHOLE_IN_RBR),
is_update ? "UPDATE" : "DELETE",
table_names.c_ptr());
}
}
}
#ifndef DBUG_OFF
else