Skip to content

Commit ad82e86

Browse files
lock categories to control different lock-purposes (#12163)
1 parent b458331 commit ad82e86

File tree

23 files changed

+184
-88
lines changed

23 files changed

+184
-88
lines changed
Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,93 @@
11
#pragma once
22
#include <ydb/library/accessor/accessor.h>
33

4-
#include <util/generic/string.h>
54
#include <util/generic/hash_set.h>
5+
#include <util/generic/string.h>
66

7-
#include <optional>
87
#include <memory>
8+
#include <optional>
9+
#include <set>
910
#include <vector>
1011

1112
namespace NKikimr::NOlap {
1213
class TPortionInfo;
1314
class TGranuleMeta;
14-
}
15+
} // namespace NKikimr::NOlap
1516

1617
namespace NKikimr::NOlap::NDataLocks {
1718

19+
enum class ELockCategory : ui32 {
20+
Compaction = 0,
21+
Cleanup,
22+
Sharing,
23+
Actualization,
24+
Tables,
25+
Any,
26+
MAX
27+
};
28+
29+
static const inline std::array<std::set<ELockCategory>, (ui32)ELockCategory::MAX> LockCategoriesInteraction = {
30+
//Compaction
31+
std::set<ELockCategory>({ ELockCategory::Compaction, ELockCategory::Actualization, ELockCategory::Tables, ELockCategory::Any}),
32+
//Cleanup
33+
std::set<ELockCategory>({ ELockCategory::Cleanup, ELockCategory::Sharing, ELockCategory::Tables, ELockCategory::Any }),
34+
//Sharing
35+
std::set<ELockCategory>({ ELockCategory::Sharing, ELockCategory::Cleanup, ELockCategory::Tables, ELockCategory::Any }),
36+
//Actualization
37+
std::set<ELockCategory>({ ELockCategory::Actualization, ELockCategory::Compaction, ELockCategory::Tables, ELockCategory::Any }),
38+
//Tables
39+
std::set<ELockCategory>({ ELockCategory::Cleanup, ELockCategory::Sharing, ELockCategory::Actualization, ELockCategory::Compaction,
40+
ELockCategory::Tables, ELockCategory::Any }),
41+
//Any
42+
std::set<ELockCategory>({ ELockCategory::Cleanup, ELockCategory::Sharing, ELockCategory::Actualization, ELockCategory::Compaction,
43+
ELockCategory::Tables, ELockCategory::Any }),
44+
};
45+
1846
class ILock {
1947
private:
2048
YDB_READONLY_DEF(TString, LockName);
2149
YDB_READONLY_FLAG(ReadOnly, false);
50+
const ELockCategory Category;
51+
2252
protected:
23-
virtual std::optional<TString> DoIsLocked(const TPortionInfo& portion, const THashSet<TString>& excludedLocks = {}) const = 0;
24-
virtual std::optional<TString> DoIsLocked(const TGranuleMeta& granule, const THashSet<TString>& excludedLocks = {}) const = 0;
53+
virtual std::optional<TString> DoIsLocked(
54+
const TPortionInfo& portion, const ELockCategory category, const THashSet<TString>& excludedLocks = {}) const = 0;
55+
virtual std::optional<TString> DoIsLocked(
56+
const TGranuleMeta& granule, const ELockCategory category, const THashSet<TString>& excludedLocks = {}) const = 0;
2557
virtual bool DoIsEmpty() const = 0;
58+
2659
public:
27-
ILock(const TString& lockName, const bool isReadOnly = false)
60+
ILock(const TString& lockName, const ELockCategory category, const bool isReadOnly = false)
2861
: LockName(lockName)
2962
, ReadOnlyFlag(isReadOnly)
30-
{
31-
63+
, Category(category) {
3264
}
3365

3466
virtual ~ILock() = default;
3567

36-
std::optional<TString> IsLocked(const TPortionInfo& portion, const THashSet<TString>& excludedLocks = {}, const bool readOnly = false) const {
68+
std::optional<TString> IsLocked(const TPortionInfo& portion, const ELockCategory portionForLock, const THashSet<TString>& excludedLocks = {},
69+
const bool readOnly = false) const {
3770
if (IsReadOnly() && readOnly) {
3871
return {};
3972
}
40-
return DoIsLocked(portion, excludedLocks);
73+
if (!LockCategoriesInteraction[(ui32)Category].contains(portionForLock)) {
74+
return {};
75+
}
76+
return DoIsLocked(portion, portionForLock, excludedLocks);
4177
}
42-
std::optional<TString> IsLocked(const TGranuleMeta& g, const THashSet<TString>& excludedLocks = {}, const bool readOnly = false) const {
78+
std::optional<TString> IsLocked(const TGranuleMeta& g, const ELockCategory portionForLock, const THashSet<TString>& excludedLocks = {},
79+
const bool readOnly = false) const {
4380
if (IsReadOnly() && readOnly) {
4481
return {};
4582
}
46-
return DoIsLocked(g, excludedLocks);
83+
if (!LockCategoriesInteraction[(ui32)Category].contains(portionForLock)) {
84+
return {};
85+
}
86+
return DoIsLocked(g, portionForLock, excludedLocks);
4787
}
4888
bool IsEmpty() const {
4989
return DoIsEmpty();
5090
}
5191
};
5292

53-
}
93+
} // namespace NKikimr::NOlap::NDataLocks

ydb/core/tx/columnshard/data_locks/locks/composite.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,24 @@ class TCompositeLock: public ILock {
88
using TBase = ILock;
99
std::vector<std::shared_ptr<ILock>> Locks;
1010
protected:
11-
virtual std::optional<TString> DoIsLocked(const TPortionInfo& portion, const THashSet<TString>& excludedLocks) const override {
11+
virtual std::optional<TString> DoIsLocked(const TPortionInfo& portion, const ELockCategory category, const THashSet<TString>& excludedLocks) const override {
1212
for (auto&& i : Locks) {
1313
if (excludedLocks.contains(i->GetLockName())) {
1414
continue;
1515
}
16-
if (auto lockName = i->IsLocked(portion)) {
16+
if (auto lockName = i->IsLocked(portion, category)) {
1717
return lockName;
1818
}
1919
}
2020
return {};
2121
}
22-
virtual std::optional<TString> DoIsLocked(const TGranuleMeta& granule, const THashSet<TString>& excludedLocks) const override {
22+
virtual std::optional<TString> DoIsLocked(
23+
const TGranuleMeta& granule, const ELockCategory category, const THashSet<TString>& excludedLocks) const override {
2324
for (auto&& i : Locks) {
2425
if (excludedLocks.contains(i->GetLockName())) {
2526
continue;
2627
}
27-
if (auto lockName = i->IsLocked(granule)) {
28+
if (auto lockName = i->IsLocked(granule, category)) {
2829
return lockName;
2930
}
3031
}
@@ -34,8 +35,9 @@ class TCompositeLock: public ILock {
3435
return Locks.empty();
3536
}
3637
public:
37-
TCompositeLock(const TString& lockName, const std::vector<std::shared_ptr<ILock>>& locks, const bool readOnly = false)
38-
: TBase(lockName, readOnly)
38+
TCompositeLock(const TString& lockName, const std::vector<std::shared_ptr<ILock>>& locks,
39+
const ELockCategory category = NDataLocks::ELockCategory::Any, const bool readOnly = false)
40+
: TBase(lockName, category, readOnly)
3941
{
4042
for (auto&& l : locks) {
4143
if (!l || l->IsEmpty()) {
@@ -45,8 +47,9 @@ class TCompositeLock: public ILock {
4547
}
4648
}
4749

48-
TCompositeLock(const TString& lockName, std::initializer_list<std::shared_ptr<ILock>> locks, const bool readOnly = false)
49-
: TBase(lockName, readOnly)
50+
TCompositeLock(const TString& lockName, std::initializer_list<std::shared_ptr<ILock>> locks,
51+
const ELockCategory category = NDataLocks::ELockCategory::Any, const bool readOnly = false)
52+
: TBase(lockName, category, readOnly)
5053
{
5154
for (auto&& l : locks) {
5255
if (!l || l->IsEmpty()) {

ydb/core/tx/columnshard/data_locks/locks/list.h

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ class TListPortionsLock: public ILock {
1111
THashSet<TPortionAddress> Portions;
1212
THashSet<ui64> Granules;
1313
protected:
14-
virtual std::optional<TString> DoIsLocked(const TPortionInfo& portion, const THashSet<TString>& /*excludedLocks*/) const override {
14+
virtual std::optional<TString> DoIsLocked(
15+
const TPortionInfo& portion, const ELockCategory /*category*/, const THashSet<TString>& /*excludedLocks*/) const override {
1516
if (Portions.contains(portion.GetAddress())) {
1617
return GetLockName();
1718
}
1819
return {};
1920
}
20-
virtual std::optional<TString> DoIsLocked(const TGranuleMeta& granule, const THashSet<TString>& /*excludedLocks*/) const override {
21+
virtual std::optional<TString> DoIsLocked(
22+
const TGranuleMeta& granule, const ELockCategory /*category*/, const THashSet<TString>& /*excludedLocks*/) const override {
2123
if (Granules.contains(granule.GetPathId())) {
2224
return GetLockName();
2325
}
@@ -27,42 +29,46 @@ class TListPortionsLock: public ILock {
2729
return Portions.empty();
2830
}
2931
public:
30-
TListPortionsLock(const TString& lockName, const std::vector<TPortionDataAccessor>& portions, const bool readOnly = false)
31-
: TBase(lockName, readOnly)
32+
TListPortionsLock(const TString& lockName, const std::vector<TPortionDataAccessor>& portions, const ELockCategory category, const bool readOnly = false)
33+
: TBase(lockName, category, readOnly)
3234
{
3335
for (auto&& p : portions) {
3436
Portions.emplace(p.GetPortionInfo().GetAddress());
3537
Granules.emplace(p.GetPortionInfo().GetPathId());
3638
}
3739
}
3840

39-
TListPortionsLock(const TString& lockName, const std::vector<std::shared_ptr<TPortionInfo>>& portions, const bool readOnly = false)
40-
: TBase(lockName, readOnly) {
41+
TListPortionsLock(const TString& lockName, const std::vector<std::shared_ptr<TPortionInfo>>& portions, const ELockCategory category,
42+
const bool readOnly = false)
43+
: TBase(lockName, category, readOnly) {
4144
for (auto&& p : portions) {
4245
Portions.emplace(p->GetAddress());
4346
Granules.emplace(p->GetPathId());
4447
}
4548
}
4649

47-
TListPortionsLock(const TString& lockName, const std::vector<TPortionInfo::TConstPtr>& portions, const bool readOnly = false)
48-
: TBase(lockName, readOnly) {
50+
TListPortionsLock(
51+
const TString& lockName, const std::vector<TPortionInfo::TConstPtr>& portions, const ELockCategory category, const bool readOnly = false)
52+
: TBase(lockName, category, readOnly) {
4953
for (auto&& p : portions) {
5054
Portions.emplace(p->GetAddress());
5155
Granules.emplace(p->GetPathId());
5256
}
5357
}
5458

55-
TListPortionsLock(const TString& lockName, const std::vector<TPortionInfo>& portions, const bool readOnly = false)
56-
: TBase(lockName, readOnly) {
59+
TListPortionsLock(
60+
const TString& lockName, const std::vector<TPortionInfo>& portions, const ELockCategory category, const bool readOnly = false)
61+
: TBase(lockName, category, readOnly) {
5762
for (auto&& p : portions) {
5863
Portions.emplace(p.GetAddress());
5964
Granules.emplace(p.GetPathId());
6065
}
6166
}
6267

6368
template <class T, class TGetter>
64-
TListPortionsLock(const TString& lockName, const std::vector<T>& portions, const TGetter& g, const bool readOnly = false)
65-
: TBase(lockName, readOnly) {
69+
TListPortionsLock(
70+
const TString& lockName, const std::vector<T>& portions, const TGetter& g, const ELockCategory category, const bool readOnly = false)
71+
: TBase(lockName, category, readOnly) {
6672
for (auto&& p : portions) {
6773
const auto address = g(p);
6874
Portions.emplace(address);
@@ -71,17 +77,19 @@ class TListPortionsLock: public ILock {
7177
}
7278

7379
template <class T>
74-
TListPortionsLock(const TString& lockName, const THashMap<TPortionAddress, T>& portions, const bool readOnly = false)
75-
: TBase(lockName, readOnly) {
80+
TListPortionsLock(
81+
const TString& lockName, const THashMap<TPortionAddress, T>& portions, const ELockCategory category, const bool readOnly = false)
82+
: TBase(lockName, category, readOnly) {
7683
for (auto&& p : portions) {
7784
const auto address = p.first;
7885
Portions.emplace(address);
7986
Granules.emplace(address.GetPathId());
8087
}
8188
}
8289

83-
TListPortionsLock(const TString& lockName, const THashSet<TPortionAddress>& portions, const bool readOnly = false)
84-
: TBase(lockName, readOnly) {
90+
TListPortionsLock(
91+
const TString& lockName, const THashSet<TPortionAddress>& portions, const ELockCategory category, const bool readOnly = false)
92+
: TBase(lockName, category, readOnly) {
8593
for (auto&& address : portions) {
8694
Portions.emplace(address);
8795
Granules.emplace(address.GetPathId());
@@ -94,13 +102,15 @@ class TListTablesLock: public ILock {
94102
using TBase = ILock;
95103
THashSet<ui64> Tables;
96104
protected:
97-
virtual std::optional<TString> DoIsLocked(const TPortionInfo& portion, const THashSet<TString>& /*excludedLocks*/) const override {
105+
virtual std::optional<TString> DoIsLocked(
106+
const TPortionInfo& portion, const ELockCategory /*category*/, const THashSet<TString>& /*excludedLocks*/) const override {
98107
if (Tables.contains(portion.GetPathId())) {
99108
return GetLockName();
100109
}
101110
return {};
102111
}
103-
virtual std::optional<TString> DoIsLocked(const TGranuleMeta& granule, const THashSet<TString>& /*excludedLocks*/) const override {
112+
virtual std::optional<TString> DoIsLocked(
113+
const TGranuleMeta& granule, const ELockCategory /*category*/, const THashSet<TString>& /*excludedLocks*/) const override {
104114
if (Tables.contains(granule.GetPathId())) {
105115
return GetLockName();
106116
}
@@ -110,8 +120,8 @@ class TListTablesLock: public ILock {
110120
return Tables.empty();
111121
}
112122
public:
113-
TListTablesLock(const TString& lockName, const THashSet<ui64>& tables, const bool readOnly = false)
114-
: TBase(lockName, readOnly)
123+
TListTablesLock(const TString& lockName, const THashSet<ui64>& tables, const ELockCategory category, const bool readOnly = false)
124+
: TBase(lockName, category, readOnly)
115125
, Tables(tables)
116126
{
117127
}

ydb/core/tx/columnshard/data_locks/locks/snapshot.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ class TSnapshotLock: public ILock {
1111
const TSnapshot SnapshotBarrier;
1212
const THashSet<ui64> PathIds;
1313
protected:
14-
virtual std::optional<TString> DoIsLocked(const TPortionInfo& portion, const THashSet<TString>& /*excludedLocks*/) const override {
14+
virtual std::optional<TString> DoIsLocked(
15+
const TPortionInfo& portion, const ELockCategory /*category*/, const THashSet<TString>& /*excludedLocks*/) const override {
1516
if (PathIds.contains(portion.GetPathId()) && portion.RecordSnapshotMin() <= SnapshotBarrier) {
1617
return GetLockName();
1718
}
@@ -20,15 +21,16 @@ class TSnapshotLock: public ILock {
2021
virtual bool DoIsEmpty() const override {
2122
return PathIds.empty();
2223
}
23-
virtual std::optional<TString> DoIsLocked(const TGranuleMeta& granule, const THashSet<TString>& /*excludedLocks*/) const override {
24+
virtual std::optional<TString> DoIsLocked(
25+
const TGranuleMeta& granule, const ELockCategory /*category*/, const THashSet<TString>& /*excludedLocks*/) const override {
2426
if (PathIds.contains(granule.GetPathId())) {
2527
return GetLockName();
2628
}
2729
return {};
2830
}
2931
public:
30-
TSnapshotLock(const TString& lockName, const TSnapshot& snapshotBarrier, const THashSet<ui64>& pathIds, const bool readOnly = false)
31-
: TBase(lockName, readOnly)
32+
TSnapshotLock(const TString& lockName, const TSnapshot& snapshotBarrier, const THashSet<ui64>& pathIds, const ELockCategory category, const bool readOnly = false)
33+
: TBase(lockName, category, readOnly)
3234
, SnapshotBarrier(snapshotBarrier)
3335
, PathIds(pathIds)
3436
{

ydb/core/tx/columnshard/data_locks/manager/manager.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,36 @@ void TManager::UnregisterLock(const TString& processId) {
1515
AFL_VERIFY(ProcessLocks.erase(processId))("process_id", processId);
1616
}
1717

18-
std::optional<TString> TManager::IsLocked(const TPortionInfo& portion, const THashSet<TString>& excludedLocks) const {
18+
std::optional<TString> TManager::IsLocked(
19+
const TPortionInfo& portion, const ELockCategory lockCategory, const THashSet<TString>& excludedLocks) const {
1920
for (auto&& i : ProcessLocks) {
2021
if (excludedLocks.contains(i.first)) {
2122
continue;
2223
}
23-
if (auto lockName = i.second->IsLocked(portion, excludedLocks)) {
24+
if (auto lockName = i.second->IsLocked(portion, lockCategory, excludedLocks)) {
2425
return lockName;
2526
}
2627
}
2728
return {};
2829
}
2930

30-
std::optional<TString> TManager::IsLocked(const TGranuleMeta& granule, const THashSet<TString>& excludedLocks) const {
31+
std::optional<TString> TManager::IsLocked(
32+
const TGranuleMeta& granule, const ELockCategory lockCategory, const THashSet<TString>& excludedLocks) const {
3133
for (auto&& i : ProcessLocks) {
3234
if (excludedLocks.contains(i.first)) {
3335
continue;
3436
}
35-
if (auto lockName = i.second->IsLocked(granule, excludedLocks)) {
37+
if (auto lockName = i.second->IsLocked(granule, lockCategory, excludedLocks)) {
3638
return lockName;
3739
}
3840
}
3941
return {};
4042
}
4143

42-
std::optional<TString> TManager::IsLocked(
43-
const std::shared_ptr<const TPortionInfo>& portion, const THashSet<TString>& excludedLocks /*= {}*/) const {
44+
std::optional<TString> TManager::IsLocked(const std::shared_ptr<const TPortionInfo>& portion, const ELockCategory lockCategory,
45+
const THashSet<TString>& excludedLocks /*= {}*/) const {
4446
AFL_VERIFY(!!portion);
45-
return IsLocked(*portion, excludedLocks);
47+
return IsLocked(*portion, lockCategory, excludedLocks);
4648
}
4749

4850
void TManager::Stop() {

ydb/core/tx/columnshard/data_locks/manager/manager.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ class TManager {
4141
[[nodiscard]] std::shared_ptr<TGuard> RegisterLock(Args&&... args) {
4242
return RegisterLock(std::make_shared<TLock>(args...));
4343
}
44-
std::optional<TString> IsLocked(const TPortionInfo& portion, const THashSet<TString>& excludedLocks = {}) const;
45-
std::optional<TString> IsLocked(const std::shared_ptr<const TPortionInfo>& portion, const THashSet<TString>& excludedLocks = {}) const;
46-
std::optional<TString> IsLocked(const TGranuleMeta& granule, const THashSet<TString>& excludedLocks = {}) const;
44+
std::optional<TString> IsLocked(
45+
const TPortionInfo& portion, const ELockCategory lockCategory, const THashSet<TString>& excludedLocks = {}) const;
46+
std::optional<TString> IsLocked(
47+
const std::shared_ptr<const TPortionInfo>& portion, const ELockCategory lockCategory, const THashSet<TString>& excludedLocks = {}) const;
48+
std::optional<TString> IsLocked(
49+
const TGranuleMeta& granule, const ELockCategory lockCategory, const THashSet<TString>& excludedLocks = {}) const;
4750

4851
};
4952

ydb/core/tx/columnshard/data_sharing/common/session/common.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ TConclusionStatus TCommonSession::TryStart(NColumnShard::TColumnShard& shard) {
2424
for (auto&& i : GetPathIdsForStart()) {
2525
const auto& g = index.GetGranuleVerified(i);
2626
for (auto&& p : g.GetPortionsOlderThenSnapshot(GetSnapshotBarrier())) {
27-
if (shard.GetDataLocksManager()->IsLocked(*p.second, { "sharing_session:" + GetSessionId() })) {
27+
if (shard.GetDataLocksManager()->IsLocked(
28+
*p.second, NDataLocks::ELockCategory::Sharing, { "sharing_session:" + GetSessionId() })) {
2829
return TConclusionStatus::Fail("failed to start cursor: portion is locked");
2930
}
3031
// portionsByPath[i].emplace_back(p.second);
@@ -48,7 +49,7 @@ void TCommonSession::PrepareToStart(const NColumnShard::TColumnShard& shard) {
4849
State = EState::Prepared;
4950
AFL_VERIFY(!LockGuard);
5051
LockGuard = shard.GetDataLocksManager()->RegisterLock<NDataLocks::TSnapshotLock>("sharing_session:" + GetSessionId(),
51-
TransferContext.GetSnapshotBarrierVerified(), GetPathIdsForStart(), true);
52+
TransferContext.GetSnapshotBarrierVerified(), GetPathIdsForStart(), NDataLocks::ELockCategory::Sharing, true);
5253
shard.GetSharingSessionsManager()->StartSharingSession();
5354
}
5455

0 commit comments

Comments
 (0)