diff options
| author | Dan Engelbrecht <[email protected]> | 2024-06-13 08:53:01 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-06-13 08:53:01 +0200 |
| commit | b71d52375e41a084e661d0f55f044ca8982312a4 (patch) | |
| tree | f44e74a13e29d50ab36d1eebfdb4c7e606d879a9 /src/zenstore/gc.cpp | |
| parent | 5.5.3-pre1 (diff) | |
| download | zen-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.cpp | 124 |
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(); } |