BUG#49019 Mixing self-logging eng. and regular eng. does not switch to row in mixed
mode Post-push fix after backporting the patch to 5.1-bugteam: 1 - changed the name of some variables to be equivalent to pe. 2 - fixed that patch to mark a statement as unsafe when both a self-logging eng. and regular eng. are accessed and one of them is updated.
This commit is contained in:
parent
cf7bac11ec
commit
3404d83083
@ -5154,63 +5154,75 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
|
|||||||
set with all the capabilities bits set and one with no
|
set with all the capabilities bits set and one with no
|
||||||
capabilities bits set.
|
capabilities bits set.
|
||||||
*/
|
*/
|
||||||
handler::Table_flags flags_some_set= 0;
|
handler::Table_flags flags_write_some_set= 0;
|
||||||
handler::Table_flags flags_all_set=
|
handler::Table_flags flags_access_some_set= 0;
|
||||||
|
handler::Table_flags flags_write_all_set=
|
||||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE;
|
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE;
|
||||||
|
|
||||||
my_bool multi_engine= FALSE;
|
/*
|
||||||
void* prev_ht= NULL;
|
If different types of engines are about to be updated.
|
||||||
|
For example: Innodb and Falcon; Innodb and MyIsam.
|
||||||
|
*/
|
||||||
|
my_bool multi_write_engine= FALSE;
|
||||||
|
void* prev_write_ht= NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
void* prev_access_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())
|
if (table->placeholder())
|
||||||
continue;
|
continue;
|
||||||
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
|
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
|
||||||
thd->lex->set_stmt_unsafe();
|
thd->lex->set_stmt_unsafe();
|
||||||
|
ulonglong const flags= table->table->file->ha_table_flags();
|
||||||
if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
|
if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||||
{
|
{
|
||||||
ulonglong const 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)));
|
||||||
if (prev_ht && prev_ht != table->table->file->ht)
|
if (prev_write_ht && prev_write_ht != table->table->file->ht)
|
||||||
multi_engine= TRUE;
|
multi_write_engine= TRUE;
|
||||||
prev_ht= table->table->file->ht;
|
prev_write_ht= table->table->file->ht;
|
||||||
flags_all_set &= flags;
|
flags_write_all_set &= flags;
|
||||||
flags_some_set |= flags;
|
flags_write_some_set |= flags;
|
||||||
}
|
}
|
||||||
|
if (prev_access_ht && prev_access_ht != table->table->file->ht)
|
||||||
|
multi_access_engine= TRUE;
|
||||||
|
prev_access_ht= table->table->file->ht;
|
||||||
|
flags_access_some_set |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_PRINT("info", ("flags_all_set: %s%s",
|
DBUG_PRINT("info", ("flags_write_all_set: %s%s",
|
||||||
FLAGSTR(flags_all_set, HA_BINLOG_STMT_CAPABLE),
|
FLAGSTR(flags_write_all_set, HA_BINLOG_STMT_CAPABLE),
|
||||||
FLAGSTR(flags_all_set, HA_BINLOG_ROW_CAPABLE)));
|
FLAGSTR(flags_write_all_set, HA_BINLOG_ROW_CAPABLE)));
|
||||||
DBUG_PRINT("info", ("flags_some_set: %s%s",
|
DBUG_PRINT("info", ("flags_write_some_set: %s%s",
|
||||||
FLAGSTR(flags_some_set, HA_BINLOG_STMT_CAPABLE),
|
FLAGSTR(flags_write_some_set, HA_BINLOG_STMT_CAPABLE),
|
||||||
FLAGSTR(flags_some_set, HA_BINLOG_ROW_CAPABLE)));
|
FLAGSTR(flags_write_some_set, HA_BINLOG_ROW_CAPABLE)));
|
||||||
|
DBUG_PRINT("info", ("flags_access_some_set: %s%s",
|
||||||
|
FLAGSTR(flags_access_some_set, HA_BINLOG_STMT_CAPABLE),
|
||||||
|
FLAGSTR(flags_access_some_set, HA_BINLOG_ROW_CAPABLE)));
|
||||||
|
DBUG_PRINT("info", ("multi_write_engine: %s",
|
||||||
|
multi_write_engine ? "TRUE" : "FALSE"));
|
||||||
|
DBUG_PRINT("info", ("multi_access_engine: %s",
|
||||||
|
multi_access_engine ? "TRUE" : "FALSE"));
|
||||||
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"));
|
|
||||||
/*
|
|
||||||
Reading from a self-logging engine and updating another engine
|
|
||||||
generates changes that are written to the binary log in the
|
|
||||||
statement format and may make slaves to diverge. In the mixed
|
|
||||||
mode, such changes should be written to the binary log in the
|
|
||||||
row format.
|
|
||||||
*/
|
|
||||||
if (multi_engine &&
|
|
||||||
(flags_some_set & HA_HAS_OWN_BINLOGGING))
|
|
||||||
thd->lex->set_stmt_unsafe();
|
|
||||||
|
|
||||||
int error= 0;
|
int error= 0;
|
||||||
if (flags_all_set == 0)
|
if (flags_write_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 &&
|
||||||
(flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
|
(flags_write_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,"
|
||||||
@ -5218,7 +5230,7 @@ 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()) &&
|
||||||
(flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
|
(flags_write_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,"
|
||||||
@ -5231,8 +5243,8 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
|
|||||||
statement cannot be logged atomically, so we generate an error
|
statement cannot be logged atomically, so we generate an error
|
||||||
rather than allowing the binlog to become corrupt.
|
rather than allowing the binlog to become corrupt.
|
||||||
*/
|
*/
|
||||||
if (multi_engine &&
|
if (multi_write_engine &&
|
||||||
(flags_some_set & HA_HAS_OWN_BINLOGGING))
|
(flags_write_some_set & HA_HAS_OWN_BINLOGGING))
|
||||||
{
|
{
|
||||||
error= ER_BINLOG_LOGGING_IMPOSSIBLE;
|
error= ER_BINLOG_LOGGING_IMPOSSIBLE;
|
||||||
my_error(error, MYF(0),
|
my_error(error, MYF(0),
|
||||||
@ -5240,6 +5252,16 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
|
|||||||
" than one engine involved and at least one engine"
|
" than one engine involved and at least one engine"
|
||||||
" is self-logging");
|
" is self-logging");
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Reading from a self-logging engine and updating another engine
|
||||||
|
generates changes that are written to the binary log in the
|
||||||
|
statement format and may make slaves to diverge. In the mixed
|
||||||
|
mode, such changes should be written to the binary log in the
|
||||||
|
row format.
|
||||||
|
*/
|
||||||
|
else if (multi_access_engine &&
|
||||||
|
(flags_access_some_set & HA_HAS_OWN_BINLOGGING))
|
||||||
|
thd->lex->set_stmt_unsafe();
|
||||||
|
|
||||||
DBUG_PRINT("info", ("error: %d", error));
|
DBUG_PRINT("info", ("error: %d", error));
|
||||||
|
|
||||||
@ -5259,7 +5281,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
|
|||||||
here.
|
here.
|
||||||
*/
|
*/
|
||||||
if (thd->lex->is_stmt_unsafe() ||
|
if (thd->lex->is_stmt_unsafe() ||
|
||||||
(flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
|
(flags_write_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();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user