summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <mats@kindahl-laptop.dnsalias.net>2007-06-21 13:52:56 +0200
committerunknown <mats@kindahl-laptop.dnsalias.net>2007-06-21 13:52:56 +0200
commit10b10375db4da4f342c1737109749a12b32eb167 (patch)
tree0d74b4486ad13112900dd3bdb8fcfbb12a2a8c38
parentc2112f5fd0f8c4ea8102002726d12c6d5c5e48c3 (diff)
parentd2d630c2ee4cfb7bd72531882f31386167f5f857 (diff)
downloadmariadb-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.result17
-rw-r--r--mysql-test/t/binlog_multi_engine.test10
-rw-r--r--sql/sql_base.cc57
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();
}