Skip to content

Commit c00c7a8

Browse files
committed
[yugabyte#25379] docdb: Introduce per-transaction LockTracker state
Summary: The current LockTracker implementation for ObjectLockManager involves a multi-index container uniquely keyed on (versioned_txn, subtxn_id, object_id) and additionally indexed on various subsets of the unique key. This means that we have to acquire the global mutex an additional time on lock acquire/release/wait/wakeup. This diff refactors this map to instead be keyed on versioned_txn and point to a per-transaction struct (TrackedTransactionLockEntry) which contains a further subtxn_id => object_id => TrackedLockEntry mapping. This allows us to pass around this new TrackedTransactionLockEntry and avoid the need for a repeated global mutex lock for LockTracker functionality. TrackedTransactionLockEntry is currently only briefly passed around through the lock acquire path to avoid repeated global mutex locks; storing it externally to help avoid the need for the initial global mutex lock will be addressed in a later diff. This is also needed for the planned move of ObjectLockManager into shared memory, to avoid partially updated indexes in the multi-index in event of PG crashing while inserting/deleting from the container. Jira: DB-14609 Test Plan: Jenkins. Reviewers: bkolagani Reviewed By: bkolagani Subscribers: sergei, ybase Differential Revision: https://phorge.dev.yugabyte.com/D40814
1 parent 73a7f12 commit c00c7a8

File tree

5 files changed

+268
-264
lines changed

5 files changed

+268
-264
lines changed

src/yb/docdb/object_lock_data.h

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,22 @@ struct VersionedTransaction {
3131

3232
YB_STRUCT_DEFINE_HASH(VersionedTransaction, txn_id, txn_version);
3333

34+
auto operator<=>(const VersionedTransaction&) const = default;
35+
3436
std::string ToString() const {
3537
return YB_STRUCT_TO_STRING(txn_id, txn_version);
3638
}
3739
};
3840

39-
inline bool operator==(const VersionedTransaction& lhs, const VersionedTransaction& rhs) {
40-
return YB_STRUCT_EQUALS(txn_id, txn_version);
41-
}
42-
43-
inline bool operator<(const VersionedTransaction& lhs, const VersionedTransaction& rhs) {
44-
if (lhs.txn_id != rhs.txn_id) {
45-
return lhs.txn_id < rhs.txn_id;
46-
}
47-
return lhs.txn_version < rhs.txn_version;
48-
}
49-
5041
struct ObjectLockOwner {
5142
VersionedTransaction versioned_txn;
5243
SubTransactionId subtxn_id;
5344

5445
ObjectLockOwner(
5546
const TransactionId& txn_id_, TxnReuseVersion txn_version_, SubTransactionId subtxn_id_)
5647
: versioned_txn(txn_id_, txn_version_), subtxn_id(subtxn_id_) {}
48+
ObjectLockOwner(const VersionedTransaction& versioned_txn_, SubTransactionId subtxn_id_)
49+
: versioned_txn(versioned_txn_), subtxn_id(subtxn_id_) {}
5750
ObjectLockOwner(VersionedTransaction&& versioned_txn_, SubTransactionId subtxn_id_)
5851
: versioned_txn(std::move(versioned_txn_)), subtxn_id(subtxn_id_) {}
5952

@@ -66,22 +59,13 @@ struct ObjectLockOwner {
6659

6760
YB_STRUCT_DEFINE_HASH(ObjectLockOwner, versioned_txn, subtxn_id);
6861

62+
auto operator<=>(const ObjectLockOwner&) const = default;
63+
6964
std::string ToString() const {
7065
return YB_STRUCT_TO_STRING(versioned_txn, subtxn_id);
7166
}
7267
};
7368

74-
inline bool operator==(const ObjectLockOwner& lhs, const ObjectLockOwner& rhs) {
75-
return YB_STRUCT_EQUALS(versioned_txn, subtxn_id);
76-
}
77-
78-
inline bool operator<(const ObjectLockOwner& lhs, const ObjectLockOwner& rhs) {
79-
if (lhs.versioned_txn != rhs.versioned_txn) {
80-
return lhs.versioned_txn < rhs.versioned_txn;
81-
}
82-
return lhs.subtxn_id < rhs.subtxn_id;
83-
}
84-
8569
// ObjectLockPrefix is the entity for which the ts_local_lock_manager acquires locks. In context of
8670
// object/table locks, when a session requests lock(s) on an object oid corresponding to a database
8771
// oid, an 'ObjectLockPrefix' in formed which is then passed to the ObjectLockManager.
@@ -96,23 +80,11 @@ struct ObjectLockPrefix {
9680

9781
YB_STRUCT_DEFINE_HASH(ObjectLockPrefix, database_oid, object_oid, lock_type);
9882

83+
auto operator<=>(const ObjectLockPrefix&) const = default;
84+
9985
uint64_t database_oid;
10086
uint64_t object_oid;
10187
dockv::KeyEntryType lock_type;
10288
};
10389

104-
inline bool operator==(const ObjectLockPrefix& lhs, const ObjectLockPrefix& rhs) {
105-
return YB_STRUCT_EQUALS(database_oid, object_oid, lock_type);
106-
}
107-
108-
inline bool operator<(const ObjectLockPrefix& lhs, const ObjectLockPrefix& rhs) {
109-
if (lhs.database_oid != rhs.database_oid) {
110-
return lhs.database_oid < rhs.database_oid;
111-
}
112-
if (lhs.object_oid != rhs.object_oid) {
113-
return lhs.object_oid < rhs.object_oid;
114-
}
115-
return lhs.lock_type < rhs.lock_type;
116-
}
117-
11890
} // namespace yb::docdb

0 commit comments

Comments
 (0)