diff options
author | alexvru <alexvru@ydb.tech> | 2023-10-24 23:17:09 +0300 |
---|---|---|
committer | alexvru <alexvru@ydb.tech> | 2023-10-24 23:53:10 +0300 |
commit | 50167f67480c8969d5b6fa49f878b356fab83cce (patch) | |
tree | 51826cd3b49e495c18b9a236df489399113f38d4 | |
parent | f497b52bb70f52b35c75ba4d18d66fd8904a16e2 (diff) | |
download | ydb-50167f67480c8969d5b6fa49f878b356fab83cce.tar.gz |
Fix garbage collection during initial sync process KIKIMR-19748
26 files changed, 136 insertions, 90 deletions
diff --git a/ydb/core/base/blobstorage.h b/ydb/core/base/blobstorage.h index 7955b529293..846abac4013 100644 --- a/ydb/core/base/blobstorage.h +++ b/ydb/core/base/blobstorage.h @@ -704,6 +704,7 @@ struct TEvBlobStorage { EvGetLogoBlobIndexStatRequest, EvReadMetadata, EvWriteMetadata, + EvPermitGarbageCollection, EvYardInitResult = EvPut + 9 * 512, /// 268 636 672 EvLogResult, diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp index a07206a22b2..7c566109391 100644 --- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp +++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp @@ -89,7 +89,8 @@ namespace NKikimr { // calculate keep status bool allowKeepFlags = HullCtx->AllowKeepFlags; NGc::TKeepStatus keep = brs->Keep(dbIt.GetCurKey(), dbMerger.GetMemRec(), - dbMerger.GetMemRecsMerged(), allowKeepFlags); + dbMerger.GetMemRecsMerged(), allowKeepFlags, + true /*allowGarbageCollection*/); if (keep.KeepIndex && !keep.KeepByBarrier) { // we keep this record because of keep flags candidates.AddCandidate(dbIt.GetCurKey().LogoBlobID()); diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp index 9372ce3c4fa..bb316e02414 100644 --- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp +++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp @@ -24,7 +24,7 @@ namespace NKikimr { const TMemRecLogoBlob &memRec, ui32 recsMerged, bool allowKeepFlags) const { - return BarriersEssence->Keep(key, memRec, recsMerged, allowKeepFlags).KeepData; + return BarriersEssence->Keep(key, memRec, recsMerged, allowKeepFlags, false /*allowGarbageCollection*/).KeepData; } TIntrusivePtr<THullCtx> HullCtx; @@ -92,10 +92,10 @@ namespace NKikimr { const auto& topology = *HullCtx->VCtx->Top; // topology we have Y_ABORT_UNLESS(topology.BelongsToSubgroup(self, CurKey.Hash())); // check that blob belongs to subgroup - //if (!Filter->Check(CurKey, CurIt.GetMemRec(), CurIt.GetMemRecsMerged(), HullCtx->AllowKeepFlags)) { - // // filter check returned false - // return false; - //} + if (!Filter->Check(CurKey, CurIt.GetMemRec(), CurIt.GetMemRecsMerged(), HullCtx->AllowKeepFlags)) { + // filter check returned false + return false; + } const TSubgroupPartLayout layout = TSubgroupPartLayout::CreateFromIngress(CurIngress, topology.GType); const ui32 idxInSubgroup = topology.GetIdxInSubgroup(self, CurKey.Hash()); diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_events.h b/ydb/core/blobstorage/vdisk/common/vdisk_events.h index 534f189e244..cf4749748ce 100644 --- a/ydb/core/blobstorage/vdisk/common/vdisk_events.h +++ b/ydb/core/blobstorage/vdisk/common/vdisk_events.h @@ -3075,4 +3075,6 @@ namespace NKikimr { } }; + struct TEvPermitGarbageCollection : TEventLocal<TEvPermitGarbageCollection, TEvBlobStorage::EvPermitGarbageCollection> {}; + } // NKikimr diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_search.h b/ydb/core/blobstorage/vdisk/defrag/defrag_search.h index 9c85bb7d362..d9bfd6f51ed 100644 --- a/ydb/core/blobstorage/vdisk/defrag/defrag_search.h +++ b/ydb/core/blobstorage/vdisk/defrag/defrag_search.h @@ -120,7 +120,7 @@ namespace NKikimr { void Finish() { if (!Merger.Empty()) { Y_ABORT_UNLESS(!Merger.HasSmallBlobs()); - NGc::TKeepStatus status = Barriers->Keep(Key, MemRec, NumMemRecsMerged, AllowKeepFlags); + NGc::TKeepStatus status = Barriers->Keep(Key, MemRec, NumMemRecsMerged, AllowKeepFlags, true /*allowGarbageCollection*/); const auto& hugeMerger = Merger.GetHugeBlobMerger(); const auto& local = MemRec.GetIngress().LocalParts(GType); ui8 partIdx = local.FirstPosition(); diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp index c05fd1e05a4..7bc04806db5 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp +++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp @@ -61,8 +61,13 @@ namespace NKikimr { NGc::TKeepStatus TBarriersEssence::KeepLogoBlob(const TLogoBlobID &id, const TIngress &ingress, const ui32 recsMerged, - const bool allowKeepFlags) const + const bool allowKeepFlags, + bool allowGarbageCollection) const { + if (!allowGarbageCollection) { + return {true}; + } + // extract gen and step const ui32 gen = id.Generation(); const ui32 step = id.Step(); diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h index 90b62281524..b8924b26012 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h +++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h @@ -35,33 +35,29 @@ namespace NGcOpt { NGc::TKeepStatus Keep(const TKeyLogoBlob &key, const TMemRecLogoBlob &memRec, ui32 recsMerged, - bool allowKeepFlags) const { + bool allowKeepFlags, + bool allowGarbageCollection) const { const TIngress ingress = memRec.GetIngress(); Y_DEBUG_ABORT_UNLESS(recsMerged >= 1); - return KeepLogoBlob(key.LogoBlobID(), ingress, recsMerged, allowKeepFlags); + return KeepLogoBlob(key.LogoBlobID(), ingress, recsMerged, allowKeepFlags, allowGarbageCollection); } - NGc::TKeepStatus Keep(const TKeyBlock &key, - const TMemRecBlock &memRec, - ui32 recsMerged, - bool allowKeepFlags) const { - Y_UNUSED(key); - Y_UNUSED(memRec); - Y_UNUSED(recsMerged); - Y_UNUSED(allowKeepFlags); + NGc::TKeepStatus Keep(const TKeyBlock& /*key*/, + const TMemRecBlock& /*memRec*/, + ui32 /*recsMerged*/, + bool /*allowKeepFlags*/, + bool /*allowGarbageCollection*/) const { // NOTE: We never delete block records, we only merge them. Merge rules are // very simple, i.e. last block wins. As a result, after full merge // blocks db size is equal to number of tablets on this vdisk. return NGc::TKeepStatus(true); } - NGc::TKeepStatus Keep(const TKeyBarrier &key, - const TMemRecBarrier &memRec, - ui32 recsMerged, - bool allowKeepFlags) const { - Y_UNUSED(memRec); - Y_UNUSED(recsMerged); - Y_UNUSED(allowKeepFlags); + NGc::TKeepStatus Keep(const TKeyBarrier& key, + const TMemRecBarrier& /*memRec*/, + ui32 /*recsMerged*/, + bool /*allowKeepFlags*/, + bool /*allowGarbageCollection*/) const { return KeepBarrier(key); } @@ -82,7 +78,8 @@ namespace NGcOpt { NGc::TKeepStatus KeepLogoBlob(const TLogoBlobID &id, const TIngress &ingress, const ui32 recsMerged, - const bool allowKeepFlags) const; + const bool allowKeepFlags, + bool allowGarbageCollection) const; }; } // NGcOpt diff --git a/ydb/core/blobstorage/vdisk/hulldb/blobstorage_hullgcmap.h b/ydb/core/blobstorage/vdisk/hulldb/blobstorage_hullgcmap.h index 5eedf65c169..79584e1177c 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/blobstorage_hullgcmap.h +++ b/ydb/core/blobstorage/vdisk/hulldb/blobstorage_hullgcmap.h @@ -107,12 +107,13 @@ namespace NKikimr { //////////////// Iterator ////////////////////////////////////////////// - TGcMap(TIntrusivePtr<THullCtx> &&hullCtx, ui64 incomingElementsApproximation) + TGcMap(TIntrusivePtr<THullCtx> &&hullCtx, ui64 incomingElementsApproximation, bool allowGarbageCollection) : HullCtx(std::move(hullCtx)) , IncomingElementsApproximation(incomingElementsApproximation) , IndexKeepMap() , DataKeepMap() , Stat() + , AllowGarbageCollection(allowGarbageCollection) {} // Prepares a map of keep/don't keep commands for every record @@ -139,7 +140,8 @@ namespace NKikimr { Y_UNUSED(subsMerger); bool allowKeepFlags = HullCtx->AllowKeepFlags; NGc::TKeepStatus keep = barriersEssence->Keep(dbIt.GetCurKey(), dbMerger.GetMemRec(), - dbMerger.GetMemRecsMerged(), allowKeepFlags); + dbMerger.GetMemRecsMerged(), allowKeepFlags, + AllowGarbageCollection); Stat.Update(dbIt.GetCurKey(), keep); if (keep.KeepIndex) { IndexKeepMap.Set(Stat.ItemsTotal - 1); @@ -177,14 +179,16 @@ namespace NKikimr { TDynBitMap IndexKeepMap; TDynBitMap DataKeepMap; TStat Stat; + const bool AllowGarbageCollection; }; template <class TKey, class TMemRec> TIntrusivePtr<TGcMap<TKey, TMemRec>> CreateGcMap( TIntrusivePtr<THullCtx> hullCtx, - ui64 incomingElementsApproximation) { - return new TGcMap<TKey, TMemRec>(std::move(hullCtx), incomingElementsApproximation); + ui64 incomingElementsApproximation, + bool allowGarbageCollection) { + return new TGcMap<TKey, TMemRec>(std::move(hullCtx), incomingElementsApproximation, allowGarbageCollection); } } // NKikimr diff --git a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h index fe2a48fc9ef..bab04546fab 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h +++ b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h @@ -26,10 +26,12 @@ namespace NKikimr { TStrategyStorageRatio(TIntrusivePtr<THullCtx> hullCtx, const TLevelIndexSnapshot &levelSnap, - TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> &&barriersEssence) + TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> &&barriersEssence, + bool allowGarbageCollection) : HullCtx(std::move(hullCtx)) , LevelSnap(levelSnap) , BarriersEssence(std::move(barriersEssence)) + , AllowGarbageCollection(allowGarbageCollection) {} @@ -53,6 +55,7 @@ namespace NKikimr { TIntrusivePtr<THullCtx> HullCtx; const TLevelIndexSnapshot &LevelSnap; TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> BarriersEssence; + const bool AllowGarbageCollection; struct TStat { ui32 SstsChecked = 0; @@ -163,7 +166,8 @@ namespace NKikimr { NGc::TKeepStatus keep = BarriersEssence->Keep(dbIt.GetCurKey(), dbMerger.GetMemRec(), dbMerger.GetMemRecsMerged(), - allowKeepFlags); + allowKeepFlags, + AllowGarbageCollection); if (keep.KeepIndex) { // calculate index overhead ratio->IndexItemsKeep++; diff --git a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.cpp b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.cpp index d020983f952..71334e7f21e 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.cpp +++ b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.cpp @@ -30,7 +30,7 @@ namespace NKikimr { // calculate storage ratio and gather space consumption statistics TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> barriersEssence = BarriersSnap.CreateEssence(HullCtx); BarriersSnap.Destroy(); - TStrategyStorageRatio(HullCtx, LevelSnap, std::move(barriersEssence)).Work(); + TStrategyStorageRatio(HullCtx, LevelSnap, std::move(barriersEssence), AllowGarbageCollection).Work(); // delete free ssts action = TStrategyDelSst(HullCtx, LevelSnap, Task).Select(); diff --git a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h index 649e222960d..ab256ee7b40 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h +++ b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h @@ -32,12 +32,14 @@ namespace NKikimr { const TSelectorParams ¶ms, TLevelIndexSnapshot &&levelSnap, TBarriersSnapshot &&barriersSnap, - TTask *task) + TTask *task, + bool allowGarbageCollection) : HullCtx(hullCtx) , LevelSnap(std::move(levelSnap)) , BarriersSnap(std::move(barriersSnap)) , Task(task) , Params(params) + , AllowGarbageCollection(allowGarbageCollection) { Y_DEBUG_ABORT_UNLESS(Task); Task->Clear(); @@ -53,6 +55,7 @@ namespace NKikimr { TBarriersSnapshot BarriersSnap; TTask *Task; TSelectorParams Params; + const bool AllowGarbageCollection; }; //////////////////////////////////////////////////////////////////////////// @@ -95,11 +98,12 @@ namespace NKikimr { TBarriersSnapshot BarriersSnap; const TActorId RecipientID; std::unique_ptr<TCompactionTask> CompactionTask; + const bool AllowGarbageCollection; void Bootstrap(const TActorContext &ctx) { TInstant startTime(TAppData::TimeProvider->Now()); TStrategy strategy(HullCtx, Params, std::move(LevelSnap), std::move(BarriersSnap), - CompactionTask.get()); + CompactionTask.get(), AllowGarbageCollection); NHullComp::EAction action = strategy.Select(); ctx.Send(RecipientID, new TSelected(action, std::move(CompactionTask))); @@ -124,7 +128,8 @@ namespace NKikimr { TLevelIndexSnapshot &&levelSnap, TBarriersSnapshot &&barriersSnap, const TActorId &recipientID, - std::unique_ptr<TCompactionTask> compactionTask) + std::unique_ptr<TCompactionTask> compactionTask, + bool allowGarbageCollection) : TActorBootstrapped<TThis>() , HullCtx(hullCtx) , Params(params) @@ -132,6 +137,7 @@ namespace NKikimr { , BarriersSnap(std::move(barriersSnap)) , RecipientID(recipientID) , CompactionTask(std::move(compactionTask)) + , AllowGarbageCollection(allowGarbageCollection) {} }; diff --git a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ut.cpp index da02b7de1ec..270776e73be 100644 --- a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ut.cpp +++ b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ut.cpp @@ -30,7 +30,7 @@ namespace NKikimr { TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> barriersEssence = snap.BarriersSnap.CreateEssence(snap.HullCtx); NHullComp::TStrategyStorageRatio<TKeyLogoBlob, TMemRecLogoBlob> - (snap.HullCtx, snap.LogoBlobsSnap, std::move(barriersEssence)).Work(); + (snap.HullCtx, snap.LogoBlobsSnap, std::move(barriersEssence), true).Work(); snap.LogoBlobsSnap.Output(STR); STR << "\n"; @@ -44,7 +44,7 @@ namespace NKikimr { TTask task; NHullComp::TSelectorParams params = {boundaries, 1.0, TInstant::Seconds(0), {}}; TStrategy strategy(snap.HullCtx, params, std::move(snap.LogoBlobsSnap), std::move(snap.BarriersSnap), - &task); + &task, true); auto action = strategy.Select(); STR << "action = " << NHullComp::ActionToStr(action) << "\n"; } diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp index 51784848b6d..05196bf9c26 100644 --- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp +++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp @@ -36,6 +36,7 @@ namespace NKikimr { TActorSystem *ActorSystem; const bool BarrierValidation; TDelayedResponses DelayedResponses; + bool AllowGarbageCollection = false; TFields(TIntrusivePtr<THullDs> hullDs, TIntrusivePtr<TLsnMngr> &&lsnMngr, @@ -207,7 +208,8 @@ namespace NKikimr { ReplayAddLogoBlobCmd(ctx, id, partId, ingress, std::move(buffer), lsn, THullDbRecovery::NORMAL); // run compaction if required - CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx); + CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); } void THull::AddHugeLogoBlob( @@ -220,7 +222,8 @@ namespace NKikimr { ReplayAddHugeLogoBlobCmd(ctx, id, ingress, diskAddr, lsn, THullDbRecovery::NORMAL); // run compaction if required - CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx); + CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); } void THull::AddAnubisOsirisLogoBlob( @@ -233,7 +236,8 @@ namespace NKikimr { ReplayAddLogoBlobCmd(ctx, id, ingress, seg.Point(), THullDbRecovery::NORMAL); // run compaction if required - CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx); + CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); } void THull::AddBulkSst( @@ -278,7 +282,8 @@ namespace NKikimr { Fields->DelayedResponses.ConfirmLsn(lsn, replySender); // run compaction if required - CompactFreshSegmentIfRequired<TKeyBlock, TMemRecBlock>(HullDs, Fields->BlocksRunTimeCtx, ctx); + CompactFreshSegmentIfRequired<TKeyBlock, TMemRecBlock>(HullDs, Fields->BlocksRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); } //////////////////////////////////////////////////////////////////////// @@ -464,8 +469,10 @@ namespace NKikimr { ReplayAddGCCmd(ctx, record, ingress, seg.Last); // run compaction if required - CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx); - CompactFreshSegmentIfRequired<TKeyBarrier, TMemRecBarrier>(HullDs, Fields->BarriersRunTimeCtx, ctx); + CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); + CompactFreshSegmentIfRequired<TKeyBarrier, TMemRecBarrier>(HullDs, Fields->BarriersRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); } void THull::CollectPhantoms( @@ -604,9 +611,12 @@ namespace NKikimr { Y_DEBUG_ABORT_UNLESS(curLsn == seg.Last + 1); // run compaction if required - CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx); - CompactFreshSegmentIfRequired<TKeyBlock, TMemRecBlock>(HullDs, Fields->BlocksRunTimeCtx, ctx); - CompactFreshSegmentIfRequired<TKeyBarrier, TMemRecBarrier>(HullDs, Fields->BarriersRunTimeCtx, ctx); + CompactFreshSegmentIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(HullDs, Fields->LogoBlobsRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); + CompactFreshSegmentIfRequired<TKeyBlock, TMemRecBlock>(HullDs, Fields->BlocksRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); + CompactFreshSegmentIfRequired<TKeyBarrier, TMemRecBarrier>(HullDs, Fields->BarriersRunTimeCtx, ctx, false, + Fields->AllowGarbageCollection); } // run fresh segment or fresh appendix compaction if required @@ -615,10 +625,12 @@ namespace NKikimr { const TActorContext &ctx, TIntrusivePtr<THullDs> &hullDs, std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx, - TLevelIndex<TKey, TMemRec> &levelIndex) + TLevelIndex<TKey, TMemRec> &levelIndex, + bool allowGarbageCollection) { // try to start fresh compaction - bool freshSegmentCompaction = CompactFreshSegmentIfRequired<TKey, TMemRec>(hullDs, rtCtx, ctx); + bool freshSegmentCompaction = CompactFreshSegmentIfRequired<TKey, TMemRec>(hullDs, rtCtx, ctx, false, + allowGarbageCollection); if (!freshSegmentCompaction) { // if not, try to start appendix compaction auto cjob = levelIndex.CompactFreshAppendix(); @@ -643,7 +655,7 @@ namespace NKikimr { ReplaySyncDataCmd_LogoBlobsBatch(ctx, std::move(freshBatch.LogoBlobs), s, THullDbRecovery::NORMAL); curLsn += logoBlobsCount; CompactFreshIfRequired<TKeyLogoBlob, TMemRecLogoBlob>(ctx, HullDs, - Fields->LogoBlobsRunTimeCtx, *HullDs->LogoBlobs); + Fields->LogoBlobsRunTimeCtx, *HullDs->LogoBlobs, Fields->AllowGarbageCollection); } if (freshBatch.Blocks) { @@ -660,7 +672,8 @@ namespace NKikimr { ReplaySyncDataCmd_BlocksBatch(ctx, std::move(freshBatch.Blocks), s, THullDbRecovery::NORMAL); // curLsn already updated in cycle - CompactFreshIfRequired<TKeyBlock, TMemRecBlock>(ctx, HullDs, Fields->BlocksRunTimeCtx, *HullDs->Blocks); + CompactFreshIfRequired<TKeyBlock, TMemRecBlock>(ctx, HullDs, + Fields->BlocksRunTimeCtx, *HullDs->Blocks, Fields->AllowGarbageCollection); } if (freshBatch.Barriers) { @@ -669,7 +682,7 @@ namespace NKikimr { ReplaySyncDataCmd_BarriersBatch(ctx, std::move(freshBatch.Barriers), s, THullDbRecovery::NORMAL); curLsn += barriersCount; CompactFreshIfRequired<TKeyBarrier, TMemRecBarrier>(ctx, HullDs, - Fields->BarriersRunTimeCtx, *HullDs->Barriers); + Fields->BarriersRunTimeCtx, *HullDs->Barriers, Fields->AllowGarbageCollection); } Y_ABORT_UNLESS(curLsn == seg.Last + 1); } @@ -683,4 +696,11 @@ namespace NKikimr { return HullDs->GetIndexSnapshot(); } + void THull::PermitGarbageCollection(const TActorContext& ctx) { + Fields->AllowGarbageCollection = true; + ctx.Send(HullDs->LogoBlobs->LIActor, new TEvPermitGarbageCollection); + ctx.Send(HullDs->Blocks->LIActor, new TEvPermitGarbageCollection); + ctx.Send(HullDs->Barriers->LIActor, new TEvPermitGarbageCollection); + } + } // NKikimr diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h index c6d74408e34..70656ed91a7 100644 --- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h +++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h @@ -210,6 +210,8 @@ namespace NKikimr { bool HasBlockRecordFor(ui64 tabletId) const { return BlocksCache.HasRecord(tabletId); } + + void PermitGarbageCollection(const TActorContext& ctx); }; // FIXME: diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp index c8cfafd7eee..1e425fec904 100644 --- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp +++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp @@ -78,7 +78,8 @@ namespace NKikimr { void CompactFreshSegment( TIntrusivePtr<THullDs> &hullDs, std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx, - const TActorContext &ctx) + const TActorContext &ctx, + bool allowGarbageCollection) { using TFreshSegment = ::NKikimr::TFreshSegment<TKey, TMemRec>; using TFreshSegmentSnapshot = ::NKikimr::TFreshSegmentSnapshot<TKey, TMemRec>; @@ -105,7 +106,7 @@ namespace NKikimr { ui64 lastLsn = freshSegment->GetLastLsn(); std::unique_ptr<TFreshCompaction> compaction(new TFreshCompaction( hullCtx, rtCtx, freshSegment, freshSegmentSnap, std::move(barriersSnap), std::move(levelSnap), - mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Max(), {})); + mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Max(), {}, allowGarbageCollection)); LOG_INFO(ctx, NKikimrServices::BS_HULLCOMP, VDISKP(hullCtx->VCtx->VDiskLogPrefix, @@ -170,6 +171,7 @@ namespace NKikimr { TFullCompactionState FullCompactionState; bool CompactionScheduled = false; TInstant NextCompactionWakeup; + bool AllowGarbageCollection = false; friend class TActorBootstrapped<TThis>; @@ -197,7 +199,7 @@ namespace NKikimr { auto fullCompactionAttrs = FullCompactionState.GetFullCompactionAttrsForLevelCompactionSelector(RTCtx); NHullComp::TSelectorParams params = {Boundaries, rateThreshold, TInstant::Seconds(0), fullCompactionAttrs}; auto selector = std::make_unique<TSelectorActor>(HullDs->HullCtx, params, std::move(levelSnap), - std::move(barriersSnap), ctx.SelfID, std::move(CompactionTask)); + std::move(barriersSnap), ctx.SelfID, std::move(CompactionTask), AllowGarbageCollection); auto aid = RunInBatchPool(ctx, selector.release()); ActiveActors.Insert(aid); return true; @@ -223,7 +225,8 @@ namespace NKikimr { void ScheduleCompaction(const TActorContext &ctx) { // schedule fresh if required - CompactFreshSegmentIfRequired<TKey, TMemRec>(HullDs, RTCtx, ctx, FullCompactionState.ForceFreshCompaction(RTCtx)); + CompactFreshSegmentIfRequired<TKey, TMemRec>(HullDs, RTCtx, ctx, FullCompactionState.ForceFreshCompaction(RTCtx), + AllowGarbageCollection); if (!RunLevelCompactionSelector(ctx)) { ScheduleCompactionWakeup(ctx); } @@ -251,7 +254,8 @@ namespace NKikimr { std::unique_ptr<TLevelCompaction> compaction(new TLevelCompaction( HullDs->HullCtx, RTCtx, nullptr, nullptr, std::move(barriersSnap), std::move(levelSnap), - mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Minutes(2), {})); + mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Minutes(2), {}, + AllowGarbageCollection)); NActors::TActorId actorId = RunInBatchPool(ctx, compaction.release()); ActiveActors.Insert(actorId); } @@ -520,7 +524,7 @@ namespace NKikimr { ScheduleCompaction(ctx); } else { CompactFreshSegmentIfRequired<TKey, TMemRec>(HullDs, RTCtx, ctx, - FullCompactionState.ForceFreshCompaction(RTCtx)); + FullCompactionState.ForceFreshCompaction(RTCtx), AllowGarbageCollection); } break; case THullCommitFinished::CommitAdvanceLsn: @@ -544,7 +548,7 @@ namespace NKikimr { RTCtx->SetFreeUpToLsn(freeUpToLsn); // we check if we need to start fresh compaction, FreeUpToLsn influence our decision const bool freshCompStarted = CompactFreshSegmentIfRequired<TKey, TMemRec>(HullDs, RTCtx, ctx, - FullCompactionState.ForceFreshCompaction(RTCtx)); + FullCompactionState.ForceFreshCompaction(RTCtx), AllowGarbageCollection); // just for valid info output to the log bool moveEntryPointStarted = false; if (!freshCompStarted && !AdvanceCommitInProgress) { @@ -626,6 +630,10 @@ namespace NKikimr { TThis::Die(ctx); } + void HandlePermitGarbageCollection(const TActorContext& /*ctx*/) { + AllowGarbageCollection = true; + } + STRICT_STFUNC(StateFunc, HFunc(THullCommitFinished, Handle) HFunc(NPDisk::TEvCutLog, Handle) @@ -636,6 +644,7 @@ namespace NKikimr { HTemplFunc(TEvAddBulkSst, Handle) HTemplFunc(TSelected, Handle) HFunc(TEvents::TEvPoisonPill, HandlePoison) + CFunc(TEvBlobStorage::EvPermitGarbageCollection, HandlePermitGarbageCollection); ) public: diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h index f1009416adc..95167a35ffb 100644 --- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h +++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h @@ -84,19 +84,21 @@ namespace NKikimr { void CompactFreshSegment( TIntrusivePtr<THullDs> &hullDs, std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx, - const TActorContext &ctx); + const TActorContext &ctx, + bool allowGarbageCollection); template <class TKey, class TMemRec> bool CompactFreshSegmentIfRequired( TIntrusivePtr<THullDs> &hullDs, std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx, const TActorContext &ctx, - bool force = false) + bool force, + bool allowGarbageCollection) { ui64 yardFreeUpToLsn = rtCtx->GetFreeUpToLsn(); bool compact = hullDs->HullCtx->FreshCompaction && rtCtx->LevelIndex->NeedsFreshCompaction(yardFreeUpToLsn, force); if (compact) { - CompactFreshSegment<TKey, TMemRec>(hullDs, rtCtx, ctx); + CompactFreshSegment<TKey, TMemRec>(hullDs, rtCtx, ctx, allowGarbageCollection); } return compact; } diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h index f736ae54c73..8ab580a316d 100644 --- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h +++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h @@ -329,7 +329,8 @@ namespace NKikimr { ui64 firstLsn, ui64 lastLsn, TDuration restoreDeadline, - std::optional<TKey> partitionKey) + std::optional<TKey> partitionKey, + bool allowGarbageCollection) : TActorBootstrapped<TThis>() , HullCtx(std::move(hullCtx)) , PDiskCtx(rtCtx->PDiskCtx) @@ -340,7 +341,7 @@ namespace NKikimr { , LevelSnap(std::move(levelSnap)) , Hmp(CreateHandoffMap<TKey, TMemRec>(HullCtx, rtCtx->HandoffDelegate, rtCtx->RunHandoff, rtCtx->SkeletonId)) - , Gcmp(CreateGcMap<TKey, TMemRec>(HullCtx, mergeElementsApproximation)) + , Gcmp(CreateGcMap<TKey, TMemRec>(HullCtx, mergeElementsApproximation, allowGarbageCollection)) , It(it) , Worker(HullCtx, PDiskCtx, rtCtx->LevelIndex, it, (bool)FreshSegment, firstLsn, lastLsn, restoreDeadline, partitionKey) diff --git a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h index 05901ef275c..70fb6c557b6 100644 --- a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h +++ b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h @@ -221,22 +221,8 @@ namespace NKikimr { }; struct TFakeFilter { - template <class T> - bool Check(const T &) const { - return true; - } - template <class T1, class T2> - bool Check(const T1&, const T2&) const { - return true; - } - template <class T1, class T2> - bool Check(const T1&, const T2&, bool) const { - return true; - } - template <class T1, class T2, class T3> - bool Check(const T1&, const T2&, const T3&, bool) const { - return true; - } + template<typename... T> + bool Check(T&&...) const { return true; } }; } // NKikimr diff --git a/ydb/core/blobstorage/vdisk/query/query_extr.cpp b/ydb/core/blobstorage/vdisk/query/query_extr.cpp index b17d1ea2917..36bfd3aa757 100644 --- a/ydb/core/blobstorage/vdisk/query/query_extr.cpp +++ b/ydb/core/blobstorage/vdisk/query/query_extr.cpp @@ -67,7 +67,7 @@ namespace NKikimr { template<typename TMerger> bool IsBlobDeleted(const TLogoBlobID &id, const TMerger &merger) { const auto &status = BarriersEssence->Keep(id, merger.GetMemRec(), merger.GetMemRecsMerged(), - QueryCtx->HullCtx->AllowKeepFlags); + QueryCtx->HullCtx->AllowKeepFlags, true /*allowGarbageCollection*/); return !status.KeepData; } diff --git a/ydb/core/blobstorage/vdisk/query/query_range.cpp b/ydb/core/blobstorage/vdisk/query/query_range.cpp index 2abfc5e2f3c..c2b76170fa6 100644 --- a/ydb/core/blobstorage/vdisk/query/query_range.cpp +++ b/ydb/core/blobstorage/vdisk/query/query_range.cpp @@ -123,7 +123,7 @@ namespace NKikimr { template<typename TMerger> void AddIndexOnly(const TLogoBlobID &logoBlobId, const TMerger &merger) { const auto &status = BarriersEssence->Keep(logoBlobId, merger.GetMemRec(), merger.GetMemRecsMerged(), - QueryCtx->HullCtx->AllowKeepFlags); + QueryCtx->HullCtx->AllowKeepFlags, true /*allowGarbageCollection*/); if (status.KeepData) { const TIngress &ingress = merger.GetMemRec().GetIngress(); ui64 ingr = ingress.Raw(); diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp index 9126809f397..3b62698b6a8 100644 --- a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp +++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp @@ -122,7 +122,8 @@ namespace NKikimr { const TIngress ingress = memRec.GetIngress(); const auto parts = ingress.PartsWeMustHaveLocally(&topology, ReplCtx->VCtx->ShortSelfVDisk, StartKey) - ingress.LocalParts(topology.GType); - if (!parts.Empty() && barriers->Keep(StartKey, memRec, it.GetMemRecsMerged(), allowKeepFlags).KeepData) { + if (!parts.Empty() && barriers->Keep(StartKey, memRec, it.GetMemRecsMerged(), allowKeepFlags, + true /*allowGarbageCollection*/).KeepData) { ++ReplInfo->ItemsTotal; ReplInfo->WorkUnitsTotal += StartKey.BlobSize(); } @@ -160,7 +161,8 @@ namespace NKikimr { return; // nothing to recover } - const NGc::TKeepStatus status = barriers.Keep(key, it.GetMemRec(), it.GetMemRecsMerged(), allowKeepFlags); + const NGc::TKeepStatus status = barriers.Keep(key, it.GetMemRec(), it.GetMemRecsMerged(), allowKeepFlags, + true /*allowGarbageCollection*/); if (!status.KeepData) { return; // no need to recover } diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp index bdbb432708a..9f3204446cc 100644 --- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp +++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp @@ -39,7 +39,7 @@ namespace NKikimr { iter.PutToMerger(&indexMerger); indexMerger.Finish(); auto status = essence->Keep(iter.GetCurKey(), indexMerger.GetMemRec(), indexMerger.GetMemRecsMerged(), - Snap->HullCtx->AllowKeepFlags); + Snap->HullCtx->AllowKeepFlags, true /*allowGarbageCollection*/); indexMerger.Clear(); const TLogoBlobID& id = iter.GetCurKey().LogoBlobID(); diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h index 62326c48975..a86b27731ea 100644 --- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h +++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h @@ -103,7 +103,8 @@ namespace NKikimr { Merger.Finish(); // obtain keep status - NGc::TKeepStatus status = Essence->Keep(id, Merger.GetMemRec(), Merger.GetMemRecsMerged(), AllowKeepFlags); + NGc::TKeepStatus status = Essence->Keep(id, Merger.GetMemRec(), Merger.GetMemRecsMerged(), AllowKeepFlags, + true /*allowGarbageCollection*/); // clear merger for next operation Merger.Clear(); diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp index 56450931cd6..4d08aec6172 100644 --- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp +++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp @@ -174,7 +174,8 @@ namespace NKikimr { if (iter.Seek(id); iter.Valid() && iter.GetCurKey().LogoBlobID() == id) { iter.PutToMerger(&merger); merger.Finish(); - keepData = barriers.Keep(id, merger.GetMemRec(), merger.GetMemRecsMerged(), snap.HullCtx->AllowKeepFlags).KeepData; + keepData = barriers.Keep(id, merger.GetMemRec(), merger.GetMemRecsMerged(), snap.HullCtx->AllowKeepFlags, + true /*allowGarbageCollection*/).KeepData; merger.Clear(); } diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp index 33b486f412c..216f54f4135 100644 --- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp +++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp @@ -1703,6 +1703,7 @@ namespace NKikimr { HugeBlobCtx, Db->GetVDiskIncarnationGuid()); ctx.Send(*SkeletonFrontIDPtr, msg.release()); + Hull->PermitGarbageCollection(ctx); // propagate status to Node Warden unless replication is on -- in that case it sets the status itself if (!runRepl) { ReplDone = true; diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp index 47142e93872..1f70e87da7d 100644 --- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp +++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp @@ -21,9 +21,10 @@ namespace NKikimr { bool Check(const TKeyLogoBlob &key, const TMemRecLogoBlob &memRec, ui32 recsMerged, - bool allowKeepFlags) const { + bool allowKeepFlags, + bool allowGarbageCollection) const { return TLogoBlobFilter::Check(key.LogoBlobID()) && - BarriersEssence->Keep(key, memRec, recsMerged, allowKeepFlags).KeepData; + BarriersEssence->Keep(key, memRec, recsMerged, allowKeepFlags, allowGarbageCollection).KeepData; } TIntrusivePtr<THullCtx> HullCtx; @@ -150,7 +151,7 @@ namespace NKikimr { // copy data until we have some space while (it.Valid() && (data->size() + NSyncLog::MaxRecFullSize <= data->capacity())) { key = it.GetCurKey(); - if (filter.Check(key, it.GetMemRec(), it.GetMemRecsMerged(), HullCtx->AllowKeepFlags)) + if (filter.Check(key, it.GetMemRec(), it.GetMemRecsMerged(), HullCtx->AllowKeepFlags, true /*allowGarbageCollection*/)) Serialize(ctx, data, key, it.GetMemRec()); it.Next(); } |