[MDEV-19986] MyRocks: Range Locking: SeekForUpdate support Created: 2019-07-08  Updated: 2023-04-16

Status: Open
Project: MariaDB Server
Component/s: Storage Engine - RocksDB
Fix Version/s: N/A

Type: Task Priority: Major
Reporter: Sergei Petrunia Assignee: Sergei Petrunia
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
PartOf
is part of MDEV-15603 Gap Lock support in MyRocks Stalled
Relates
relates to MDEV-11481 MariaRocks port: rocksdb.select_for_u... Open
relates to MDEV-13115 Implement SELECT [FOR UPDATE|LOCK IN ... Closed
relates to MDEV-25338 add SKIP LOCKED to UPDATE syntax Open

 Description   

This is to support "Seek For Update" functionality in Range Locking feature for RocksDB.

Initial input

SeekForUpdate(prefix_X) -> should try to lock range from prefix_X to X
 
Prototype with
  Seek(prefix_X) -> X; 
  TryRangeLock(prefix_X, X);
  Update snapshot (by destroying/recreating iterator?)
  Z = Seek(X) (optimizations, only look through memtable);
  if (Z > Y)
    return SeekForUpdate(X);
  else
    return Z;

The code

MyRocks part: https://github.com/spetrunia/mysql-5.6/tree/range-locking-fb-mysql-5.6.35-seekforupdate
RocksDB part: https://github.com/spetrunia/rocksdb/tree/spetrunia-rocksdb-range-locking-seekforupdate

Questions

  • criteria when to use SeekForUpdate
  • do we need to support shared locks in the first milestone? (TODO: check they will "happen to work"?)


 Comments   
Comment by Sergei Petrunia [ 2019-07-08 ]

The API

Class Transaction has a new member function w/o implementation

class Transaction {
  ...
  virtual Iterator *GetLockingIterator() {return nullptr; }

PessimisticTransaction implements it :

class PessimisticTransaction {
  ...
  Iterator* GetLockingIterator() override;

GetLockingIterator returns an object that will implement all iterator methods (not all methods are implemented yet):

//
// LockingIterator is an iterator that locks the rows before returning, as well
// as the gaps between the returned rows.
//
//  Example:
//    lock_iter= trx->GetLockingIterator();
//    lock_iter->Seek('abc');
//    lock_iter->Valid()==true && lock_iter->key() == 'bcd';
//
//   After the above, the returned record 'bcd' is locked by transaction trx.
//   Also, the range between ['abc'..'bcd'] is guaranteed to have no records
//   and be locked by trx.
//
//    lock_iter->Next();
//    lock_iter->Valid()==true && lock_iter->key() == 'efg'
//
//   Now, the range ['bcd'.. 'efg'] (bounds incluive) is also locked, and the
//   only records in it are 'bcd' and 'efg'.
//
class LockingIterator : public Iterator {
...
};

Comment by Sergei Petrunia [ 2019-07-08 ]

When to use SeekForUpdate

At the moment, MyRocks will use SeekForUpdate when the scanned range has no other bound.

Example 1: this uses range access:

select * from t1 where pk >=700 limit 10 for update;

Example 2: this uses index access:

select * from t1 order by pk limit 10 for update;

(Forward scans pass a basic test. Backward scans should be doable but I didn't have time to implement them, yet)

TODO: is this a suitable criterion?

Generated at Thu Feb 08 08:55:52 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.