BUG#23051 (READ COMMITTED breaks mixed and statement-based replication):

Moving error generating code from table_flags() to external_lock().
parent 43d419e9
......@@ -396,7 +396,9 @@ enum ha_base_keytype {
#define HA_ERR_AUTOINC_READ_FAILED 166 /* Failed to get next autoinc value */
#define HA_ERR_AUTOINC_ERANGE 167 /* Failed to set row autoinc value */
#define HA_ERR_GENERIC 168 /* Generic error */
#define HA_ERR_LAST 168 /*Copy last error nr.*/
#define HA_ERR_LOGGING_IMPOSSIBLE 169 /* It is not possible to log this
statement */
#define HA_ERR_LAST 169 /*Copy last error nr.*/
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
......
......@@ -2276,35 +2276,11 @@ Get the table flags to use for the statement. */
handler::Table_flags
ha_innobase::table_flags() const
{
THD *const thd= current_thd;
/* We are using thd->variables.tx_isolation here instead of
trx->isolation_level since store_lock() has not been called
yet.
The trx->isolation_level is set inside store_lock() (which
is called from mysql_lock_tables()) until after this
function has been called (which is called in lock_tables()
before that function calls mysql_lock_tables()). */
ulong const tx_isolation= thd_tx_isolation(thd);
/* Need to use tx_isolation here since table flags is (also)
called before prebuilt is inited. */
ulong const tx_isolation = thd_tx_isolation(current_thd);
if (tx_isolation <= ISO_READ_COMMITTED)
{
ulong const binlog_format= thd->variables.binlog_format;
/* Statement based binlogging does not work in these
isolation levels since the necessary locks cannot
be taken */
if (binlog_format == BINLOG_FORMAT_STMT)
{
char buf[256];
my_snprintf(buf, sizeof(buf),
"Transaction level '%s' in InnoDB is"
" not safe for binlog mode '%s'",
tx_isolation_names[tx_isolation],
binlog_format_names[binlog_format]);
my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf);
}
return int_table_flags;
}
return int_table_flags | HA_BINLOG_STMT_CAPABLE;
}
......@@ -6284,6 +6260,30 @@ ha_innobase::external_lock(
update_thd(thd);
/* Statement based binlogging does not work in isolation level
READ UNCOMMITTED and READ COMMITTED since the necessary
locks cannot be taken. In this case, we print an
informative error message and return with an error. */
if (lock_type == F_WRLCK)
{
ulong const binlog_format= thd->variables.binlog_format;
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
binlog_format == BINLOG_FORMAT_STMT)
{
char buf[256];
bool const read_uncommitted =
trx->isolation_level == TRX_ISO_READ_UNCOMMITTED;
my_snprintf(buf, sizeof(buf),
"Transaction level 'READ %sCOMMITTED' in"
" InnoDB is not safe for binlog mode '%s'",
read_uncommitted ? "UN" : "",
binlog_format_names[binlog_format]);
my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf);
return HA_ERR_LOGGING_IMPOSSIBLE;
}
}
trx = prebuilt->trx;
prebuilt->sql_stat_start = TRUE;
......
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