diff options
author | unknown <mats@kindahl-laptop.dnsalias.net> | 2007-06-21 13:52:56 +0200 |
---|---|---|
committer | unknown <mats@kindahl-laptop.dnsalias.net> | 2007-06-21 13:52:56 +0200 |
commit | 10b10375db4da4f342c1737109749a12b32eb167 (patch) | |
tree | 0d74b4486ad13112900dd3bdb8fcfbb12a2a8c38 | |
parent | c2112f5fd0f8c4ea8102002726d12c6d5c5e48c3 (diff) | |
parent | d2d630c2ee4cfb7bd72531882f31386167f5f857 (diff) | |
download | mariadb-git-10b10375db4da4f342c1737109749a12b32eb167.tar.gz |
Merge kindahl-laptop.dnsalias.net:/home/bkroot/mysql-5.1-rpl
into kindahl-laptop.dnsalias.net:/home/bk/b28722-mysql-5.1-rpl
mysql-test/r/binlog_multi_engine.result:
Manual merge
mysql-test/t/binlog_multi_engine.test:
Manual merge
-rw-r--r-- | mysql-test/r/binlog_multi_engine.result | 17 | ||||
-rw-r--r-- | mysql-test/t/binlog_multi_engine.test | 10 | ||||
-rw-r--r-- | sql/sql_base.cc | 57 |
3 files changed, 69 insertions, 15 deletions
diff --git a/mysql-test/r/binlog_multi_engine.result b/mysql-test/r/binlog_multi_engine.result index 71b2d7b0c48..98244edca3d 100644 --- a/mysql-test/r/binlog_multi_engine.result +++ b/mysql-test/r/binlog_multi_engine.result @@ -11,6 +11,7 @@ START TRANSACTION; INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2); UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f; 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; TRUNCATE t1m; TRUNCATE t1b; @@ -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 t1n VALUES (1,1), (1,2), (2,1), (2,2); 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; -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 t1b; 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>; 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) diff --git a/mysql-test/t/binlog_multi_engine.test b/mysql-test/t/binlog_multi_engine.test index 6614b9e5d44..b8d336fa7ed 100644 --- a/mysql-test/t/binlog_multi_engine.test +++ b/mysql-test/t/binlog_multi_engine.test @@ -1,3 +1,8 @@ +# 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_ndb.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); INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2); 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 # 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; #UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f; +>>>>>>> error ER_BINLOG_LOGGING_IMPOSSIBLE; 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); error ER_BINLOG_LOGGING_IMPOSSIBLE; 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 # might cause it to be out of sync with the results from MyISAM. diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8de3beb2a24..48c876d6d89 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -28,6 +28,8 @@ #include <io.h> #endif +#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "") + /** This internal handler is used to trap internally errors that can occur when executing open table @@ -3996,36 +3998,47 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) { 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) + { if (!table->placeholder() && table->lock_type >= TL_WRITE_ALLOW_WRITE) { -#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "") -#ifndef DBUG_OFF - ulonglong flags= table->table->file->ha_table_flags(); + ulonglong const flags= table->table->file->ha_table_flags(); DBUG_PRINT("info", ("table: %s; ha_table_flags: %s%s", table->table_name, FLAGSTR(flags, HA_BINLOG_STMT_CAPABLE), FLAGSTR(flags, HA_BINLOG_ROW_CAPABLE))); -#endif - binlog_flags &= table->table->file->ha_table_flags(); + if (prev_ht && prev_ht != table->table->file->ht) + 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), - FLAGSTR(binlog_flags, HA_BINLOG_ROW_CAPABLE))); + } + + DBUG_PRINT("info", ("flags_all_set: %s%s", + 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", thd->variables.binlog_format)); + DBUG_PRINT("info", ("multi_engine: %s", + multi_engine ? "TRUE" : "FALSE")); int error= 0; - if (binlog_flags == 0) + if (flags_all_set == 0) { my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0), "Statement cannot be logged to the binary log in" " row-based nor statement-based format"); } 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), "Statement-based format required for this statement," @@ -4033,13 +4046,29 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) } else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW || 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), "Row-based format required for this statement," " 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)); if (error) @@ -4061,7 +4090,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) here. */ 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(); } |