Skip to content
Permalink
Browse files

MDEV-17045: MyRocks tables cannot be updated when binlog_format=MIXED.

  • Loading branch information...
spetrunia committed Jun 15, 2019
1 parent 2b0eb35 commit 93c84cc8f24d80a74919d1609d73cb97502fd885
@@ -11025,6 +11025,41 @@ void ha_rocksdb::read_thd_vars(THD *const thd) {
m_checksums_pct = THDVAR(thd, checksums_pct);
}

ulonglong ha_rocksdb::table_flags() const
{
DBUG_ENTER_FUNC();

/*
HA_BINLOG_STMT_CAPABLE
Upstream: MyRocks advertises itself as it supports SBR, but has additional
checks in ha_rocksdb::external_lock()/ start_stmt() which will return an
error if one tries to run the statement.
Exceptions: @@rocksdb_unsafe_for_binlog or we are an SQL slave thread.
MariaDB: Inform the upper layer we don't support SBR, so it switches to RBR
if possible. The exceptions are the same as with the upstream.
HA_REC_NOT_IN_SEQ
If we don't set it, filesort crashes, because it assumes rowids are
1..8 byte numbers
HA_PRIMARY_KEY_IN_READ_INDEX
This flag is always set, even for tables that:
- have no PK
- have some (or all) of PK that can't be decoded from the secondary
index.
*/
THD *thd= ha_thd();
DBUG_RETURN(HA_BINLOG_ROW_CAPABLE |
((thd && (THDVAR(thd, unsafe_for_binlog) ||thd->rgi_slave))?
HA_BINLOG_STMT_CAPABLE : 0) |
HA_REC_NOT_IN_SEQ | HA_CAN_INDEX_BLOBS |
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_NULL_IN_KEY |
HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX);
}



/**
@return
@@ -11037,6 +11072,9 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
DBUG_ASSERT(thd != nullptr);

int res = HA_EXIT_SUCCESS;
#if 0
// MariaDB uses a different way to implement this, see ha_rocksdb::table_flags

int binlog_format = my_core::thd_binlog_format(thd);
bool unsafe_for_binlog = THDVAR(ha_thd(), unsafe_for_binlog);

@@ -11065,6 +11103,7 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
my_error(ER_REQUIRE_ROW_BINLOG_FORMAT, MYF(0));
DBUG_RETURN(HA_ERR_UNSUPPORTED);
}
#endif

if (lock_type == F_UNLCK) {
Rdb_transaction *const tx = get_tx_from_thd(thd);
@@ -11167,20 +11206,6 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
int ha_rocksdb::start_stmt(THD *const thd, thr_lock_type lock_type) {
DBUG_ENTER_FUNC();

/*
MariaDB: the following is a copy of the check in ha_rocksdb::external_lock:
*/
int binlog_format = my_core::thd_binlog_format(thd);
bool unsafe_for_binlog = THDVAR(ha_thd(), unsafe_for_binlog);
if (lock_type >= TL_WRITE_ALLOW_WRITE &&
!thd->rgi_slave && !unsafe_for_binlog &&
binlog_format != BINLOG_FORMAT_ROW &&
binlog_format != BINLOG_FORMAT_UNSPEC &&
my_core::thd_binlog_filter_ok(thd)) {
my_error(ER_REQUIRE_ROW_BINLOG_FORMAT, MYF(0));
DBUG_RETURN(HA_ERR_UNSUPPORTED);
}

DBUG_ASSERT(thd != nullptr);

Rdb_transaction *const tx = get_or_create_tx(thd);
@@ -863,31 +863,7 @@ class ha_rocksdb : public my_core::handler {
This is a list of flags that indicate what functionality the storage engine
implements. The current table flags are documented in handler.h
*/
ulonglong table_flags() const override {
DBUG_ENTER_FUNC();

/*
HA_BINLOG_STMT_CAPABLE
We are saying that this engine is just statement capable to have
an engine that can only handle statement-based logging. This is
used in testing.
HA_REC_NOT_IN_SEQ
If we don't set it, filesort crashes, because it assumes rowids are
1..8 byte numbers
HA_PRIMARY_KEY_IN_READ_INDEX
This flag is always set, even for tables that:
- have no PK
- have some (or all) of PK that can't be decoded from the secondary
index.
*/
DBUG_RETURN(HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
HA_REC_NOT_IN_SEQ | HA_CAN_INDEX_BLOBS |
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_NULL_IN_KEY |
HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX);
}

ulonglong table_flags() const override ;
private:
bool init_with_fields(); /* no 'override' in MariaDB */
public:
@@ -18,7 +18,16 @@ set @tmp_bf= @@binlog_format;
set binlog_format='STATEMENT';
lock tables t1 write;
insert into t1 values(1);
ERROR HY000: Can't execute updates on master with binlog_format != ROW.
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.
unlock tables;
set @@binlog_format=@tmp_bf;
drop table t1;
#
# MDEV-17045: MyRocks tables cannot be updated when binlog_format=MIXED.
#
set @tmp_bf= @@binlog_format;
set binlog_format='MIXED';
create table t1 (pk int primary key) engine=rocksdb;
insert into t1 values (1);
drop table t1;
set @@binlog_format=@tmp_bf;
@@ -8,7 +8,7 @@ select @@binlog_format;
STATEMENT
create table t1 (pk int primary key) engine=rocksdb;
insert into t1 values (1),(2),(3);
ERROR HY000: Can't execute updates on master with binlog_format != ROW.
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.
set session rocksdb_unsafe_for_binlog=on;
insert into t1 values (1),(2),(3);
select * from t1;
@@ -19,7 +19,7 @@ pk
delete from t1;
set session rocksdb_unsafe_for_binlog=off;
insert into t1 values (1),(2),(3);
ERROR HY000: Can't execute updates on master with binlog_format != ROW.
ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.
set binlog_format=row;
insert into t1 values (1),(2),(3);
include/sync_slave_sql_with_master.inc
@@ -21,10 +21,20 @@ unlock tables;
set @tmp_bf= @@binlog_format;
set binlog_format='STATEMENT';
lock tables t1 write;
--error ER_REQUIRE_ROW_BINLOG_FORMAT
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
insert into t1 values(1);
unlock tables;
set @@binlog_format=@tmp_bf;

drop table t1;

--echo #
--echo # MDEV-17045: MyRocks tables cannot be updated when binlog_format=MIXED.
--echo #
set @tmp_bf= @@binlog_format;
set binlog_format='MIXED';
create table t1 (pk int primary key) engine=rocksdb;
insert into t1 values (1);
drop table t1;
set @@binlog_format=@tmp_bf;

@@ -12,7 +12,7 @@ connection master;

select @@binlog_format;
create table t1 (pk int primary key) engine=rocksdb;
--error ER_REQUIRE_ROW_BINLOG_FORMAT
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
insert into t1 values (1),(2),(3);

set session rocksdb_unsafe_for_binlog=on;
@@ -21,7 +21,7 @@ select * from t1;
delete from t1;
set session rocksdb_unsafe_for_binlog=off;

--error ER_REQUIRE_ROW_BINLOG_FORMAT
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
insert into t1 values (1),(2),(3);

set binlog_format=row;

0 comments on commit 93c84cc

Please sign in to comment.
You can’t perform that action at this time.