[Commits] eb6f779accc: Range Locking: Shared locks continued

Sergei Petrunia psergey at askmonty.org
Mon May 13 18:29:39 EEST 2019


revision-id: eb6f779acccf4e0f86de98eb894155fa28616cc9 (fb-prod201801-234-geb6f779accc)
parent(s): d099340b9105d4fd5397c5a8548218372f963083
author: Sergei Petrunia
committer: Sergei Petrunia
timestamp: 2019-05-13 18:29:39 +0300
message:

Range Locking: Shared locks continued

- More test coverage
- ha_rocksdb::set_range_lock should set a range lock for LOCK IN SHARE MODE
-  But the Range API only allows to get a write range lock

---
 .../rocksdb/r/range_locking_shared_locks.result    | 79 +++++++++++++++++++++-
 .../rocksdb/t/range_locking_shared_locks.test      | 75 +++++++++++++++++++-
 storage/rocksdb/ha_rocksdb.cc                      |  3 +-
 3 files changed, 149 insertions(+), 8 deletions(-)

diff --git a/mysql-test/suite/rocksdb/r/range_locking_shared_locks.result b/mysql-test/suite/rocksdb/r/range_locking_shared_locks.result
index 33c7b421f9b..014b107aea5 100644
--- a/mysql-test/suite/rocksdb/r/range_locking_shared_locks.result
+++ b/mysql-test/suite/rocksdb/r/range_locking_shared_locks.result
@@ -1,9 +1,13 @@
+select @@rocksdb_use_range_locking;
+@@rocksdb_use_range_locking
+1
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
 create table t1 (
 pk int primary key,
 a int
 ) engine=rocksdb;
-insert into t1 values
-(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+insert into t1 select a,a from t0;
 # A basic test for shared locks
 begin;
 select * from t1 where pk=3 for update;
@@ -51,5 +55,74 @@ $cf_id	$TRX1_ID	0000${indexnr}80000003	X
 $cf_id	$TRX1_ID	0000${indexnr}80000005	X
 connection default;
 rollback;
-disconnect con1;
+#
+# Test if a read lock inhibits write locks
+#
+begin;
+select * from t1 where pk=2 lock in share mode;
+pk	a
+2	2
+select * from t1 where pk=8 for update;
+pk	a
+8	8
+connection con1;
+begin;
+select * from t1 where pk=2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on index: test.t1.PRIMARY
+select * from t1 where pk between 0 and 4 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on index: test.t1.PRIMARY
+delete from t1 where pk=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on index: test.t1.PRIMARY
+# Get a shared lock
+select * from t1 where pk=2 lock in share mode;
+pk	a
+2	2
+# But this should still prevent us from acquiring a write lock on that value: 
+select * from t1 where pk=2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on index: test.t1.PRIMARY
+rollback;
+connection default;
+rollback;
 drop table t1;
+create table t1 (
+pk int not null primary key,
+a int not null,
+key(a)
+) engine=rocksdb;
+insert into t1
+select
+A.a+10*B.a+100*C.a+1000*D.a, A.a+10*B.a+100*C.a+1000*D.a
+from
+t0 A, t0 B, t0 C, t0 D;
+set global rocksdb_force_flush_memtable_now=1;
+connection con1;
+begin;
+select * from t1 where pk=900 for update;
+pk	a
+900	900
+connection default;
+begin;
+explain
+select * from t1 where a between 2 and 5 lock in share mode;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	a	a	4	NULL	#	Using where; Using index
+select * from t1 where a between 2 and 5 lock in share mode;
+pk	a
+2	2
+3	3
+4	4
+5	5
+# TODO: the following prints an X lock on the range, because GetRangeLock API
+#       currently only supports write locks:
+# select * from information_schema.rocksdb_locks; # With replacements by select_from_rocksdb_locks.inc
+COLUMN_FAMILY_ID	TRANSACTION_ID	KEY	mode
+$cf_id	$TRX1_ID	0000${indexnr}80000002	S
+$cf_id	$TRX1_ID	0000${indexnr}80000003	S
+$cf_id	$TRX1_ID	0000${indexnr}80000004	S
+$cf_id	$TRX1_ID	0000${indexnr}80000005	S
+$cf_id	$TRX1_ID	0000${indexnr}80000006	S
+$cf_id	$TRX1_ID	000000010780000002 - 010000010780000005	X
+$cf_id	$TRX2_ID	0000${indexnr}80000384	X
+rollback;
+disconnect con1;
+drop table t0,t1;
diff --git a/mysql-test/suite/rocksdb/t/range_locking_shared_locks.test b/mysql-test/suite/rocksdb/t/range_locking_shared_locks.test
index 372ced5bfac..52118aa343f 100644
--- a/mysql-test/suite/rocksdb/t/range_locking_shared_locks.test
+++ b/mysql-test/suite/rocksdb/t/range_locking_shared_locks.test
@@ -5,14 +5,18 @@
 --source suite/rocksdb/include/have_range_locking.inc
 --enable_connect_log
 
+select @@rocksdb_use_range_locking;
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
 create table t1 (
   pk int primary key,
   a int
 ) engine=rocksdb;
 
 
-insert into t1 values
-(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+insert into t1 select a,a from t0;
 
 --echo # A basic test for shared locks
 
@@ -48,7 +52,72 @@ select * from t1 where pk=5 for update;
 connection default;
 rollback;
 
-disconnect con1;
+--echo #
+--echo # Test if a read lock inhibits write locks
+--echo #
+
+begin;
+select * from t1 where pk=2 lock in share mode;
+select * from t1 where pk=8 for update;
+
+connection con1;
+begin;
+
+--error ER_LOCK_WAIT_TIMEOUT
+select * from t1 where pk=2 for update;
+
+--error ER_LOCK_WAIT_TIMEOUT
+select * from t1 where pk between 0 and 4 for update;
+
+--error ER_LOCK_WAIT_TIMEOUT
+delete from t1 where pk=2;
+
+--echo # Get a shared lock
+select * from t1 where pk=2 lock in share mode;
+
+--echo # But this should still prevent us from acquiring a write lock on that value: 
+--error ER_LOCK_WAIT_TIMEOUT
+select * from t1 where pk=2 for update;
+
+rollback;
+connection default;
+rollback;
 
 drop table t1;
+create table t1 (
+  pk int not null primary key,
+  a int not null,
+  key(a)
+) engine=rocksdb;
+
+insert into t1
+select
+  A.a+10*B.a+100*C.a+1000*D.a, A.a+10*B.a+100*C.a+1000*D.a
+from
+  t0 A, t0 B, t0 C, t0 D;
+set global rocksdb_force_flush_memtable_now=1;
+
+connection con1;
+begin;
+select * from t1 where pk=900 for update;
+let $TRX2_ID=`select transaction_id from information_schema.rocksdb_trx where thread_id=connection_id()`;
+
+connection default;
+begin;
+--replace_column 9 #
+explain
+select * from t1 where a between 2 and 5 lock in share mode;
+select * from t1 where a between 2 and 5 lock in share mode;
+let $TRX1_ID=`select transaction_id from information_schema.rocksdb_trx where thread_id=connection_id()`;
+
+--echo # TODO: the following prints an X lock on the range, because GetRangeLock API
+--echo #       currently only supports write locks:
+
+--source suite/rocksdb/include/select_from_rocksdb_locks.inc
+
+rollback;
+
+disconnect con1;
+
+drop table t0,t1;
 
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index 9342ca84b04..af6bc90ede7 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -8168,8 +8168,7 @@ int ha_rocksdb::set_range_lock(Rdb_transaction *tx,
   bool start_has_inf_suffix = false, end_has_inf_suffix = false;
   rocksdb::Slice slice(slice_arg);
 
-
-  if (m_lock_rows != RDB_LOCK_WRITE || !rocksdb_use_range_locking) {
+  if (m_lock_rows == RDB_LOCK_NONE || !rocksdb_use_range_locking) {
     return 0;
   }
 


More information about the commits mailing list