[Commits] baf5e0efc8c: DML statements that are transactions on their own should also read the committed data with range locking
revision-id: baf5e0efc8c73a043180a621df1d2a13e3a4d4e5 (fb-prod201801-200-gbaf5e0efc8c) parent(s): 77d8f9447661f6147143b21ef43a1ac0f45139b5 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2019-01-28 16:24:00 +0300 message: DML statements that are transactions on their own should also read the committed data with range locking --- mysql-test/suite/rocksdb/r/range_locking.result | 35 +++++++++++++++++++ mysql-test/suite/rocksdb/t/range_locking.test | 46 +++++++++++++++++++++++++ storage/rocksdb/ha_rocksdb.cc | 10 ++++++ 3 files changed, 91 insertions(+) diff --git a/mysql-test/suite/rocksdb/r/range_locking.result b/mysql-test/suite/rocksdb/r/range_locking.result index b0217d5269a..bba4726323e 100644 --- a/mysql-test/suite/rocksdb/r/range_locking.result +++ b/mysql-test/suite/rocksdb/r/range_locking.result @@ -301,3 +301,38 @@ commit; disconnect con1; connection default; drop table t1; +# +# Another no-snapshot-checking test, this time for single-statement +# transaction +# +create table t1 (pk int primary key, a int, name varchar(16)) engine=rocksdb; +insert into t1 values (1,1, 'row1'), (2,2,'row2'); +connect con1,localhost,root,,; +connection con1; +select get_lock('row1', 100); +get_lock('row1', 100) +1 +connection default; +# The following will read the first row (1,1,'row1'), and stop. +update t1 set a=a+100 where get_lock(name, 1000)=1; +connection con1; +update t1 set a=5 where pk=2; +select release_lock('row1'); +release_lock('row1') +1 +connection default; +# Look at the row with pk=2: +# 2, 105, row2 - means the UPDATE was reading current data (Correct) +# 2, 102, row - means the UPDATE read the snapshot (incorrect) +select * from t1; +pk a name +1 101 row1 +2 105 row2 +# Try releasing both locks (in 5.6, we will be holding only the second one) +select release_lock(name) from t1; +release_lock(name) +NULL +1 +disconnect con1; +connection default; +drop table t1; diff --git a/mysql-test/suite/rocksdb/t/range_locking.test b/mysql-test/suite/rocksdb/t/range_locking.test index e1e8ac92bdc..068bb3be4b1 100644 --- a/mysql-test/suite/rocksdb/t/range_locking.test +++ b/mysql-test/suite/rocksdb/t/range_locking.test @@ -306,3 +306,49 @@ commit; disconnect con1; connection default; drop table t1; + +--echo # +--echo # Another no-snapshot-checking test, this time for single-statement +--echo # transaction +--echo # + +create table t1 (pk int primary key, a int, name varchar(16)) engine=rocksdb; +insert into t1 values (1,1, 'row1'), (2,2,'row2'); + +connect (con1,localhost,root,,); +connection con1; +select get_lock('row1', 100); + +connection default; + +--echo # The following will read the first row (1,1,'row1'), and stop. + +send update t1 set a=a+100 where get_lock(name, 1000)=1; + +# Wait till the default connection has stopped: +connection con1; + +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = "User lock" + AND INFO = "update t1 set a=a+100 where get_lock(name, 1000)=1"; +--source include/wait_condition.inc + +# Update the second row +update t1 set a=5 where pk=2; + +select release_lock('row1'); + +connection default; +reap; + +--echo # Look at the row with pk=2: +--echo # 2, 105, row2 - means the UPDATE was reading current data (Correct) +--echo # 2, 102, row - means the UPDATE read the snapshot (incorrect) +select * from t1; + +--echo # Try releasing both locks (in 5.6, we will be holding only the second one) +select release_lock(name) from t1; + +disconnect con1; +connection default; +drop table t1; diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 8871a43c048..9f67b388e44 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -2628,6 +2628,7 @@ public: virtual bool is_tx_started() const = 0; virtual void start_tx() = 0; virtual void start_stmt(bool is_dml_statement) = 0; + virtual void start_autocommit_stmt(bool is_dml_statement){} void set_initial_savepoint() { /* @@ -3082,6 +3083,12 @@ public: acquire_snapshot(false); } + void start_autocommit_stmt(bool is_dml_statement) override { + if (rocksdb_use_range_locking && is_dml_statement) { + start_ignore_snapshot(); + } + } + /* This must be called when last statement is rolled back, but the transaction continues @@ -3696,6 +3703,7 @@ static int rocksdb_commit(handlerton *const hton, THD *const thd, - For a COMMIT statement that finishes a multi-statement transaction - For a statement that has its own transaction */ + tx->end_ignore_snapshot_if_needed(); if (tx->commit()) { DBUG_RETURN(HA_ERR_ROCKSDB_COMMIT_FAILED); } @@ -4303,6 +4311,8 @@ static inline void rocksdb_register_tx(handlerton *const hton, THD *const thd, if (my_core::thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { tx->start_stmt(is_dml_stmt); trans_register_ha(thd, TRUE, rocksdb_hton); + } else { + tx->start_autocommit_stmt(is_dml_stmt); } }
participants (1)
-
Sergei Petrunia