mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
BUG#23051 (READ COMMITTED breaks mixed and statement-based replication):
Moving error generating code from table_flags() to external_lock().
This commit is contained in:
parent
43d419e9a9
commit
5491df5ae9
2 changed files with 30 additions and 28 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue