Commit f6d876ac authored by mats@kindahl-laptop.dnsalias.net's avatar mats@kindahl-laptop.dnsalias.net

Merge kindahl-laptop.dnsalias.net:/home/bkroot/mysql-5.1-rpl

into  kindahl-laptop.dnsalias.net:/home/bk/b28722-mysql-5.1-rpl
parents e6f7d608 3975652c
...@@ -11,6 +11,7 @@ START TRANSACTION; ...@@ -11,6 +11,7 @@ START TRANSACTION;
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2); INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f; UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c; UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
ERROR HY000: Binary logging not possible. Message: Statement-based format required for this statement, but not allowed by this combination of engines
COMMIT; COMMIT;
TRUNCATE t1m; TRUNCATE t1m;
TRUNCATE t1b; TRUNCATE t1b;
...@@ -41,11 +42,25 @@ INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2); ...@@ -41,11 +42,25 @@ INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2); INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2); INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
ERROR HY000: Binary logging not possible. Message: Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c; UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
ERROR HY000: Binary logging not possible. Message: Statement cannot be logged to the binary log in row-based nor statement-based format ERROR HY000: Binary logging not possible. Message: Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging
TRUNCATE t1m; TRUNCATE t1m;
TRUNCATE t1b; TRUNCATE t1b;
TRUNCATE t1n; TRUNCATE t1n;
SET SESSION BINLOG_FORMAT=ROW;
INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
ERROR HY000: Binary logging not possible. Message: Row-based format required for this statement, but not allowed by this combination of engines
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
ERROR HY000: Binary logging not possible. Message: Row-based format required for this statement, but not allowed by this combination of engines
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
ERROR HY000: Binary logging not possible. Message: Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
ERROR HY000: Binary logging not possible. Message: Row-based format required for this statement, but not allowed by this combination of engines
DROP TABLE t1m, t1b, t1n;
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2) master-bin.000001 # Query # # use `test`; INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2)
......
# Test to test how logging is done depending on the capabilities of
# the engines. Unfortunately, we don't have a good row-only logging
# engine, and NDB does not really cut is since it is also
# self-logging. I'm using it nevertheless.
source include/have_blackhole.inc; source include/have_blackhole.inc;
source include/have_ndb.inc; source include/have_ndb.inc;
source include/have_binlog_format_mixed_or_row.inc; source include/have_binlog_format_mixed_or_row.inc;
...@@ -40,6 +45,8 @@ INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2); ...@@ -40,6 +45,8 @@ INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2); INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
error ER_BINLOG_LOGGING_IMPOSSIBLE;
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
# Not possible to test this since NDB writes its own binlog, which # Not possible to test this since NDB writes its own binlog, which
# might cause it to be out of sync with the results from MyISAM. # might cause it to be out of sync with the results from MyISAM.
...@@ -47,6 +54,7 @@ UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c; ...@@ -47,6 +54,7 @@ UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
#UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f; #UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
>>>>>>>
error ER_BINLOG_LOGGING_IMPOSSIBLE; error ER_BINLOG_LOGGING_IMPOSSIBLE;
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c; UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
...@@ -67,6 +75,8 @@ INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2); ...@@ -67,6 +75,8 @@ INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
error ER_BINLOG_LOGGING_IMPOSSIBLE; error ER_BINLOG_LOGGING_IMPOSSIBLE;
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c; UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
error ER_BINLOG_LOGGING_IMPOSSIBLE;
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
# Not possible to test this since NDB writes its own binlog, which # Not possible to test this since NDB writes its own binlog, which
# might cause it to be out of sync with the results from MyISAM. # might cause it to be out of sync with the results from MyISAM.
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <io.h> #include <io.h>
#endif #endif
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
/** /**
This internal handler is used to trap internally This internal handler is used to trap internally
errors that can occur when executing open table errors that can occur when executing open table
...@@ -3996,36 +3998,47 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) ...@@ -3996,36 +3998,47 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
{ {
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
{ {
handler::Table_flags binlog_flags= ~handler::Table_flags(); handler::Table_flags flags_some_set= handler::Table_flags();
handler::Table_flags flags_all_set= ~handler::Table_flags();
my_bool multi_engine= FALSE;
void* prev_ht= NULL;
for (TABLE_LIST *table= tables; table; table= table->next_global) for (TABLE_LIST *table= tables; table; table= table->next_global)
{
if (!table->placeholder() && table->lock_type >= TL_WRITE_ALLOW_WRITE) if (!table->placeholder() && table->lock_type >= TL_WRITE_ALLOW_WRITE)
{ {
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "") ulonglong const flags= table->table->file->ha_table_flags();
#ifndef DBUG_OFF
ulonglong flags= table->table->file->ha_table_flags();
DBUG_PRINT("info", ("table: %s; ha_table_flags: %s%s", DBUG_PRINT("info", ("table: %s; ha_table_flags: %s%s",
table->table_name, table->table_name,
FLAGSTR(flags, HA_BINLOG_STMT_CAPABLE), FLAGSTR(flags, HA_BINLOG_STMT_CAPABLE),
FLAGSTR(flags, HA_BINLOG_ROW_CAPABLE))); FLAGSTR(flags, HA_BINLOG_ROW_CAPABLE)));
#endif if (prev_ht && prev_ht != table->table->file->ht)
binlog_flags &= table->table->file->ha_table_flags(); multi_engine= TRUE;
prev_ht= table->table->file->ht;
flags_all_set &= flags;
flags_some_set |= flags;
} }
binlog_flags&= HA_BINLOG_FLAGS; }
DBUG_PRINT("info", ("binlog_flags: %s%s",
FLAGSTR(binlog_flags, HA_BINLOG_STMT_CAPABLE), DBUG_PRINT("info", ("flags_all_set: %s%s",
FLAGSTR(binlog_flags, HA_BINLOG_ROW_CAPABLE))); FLAGSTR(flags_all_set, HA_BINLOG_STMT_CAPABLE),
FLAGSTR(flags_all_set, HA_BINLOG_ROW_CAPABLE)));
DBUG_PRINT("info", ("flags_some_set: %s%s",
FLAGSTR(flags_some_set, HA_BINLOG_STMT_CAPABLE),
FLAGSTR(flags_some_set, HA_BINLOG_ROW_CAPABLE)));
DBUG_PRINT("info", ("thd->variables.binlog_format: %ld", DBUG_PRINT("info", ("thd->variables.binlog_format: %ld",
thd->variables.binlog_format)); thd->variables.binlog_format));
DBUG_PRINT("info", ("multi_engine: %s",
multi_engine ? "TRUE" : "FALSE"));
int error= 0; int error= 0;
if (binlog_flags == 0) if (flags_all_set == 0)
{ {
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0), my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
"Statement cannot be logged to the binary log in" "Statement cannot be logged to the binary log in"
" row-based nor statement-based format"); " row-based nor statement-based format");
} }
else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT && else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
(binlog_flags & HA_BINLOG_STMT_CAPABLE) == 0) (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
{ {
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0), my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
"Statement-based format required for this statement," "Statement-based format required for this statement,"
...@@ -4033,13 +4046,29 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) ...@@ -4033,13 +4046,29 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
} }
else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW || else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW ||
thd->lex->is_stmt_unsafe()) && thd->lex->is_stmt_unsafe()) &&
(binlog_flags & HA_BINLOG_ROW_CAPABLE) == 0) (flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
{ {
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0), my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
"Row-based format required for this statement," "Row-based format required for this statement,"
" but not allowed by this combination of engines"); " but not allowed by this combination of engines");
} }
/*
If more than one engine is involved in the statement and at
least one is doing it's own logging (is *self-logging*), the
statement cannot be logged atomically, so we generate an error
rather than allowing the binlog to become corrupt.
*/
if (multi_engine &&
(flags_some_set & HA_HAS_OWN_BINLOGGING))
{
error= ER_BINLOG_LOGGING_IMPOSSIBLE;
my_error(error, MYF(0),
"Statement cannot be written atomically since more"
" than one engine involved and at least one engine"
" is self-logging");
}
DBUG_PRINT("info", ("error: %d", error)); DBUG_PRINT("info", ("error: %d", error));
if (error) if (error)
...@@ -4061,7 +4090,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) ...@@ -4061,7 +4090,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
here. here.
*/ */
if (thd->lex->is_stmt_unsafe() || if (thd->lex->is_stmt_unsafe() ||
(binlog_flags & HA_BINLOG_STMT_CAPABLE) == 0) (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
{ {
thd->set_current_stmt_binlog_row_based_if_mixed(); thd->set_current_stmt_binlog_row_based_if_mixed();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment