summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@sun.com>2010-03-31 14:30:24 +0100
committerAlfranio Correia <alfranio.correia@sun.com>2010-03-31 14:30:24 +0100
commit4d71a007bacc473924e537ac1e49e58cf1ed6b14 (patch)
tree76af6a16f7a21178e722d6b90b26529ef26255b4 /sql/sql_class.cc
parent1ddd2ac2db1290f88840c8c5e6bfdb2359539d3f (diff)
parent7827688f231be69a86a317e110fd1b3ba559af43 (diff)
downloadmariadb-git-4d71a007bacc473924e537ac1e49e58cf1ed6b14.tar.gz
auto-merge mysql-trunk-bugfixing (local) --> mysql-trunk-bugfixing
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc98
1 files changed, 65 insertions, 33 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 4b21bc283e2..ffceb2eabce 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3589,13 +3589,33 @@ int THD::decide_logging_format(TABLE_LIST *tables)
capabilities, and one with the intersection of all the engine
capabilities.
*/
+ handler::Table_flags flags_write_some_set= 0;
handler::Table_flags flags_some_set= 0;
- handler::Table_flags flags_all_set=
+ handler::Table_flags flags_write_all_set=
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE;
- my_bool multi_engine= FALSE;
- my_bool mixed_engine= FALSE;
- my_bool all_trans_engines= TRUE;
+ /*
+ If different types of engines are about to be updated.
+ For example: Innodb and Falcon; Innodb and MyIsam.
+ */
+ my_bool multi_write_engine= FALSE;
+ /*
+ If different types of engines are about to be accessed
+ and any of them is about to be updated. For example:
+ Innodb and Falcon; Innodb and MyIsam.
+ */
+ my_bool multi_access_engine= FALSE;
+ /*
+ If non-transactional and transactional engines are about
+ to be accessed and any of them is about to be updated.
+ For example: Innodb and MyIsam.
+ */
+ my_bool trans_non_trans_access_engines= FALSE;
+ /*
+ If all engines that are about to be updated are
+ transactional.
+ */
+ my_bool all_trans_write_engines= TRUE;
TABLE* prev_write_table= NULL;
TABLE* prev_access_table= NULL;
@@ -3621,32 +3641,50 @@ int THD::decide_logging_format(TABLE_LIST *tables)
continue;
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE);
+ handler::Table_flags const flags= table->table->file->ha_table_flags();
+ DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx",
+ table->table_name, flags));
if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
{
- handler::Table_flags const flags= table->table->file->ha_table_flags();
- DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx",
- table->table_name, flags));
if (prev_write_table && prev_write_table->file->ht !=
table->table->file->ht)
- multi_engine= TRUE;
- all_trans_engines= all_trans_engines &&
- table->table->file->has_transactions();
+ multi_write_engine= TRUE;
+ all_trans_write_engines= all_trans_write_engines &&
+ table->table->file->has_transactions();
prev_write_table= table->table;
- flags_all_set &= flags;
- flags_some_set |= flags;
+ flags_write_all_set &= flags;
+ flags_write_some_set |= flags;
}
+ flags_some_set |= flags;
if (prev_access_table && prev_access_table->file->ht != table->table->file->ht)
- mixed_engine= mixed_engine || (prev_access_table->file->has_transactions() !=
- table->table->file->has_transactions());
+ {
+ multi_access_engine= TRUE;
+ trans_non_trans_access_engines= trans_non_trans_access_engines ||
+ (prev_access_table->file->has_transactions() !=
+ table->table->file->has_transactions());
+ }
prev_access_table= table->table;
}
+ DBUG_PRINT("info", ("flags_write_all_set: 0x%llx", flags_write_all_set));
+ DBUG_PRINT("info", ("flags_write_some_set: 0x%llx", flags_write_some_set));
+ DBUG_PRINT("info", ("flags_some_set: 0x%llx", flags_some_set));
+ DBUG_PRINT("info", ("multi_write_engine: %d", multi_write_engine));
+ DBUG_PRINT("info", ("multi_access_engine: %d", multi_access_engine));
+ DBUG_PRINT("info", ("trans_non_trans_access_engines: %d",
+ trans_non_trans_access_engines));
+
+ int error= 0;
+ int unsafe_flags;
+
/*
Set the statement as unsafe if:
. it is a mixed statement, i.e. access transactional and non-transactional
- tables, and updates at least one;
- or
+ tables, and update any of them;
+
+ or:
+
. an early statement updated a transactional table;
. and, the current statement updates a non-transactional table.
@@ -3710,32 +3748,26 @@ int THD::decide_logging_format(TABLE_LIST *tables)
isolation level but if we have pure repeatable read or serializable the
lock history on the slave will be different from the master.
*/
- if (mixed_engine ||
- (trans_has_updated_trans_table(this) && !all_trans_engines))
+ if (!trans_non_trans_access_engines)
+ lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_MIXED_STATEMENT);
+ else if (trans_has_updated_trans_table(this) && !all_trans_write_engines)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_NONTRANS_AFTER_TRANS);
- DBUG_PRINT("info", ("flags_all_set: 0x%llx", flags_all_set));
- DBUG_PRINT("info", ("flags_some_set: 0x%llx", flags_some_set));
- DBUG_PRINT("info", ("multi_engine: %d", multi_engine));
-
- int error= 0;
- int unsafe_flags;
-
/*
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))
- {
+ if (multi_write_engine &&
+ (flags_write_some_set & HA_HAS_OWN_BINLOGGING))
my_error((error= ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE),
MYF(0));
- }
+ else if (multi_access_engine && flags_some_set & HA_HAS_OWN_BINLOGGING)
+ lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE);
/* both statement-only and row-only engines involved */
- if ((flags_all_set & (HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE)) == 0)
+ if ((flags_write_all_set & (HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE)) == 0)
{
/*
1. Error: Binary logging impossible since both row-incapable
@@ -3744,7 +3776,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
my_error((error= ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE), MYF(0));
}
/* statement-only engines involved */
- else if ((flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
+ else if ((flags_write_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
{
if (lex->is_stmt_row_injection())
{
@@ -3792,7 +3824,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
*/
my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_MODE), MYF(0));
}
- else if ((flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
+ else if ((flags_write_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
{
/*
5. Error: Cannot modify table that uses a storage engine
@@ -3820,7 +3852,7 @@ int THD::decide_logging_format(TABLE_LIST *tables)
else
{
if (lex->is_stmt_unsafe() || lex->is_stmt_row_injection()
- || (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
+ || (flags_write_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
{
/* log in row format! */
set_current_stmt_binlog_format_row_if_mixed();