aboutsummaryrefslogtreecommitdiff
path: root/src/zenstore/gc.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-06-13 08:53:01 +0200
committerGitHub Enterprise <[email protected]>2024-06-13 08:53:01 +0200
commitb71d52375e41a084e661d0f55f044ca8982312a4 (patch)
treef44e74a13e29d50ab36d1eebfdb4c7e606d879a9 /src/zenstore/gc.cpp
parent5.5.3-pre1 (diff)
downloadzen-b71d52375e41a084e661d0f55f044ca8982312a4.tar.xz
zen-b71d52375e41a084e661d0f55f044ca8982312a4.zip
Make sure we monitor for new project, oplogs, namespaces and buckets during GCv2 (#93)
- Bugfix: Make sure we monitor and include new project/oplogs created during GCv2 - Bugfix: Make sure we monitor and include new namespaces/cache buckets created during GCv2
Diffstat (limited to 'src/zenstore/gc.cpp')
-rw-r--r--src/zenstore/gc.cpp124
1 files changed, 85 insertions, 39 deletions
diff --git a/src/zenstore/gc.cpp b/src/zenstore/gc.cpp
index e8cf6ec5e..8db34b9c5 100644
--- a/src/zenstore/gc.cpp
+++ b/src/zenstore/gc.cpp
@@ -382,7 +382,7 @@ WriteReferencerStats(CbObjectWriter& Writer, const GcReferencerStats& Stats, boo
Writer << "CreateReferenceCheckers" << ToTimeSpan(Stats.CreateReferenceCheckersMS);
Writer << "PreCacheState" << ToTimeSpan(Stats.PreCacheStateMS);
- Writer << "LockState" << ToTimeSpan(Stats.LockStateMS);
+ Writer << "UpdateLockedState" << ToTimeSpan(Stats.UpdateLockedStateMS);
Writer << "Elapsed" << ToTimeSpan(Stats.ElapsedMS);
};
@@ -452,6 +452,7 @@ WriteGCResult(CbObjectWriter& Writer, const GcResult& Result, bool HumanReadable
Writer << "CreateReferenceCheckers" << ToTimeSpan(Result.CreateReferenceCheckersMS);
Writer << "PreCacheState" << ToTimeSpan(Result.PreCacheStateMS);
Writer << "LockState" << ToTimeSpan(Result.LockStateMS);
+ Writer << "UpdateLockedState" << ToTimeSpan(Result.UpdateLockedStateMS);
Writer << "CreateReferencePruners" << ToTimeSpan(Result.CreateReferencePrunersMS);
Writer << "RemoveUnreferencedData" << ToTimeSpan(Result.RemoveUnreferencedDataMS);
@@ -510,7 +511,7 @@ void
Sum(GcReferencerStats& Stat)
{
Stat.ElapsedMS = Stat.RemoveExpiredDataStats.ElapsedMS + Stat.CompactStoreStats.ElapsedMS + Stat.CreateReferenceCheckersMS +
- Stat.PreCacheStateMS + Stat.LockStateMS;
+ Stat.PreCacheStateMS + Stat.UpdateLockedStateMS;
}
void
@@ -521,7 +522,7 @@ Add(GcReferencerStats& Sum, const GcReferencerStats& Sub)
Sum.CreateReferenceCheckersMS += Sub.CreateReferenceCheckersMS;
Sum.PreCacheStateMS += Sub.PreCacheStateMS;
- Sum.LockStateMS += Sub.LockStateMS;
+ Sum.UpdateLockedStateMS += Sub.UpdateLockedStateMS;
Sum.ElapsedMS += Sub.ElapsedMS;
}
@@ -584,6 +585,19 @@ GcManager::RemoveGcReferencer(GcReferencer& Referencer)
}
void
+GcManager::AddGcReferenceLocker(GcReferenceLocker& ReferenceLocker)
+{
+ RwLock::ExclusiveLockScope _(m_Lock);
+ m_GcReferencerLockers.push_back(&ReferenceLocker);
+}
+void
+GcManager::RemoveGcReferenceLocker(GcReferenceLocker& ReferenceLocker)
+{
+ RwLock::ExclusiveLockScope _(m_Lock);
+ std::erase_if(m_GcReferencerLockers, [&](GcReferenceLocker* $) { return $ == &ReferenceLocker; });
+}
+
+void
GcManager::AddGcReferenceStore(GcReferenceStore& ReferenceStore)
{
RwLock::ExclusiveLockScope _(m_Lock);
@@ -879,59 +893,90 @@ GcManager::CollectGarbage(const GcSettings& Settings)
}
}
+ std::vector<RwLock::SharedLockScope> LockerScopes;
SCOPED_TIMER(uint64_t ElapsedMS = Timer.GetElapsedTimeMs(); Result.WriteBlockMS = std::chrono::milliseconds(ElapsedMS);
ZEN_INFO("GCV2: Writes blocked for {}", NiceTimeSpanMs(ElapsedMS)));
{
- ZEN_INFO("GCV2: Locking state for {} reference checkers", ReferenceCheckers.size());
if (!ReferenceCheckers.empty())
{
if (CheckGCCancel())
{
return Sum(Result, true);
}
- ZEN_TRACE_CPU("GcV2::LockState");
-
- // Locking all references checkers so we have a steady state of which references are used
- // From this point we have blocked all writes to all References (DiskBucket/ProjectStore) until
- // we delete the ReferenceCheckers
- Latch WorkLeft(1);
-
+ ZEN_INFO("GCV2: Locking state for {} reference checkers", ReferenceCheckers.size());
{
- SCOPED_TIMER(Result.LockStateMS = std::chrono::milliseconds(Timer.GetElapsedTimeMs());
- if (Ctx.Settings.Verbose) {
- ZEN_INFO("GCV2: Locked state using {} reference checkers in {}",
- ReferenceCheckers.size(),
- NiceTimeSpanMs(Result.LockStateMS.count()));
- });
- for (auto& It : ReferenceCheckers)
+ ZEN_TRACE_CPU("GcV2::LockReferencers");
+ // From this point we have blocked all writes to all References (DiskBucket/ProjectStore) until
+ // we delete the ReferenceLockers
+ Latch WorkLeft(1);
{
- if (CheckGCCancel())
+ SCOPED_TIMER(Result.LockStateMS = std::chrono::milliseconds(Timer.GetElapsedTimeMs());
+ if (Ctx.Settings.Verbose) {
+ ZEN_INFO("GCV2: Locked referencers using {} reference lockers in {}",
+ ReferenceCheckers.size(),
+ NiceTimeSpanMs(Result.LockStateMS.count()));
+ });
+ for (GcReferenceLocker* ReferenceLocker : m_GcReferencerLockers)
{
- WorkLeft.CountDown();
- WorkLeft.Wait();
- return Sum(Result, true);
- }
-
- GcReferenceChecker* Checker = It.first.get();
- size_t Index = It.second;
- std::pair<std::string, GcReferencerStats>* Stats = &Result.ReferencerStats[Index];
- WorkLeft.AddCount(1);
- ThreadPool.ScheduleWork([this, &Ctx, Checker, Index, Stats, &WorkLeft]() {
- auto _ = MakeGuard([&WorkLeft]() { WorkLeft.CountDown(); });
- try
+ std::vector<RwLock::SharedLockScope> LockScopes = ReferenceLocker->LockState(Ctx);
+ for (auto It = std::make_move_iterator(LockScopes.begin());
+ It != std::make_move_iterator(LockScopes.end());
+ It++)
{
- SCOPED_TIMER(Stats->second.LockStateMS = std::chrono::milliseconds(Timer.GetElapsedTimeMs()););
- Checker->LockState(Ctx);
+ LockerScopes.emplace_back(std::move(*It));
}
- catch (const std::exception& Ex)
+ }
+ }
+ }
+ ZEN_INFO("GCV2: Updating locked state for {} reference checkers", ReferenceCheckers.size());
+ {
+ ZEN_TRACE_CPU("GcV2::UpdateLockedState");
+
+ // Locking all references checkers so we have a steady state of which references are used
+ // From this point we have blocked all writes to all References (DiskBucket/ProjectStore) until
+ // we delete the ReferenceCheckers
+ Latch WorkLeft(1);
+
+ {
+ SCOPED_TIMER(Result.UpdateLockedStateMS = std::chrono::milliseconds(Timer.GetElapsedTimeMs());
+ if (Ctx.Settings.Verbose) {
+ ZEN_INFO("GCV2: Updated locked state using {} reference checkers in {}",
+ ReferenceCheckers.size(),
+ NiceTimeSpanMs(Result.UpdateLockedStateMS.count()));
+ });
+ for (auto& It : ReferenceCheckers)
+ {
+ if (CheckGCCancel())
{
- ZEN_ERROR("GCV2: Failed locking state for {}. Reason: '{}'", Checker->GetGcName(Ctx), Ex.what());
- SetCancelGC(true);
+ WorkLeft.CountDown();
+ WorkLeft.Wait();
+ return Sum(Result, true);
}
- });
+
+ GcReferenceChecker* Checker = It.first.get();
+ size_t Index = It.second;
+ std::pair<std::string, GcReferencerStats>* Stats = &Result.ReferencerStats[Index];
+ WorkLeft.AddCount(1);
+ ThreadPool.ScheduleWork([this, &Ctx, Checker, Index, Stats, &WorkLeft]() {
+ auto _ = MakeGuard([&WorkLeft]() { WorkLeft.CountDown(); });
+ try
+ {
+ SCOPED_TIMER(Stats->second.UpdateLockedStateMS =
+ std::chrono::milliseconds(Timer.GetElapsedTimeMs()););
+ Checker->UpdateLockedState(Ctx);
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("GCV2: Failed Updating locked state for {}. Reason: '{}'",
+ Checker->GetGcName(Ctx),
+ Ex.what());
+ SetCancelGC(true);
+ }
+ });
+ }
+ WorkLeft.CountDown();
+ WorkLeft.Wait();
}
- WorkLeft.CountDown();
- WorkLeft.Wait();
}
}
}
@@ -1020,6 +1065,7 @@ GcManager::CollectGarbage(const GcSettings& Settings)
}
}
// Let the GcReferencers add new data, we will only change on-disk data at this point, adding new data is allowed
+ LockerScopes.clear();
ReferenceCheckers.clear();
ReferencePruners.clear();
}