-
Notifications
You must be signed in to change notification settings - Fork 6.2k
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
Conversation
There was a problem hiding this 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.
There was a problem hiding this 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.
There was a problem hiding this 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.
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
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). 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: Solution2: Assume that the lock manager can somehow call
to get the Comparator. I'm not sure if/how to do that safely though ( Should this issue be addressed as part of this patch? |
PessimisticTransactionDB::GetLockStatusData() { | ||
return lock_mgr_.GetLockStatusData(); | ||
LockManager::PointLockStatus PessimisticTransactionDB::GetLockStatusData() { | ||
return lock_manager_->GetPointLockStatus(); |
There was a problem hiding this comment.
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?)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Solution1 looks good to me, I'll do it in this PR. |
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
2 similar comments
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
@spetrunia PTAL |
@Cheng-Chang looks good to me now. |
There was a problem hiding this 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.
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
There was a problem hiding this 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.
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
There was a problem hiding this 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.
this information is exposed through LockManager interface
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
There was a problem hiding this 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); |
There was a problem hiding this comment.
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 settingstart == end
- There could be a
PointAndRangeLockManager
composed of aPointLockManager
and aRangeLockManager
that delegates/coordinates locking requests.
Is the plan one of these, or something else?
There was a problem hiding this comment.
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
.
@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. |
There was a problem hiding this 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.
@cheng-chang has updated the pull request. You must reimport the pull request before landing. |
There was a problem hiding this 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.
@Cheng-Chang merged this pull request in 0ea7db7. |
There was a problem hiding this 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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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.
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
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 aLockManager
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