Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract out LockManager interface #7532

Closed
wants to merge 7 commits into from
Closed

Abstract out LockManager interface #7532

wants to merge 7 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Oct 10, 2020

In order to be able to introduce more locking protocols, we need to abstract out the locking subsystem in TransactionDB into a set of interfaces.

PR #7013 introduces interface LockTracker. This PR is a follow up to take the first step to abstract out a LockManager interface.

Further modifications to the interface may be needed when introducing the first implementation of range lock. But the idea here is to put the range lock implementation based on range tree under the utilities/transactions/lock/range/range_tree.

Test Plan:
point_lock_manager_test

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

@spetrunia
Copy link
Contributor

A question about this call:

class LockManager {
  ...
  // Enable locking for the specified column family.
  // Caller should guarantee that this column family is not already enabled.
  virtual void AddColumnFamily(ColumnFamilyId column_family_id) = 0;

Here, the LockManager is expected to initialize its data structures based on just ColumnFamilyId (not ColumnFamilyHandle).
Current PointLockManager can do this because it doesn't care about the Comparator used, it assumes the comparator is memcmp() (one can see this in class LockMapStripe: the keys are indexed with std::unordered_map<std::string, LockInfo> keys).

A Range-based Lock manager (or a more advanced Point-based lock manager) needs to "know" what Comparator is used.

I can see two solutions:
Solution1: Pass ColumnFamilyHandle* instead (this is what current Range Locking code is using)

Solution2: Assume that the lock manager can somehow call

  db_.versions_.GetColumnFamily(id)->GetComparator();

to get the Comparator. I'm not sure if/how to do that safely though (versions_ is not public, etc).

Should this issue be addressed as part of this patch?

PessimisticTransactionDB::GetLockStatusData() {
return lock_mgr_.GetLockStatusData();
LockManager::PointLockStatus PessimisticTransactionDB::GetLockStatusData() {
return lock_manager_->GetPointLockStatus();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, now LockManager got two functions, GetPointLockStatus and GetRangeLockStatus.

Should this function (PessimisticTransactionDB::GetLockStatusData) also be replaced with two functions? (And if yes, should this be done in this PR or outside of it?)

Copy link
Author

@ghost ghost Oct 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add GetRangeLockStatus to TransactionDB's interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I talked with @Cheng-Chang about this, and I think that in the future, we should always get status from the lock manager objects, and the methods on PessimisticTransactionDB will go away.

I think the below calls relating to deadlock info would be similar too.

@ghost
Copy link
Author

ghost commented Oct 12, 2020

A question about this call:

class LockManager {
  ...
  // Enable locking for the specified column family.
  // Caller should guarantee that this column family is not already enabled.
  virtual void AddColumnFamily(ColumnFamilyId column_family_id) = 0;

Here, the LockManager is expected to initialize its data structures based on just ColumnFamilyId (not ColumnFamilyHandle).
Current PointLockManager can do this because it doesn't care about the Comparator used, it assumes the comparator is memcmp() (one can see this in class LockMapStripe: the keys are indexed with std::unordered_map<std::string, LockInfo> keys).

A Range-based Lock manager (or a more advanced Point-based lock manager) needs to "know" what Comparator is used.

I can see two solutions:
Solution1: Pass ColumnFamilyHandle* instead (this is what current Range Locking code is using)

Solution2: Assume that the lock manager can somehow call

  db_.versions_.GetColumnFamily(id)->GetComparator();

to get the Comparator. I'm not sure if/how to do that safely though (versions_ is not public, etc).

Should this issue be addressed as part of this patch?

Solution1 looks good to me, I'll do it in this PR.

@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

2 similar comments
@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

@ghost
Copy link
Author

ghost commented Oct 12, 2020

@spetrunia PTAL

@spetrunia
Copy link
Contributor

@Cheng-Chang looks good to me now.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@ghost ghost requested a review from lth October 16, 2020 20:48
this information is exposed through LockManager interface
@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@ajkr ajkr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

const TransactionDBOptions& opt) {
assert(db);
// TODO: determine the lock manager implementation based on configuration.
return new PointLockManager(db, opt);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some difficulty imagining what the configuration will look like for choosing between PointLockManager vs. RangeLockManager since my understanding is transactions can have a mix of point and range ops. Some possibilities I was thinking of:

  • Since Range endpoints are inclusive, RangeLockManager could also lock point keys by setting start == end
  • There could be a PointAndRangeLockManager composed of a PointLockManager and a RangeLockManager that delegates/coordinates locking requests.

Is the plan one of these, or something else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one. When RangeLockManager is used, acquiring a point lock on $P is the same as acquiring a range lock on $P <= key <= $P.

@ghost
Copy link
Author

ghost commented Oct 19, 2020

@lth I'm going to merge the PR to unblock Sergey, feel free to leave reviews, I'll address them in a follow up PR.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@cheng-chang has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheng-Chang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@Cheng-Chang merged this pull request in 0ea7db7.

Copy link
Contributor

@lth lth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good to me too.

Regarding needing the handle for comparators for AddColumnFamily, write prepared needed to solve a similar problem, so it'd be good if the two solutions converged eventually. This is implemented in UpdateCFComparatorMap. Maybe we can add a TODO?

Endpoint start;
Endpoint end;
std::vector<TransactionID> ids;
bool exclusive;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does range locking support shared locks? Or is this here just for future extensibility?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future extensibility.

PessimisticTransactionDB::GetLockStatusData() {
return lock_mgr_.GetLockStatusData();
LockManager::PointLockStatus PessimisticTransactionDB::GetLockStatusData() {
return lock_manager_->GetPointLockStatus();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I talked with @Cheng-Chang about this, and I think that in the future, we should always get status from the lock manager objects, and the methods on PessimisticTransactionDB will go away.

I think the below calls relating to deadlock info would be similar too.

codingrhythm pushed a commit to SafetyCulture/rocksdb that referenced this pull request Mar 5, 2021
Summary:
In order to be able to introduce more locking protocols, we need to abstract out the locking subsystem in TransactionDB into a set of interfaces.

PR facebook#7013 introduces interface `LockTracker`. This PR is a follow up to take the first step to abstract out a `LockManager` interface.

Further modifications to the interface may be needed when introducing the first implementation of range lock. But the idea here is to put the range lock implementation based on range tree under the `utilities/transactions/lock/range/range_tree`.

Pull Request resolved: facebook#7532

Test Plan: point_lock_manager_test

Reviewed By: ajkr

Differential Revision: D24238731

Pulled By: cheng-chang

fbshipit-source-id: 2a9458cd8b3fb008d9529dbc4d3b28c24631f463
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants