Skip to content

Commit 59fa9fb

Browse files
Accessors memory limit on background (#11816)
1 parent 0d8f95e commit 59fa9fb

File tree

9 files changed

+120
-37
lines changed

9 files changed

+120
-37
lines changed

ydb/core/tx/columnshard/columnshard__write.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ void TColumnShard::Handle(NEvents::TDataEvents::TEvWrite::TPtr& ev, const TActor
535535
return;
536536
}
537537

538-
auto schema = TablesManager.GetPrimaryIndex()->GetVersionedIndex().GetSchemaVerified(operation.GetTableId().GetSchemaVersion());
538+
auto schema = TablesManager.GetPrimaryIndex()->GetVersionedIndex().GetSchemaOptional(operation.GetTableId().GetSchemaVersion());
539539
if (!schema) {
540540
Counters.GetTabletCounters()->IncCounter(COUNTER_WRITE_FAIL);
541541
auto result = NEvents::TDataEvents::TEvWriteResult::BuildError(

ydb/core/tx/columnshard/columnshard_impl.cpp

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "blobs_action/transaction/tx_remove_blobs.h"
2222
#include "blobs_action/transaction/tx_gc_insert_table.h"
2323
#include "blobs_action/transaction/tx_gc_indexed.h"
24+
#include "blobs_reader/actor.h"
2425
#include "bg_tasks/events/events.h"
2526

2627
#include "data_accessor/manager.h"
@@ -579,8 +580,13 @@ class TChangesReadTask: public NOlap::NBlobOperations::NRead::ITask {
579580

580581
protected:
581582
virtual void DoOnDataReady(const std::shared_ptr<NOlap::NResourceBroker::NSubscribe::TResourcesGuard>& resourcesGuard) override {
583+
if (!!resourcesGuard) {
584+
AFL_VERIFY(!TxEvent->IndexChanges->ResourcesGuard);
585+
TxEvent->IndexChanges->ResourcesGuard = resourcesGuard;
586+
} else {
587+
AFL_VERIFY(TxEvent->IndexChanges->ResourcesGuard);
588+
}
582589
TxEvent->IndexChanges->Blobs = ExtractBlobsData();
583-
TxEvent->IndexChanges->ResourcesGuard = resourcesGuard;
584590
const bool isInsert = !!dynamic_pointer_cast<NOlap::TInsertColumnEngineChanges>(TxEvent->IndexChanges);
585591
std::shared_ptr<NConveyor::ITask> task = std::make_shared<TChangesTask>(std::move(TxEvent), Counters, TabletId, ParentActorId, LastCompletedTx);
586592
if (isInsert) {
@@ -615,6 +621,7 @@ class TDataAccessorsSubscriber: public NOlap::IDataAccessorRequestsSubscriber {
615621
const NActors::TActorId ShardActorId;
616622
std::shared_ptr<NOlap::TColumnEngineChanges> Changes;
617623
std::shared_ptr<NOlap::TVersionedIndex> VersionedIndex;
624+
std::shared_ptr<NOlap::NResourceBroker::NSubscribe::TResourcesGuard> ResourcesGuard;
618625

619626
virtual void DoOnRequestsFinishedImpl() = 0;
620627

@@ -624,6 +631,16 @@ class TDataAccessorsSubscriber: public NOlap::IDataAccessorRequestsSubscriber {
624631
}
625632

626633
public:
634+
void SetResourcesGuard(const std::shared_ptr<NOlap::NResourceBroker::NSubscribe::TResourcesGuard>& guard) {
635+
AFL_VERIFY(!ResourcesGuard);
636+
ResourcesGuard = guard;
637+
}
638+
639+
std::shared_ptr<NOlap::NResourceBroker::NSubscribe::TResourcesGuard>&& ExtractResourcesGuard() {
640+
AFL_VERIFY(ResourcesGuard);
641+
return std::move(ResourcesGuard);
642+
}
643+
627644
TDataAccessorsSubscriber(const NActors::TActorId& shardActorId, const std::shared_ptr<NOlap::TColumnEngineChanges>& changes,
628645
const std::shared_ptr<NOlap::TVersionedIndex>& versionedIndex)
629646
: ShardActorId(shardActorId)
@@ -801,6 +818,30 @@ void TColumnShard::SetupCompaction(const std::set<ui64>& pathIds) {
801818
}
802819
}
803820

821+
class TAccessorsMemorySubscriber: public NOlap::NResourceBroker::NSubscribe::ITask {
822+
private:
823+
using TBase = NOlap::NResourceBroker::NSubscribe::ITask;
824+
std::shared_ptr<NOlap::TDataAccessorsRequest> Request;
825+
std::shared_ptr<TDataAccessorsSubscriber> Subscriber;
826+
std::shared_ptr<NOlap::NDataAccessorControl::IDataAccessorsManager> DataAccessorsManager;
827+
828+
virtual void DoOnAllocationSuccess(const std::shared_ptr<NOlap::NResourceBroker::NSubscribe::TResourcesGuard>& guard) override {
829+
Subscriber->SetResourcesGuard(guard);
830+
Request->RegisterSubscriber(Subscriber);
831+
DataAccessorsManager->AskData(Request);
832+
}
833+
834+
public:
835+
TAccessorsMemorySubscriber(const ui64 memory, const TString& externalTaskId, const NOlap::NResourceBroker::NSubscribe::TTaskContext& context,
836+
std::shared_ptr<NOlap::TDataAccessorsRequest>&& request, const std::shared_ptr<TDataAccessorsSubscriber>& subscriber,
837+
const std::shared_ptr<NOlap::NDataAccessorControl::IDataAccessorsManager>& dataAccessorsManager)
838+
: TBase(0, memory, externalTaskId, context)
839+
, Request(std::move(request))
840+
, Subscriber(subscriber)
841+
, DataAccessorsManager(dataAccessorsManager) {
842+
}
843+
};
844+
804845
class TCompactionDataAccessorsSubscriber: public TDataAccessorsSubscriberWithRead {
805846
private:
806847
using TBase = TDataAccessorsSubscriberWithRead;
@@ -811,10 +852,9 @@ class TCompactionDataAccessorsSubscriber: public TDataAccessorsSubscriberWithRea
811852
AFL_DEBUG(NKikimrServices::TX_COLUMNSHARD)("event", "compaction")("external_task_id", externalTaskId);
812853

813854
auto ev = std::make_unique<TEvPrivate::TEvWriteIndex>(VersionedIndex, Changes, CacheDataAfterWrite);
814-
auto readSubscriber = std::make_shared<NOlap::NBlobOperations::NRead::ITask::TReadSubscriber>(
815-
std::make_shared<TCompactChangesReadTask>(std::move(ev), ShardActorId, ShardTabletId, Counters, SnapshotModification), 0,
816-
Changes->CalcMemoryForUsage(), externalTaskId, TaskSubscriptionContext);
817-
NOlap::NResourceBroker::NSubscribe::ITask::StartResourceSubscription(ResourceSubscribeActor, readSubscriber);
855+
ev->IndexChanges->ResourcesGuard = ExtractResourcesGuard();
856+
TActorContext::AsActorContext().Register(new NOlap::NBlobOperations::NRead::TActor(
857+
std::make_shared<TCompactChangesReadTask>(std::move(ev), ShardActorId, ShardTabletId, Counters, SnapshotModification)));
818858
}
819859

820860
public:
@@ -837,10 +877,14 @@ void TColumnShard::StartCompaction(const std::shared_ptr<NPrioritiesQueue::TAllo
837877

838878
auto actualIndexInfo = std::make_shared<NOlap::TVersionedIndex>(TablesManager.GetPrimaryIndex()->GetVersionedIndex());
839879
auto request = compaction->ExtractDataAccessorsRequest();
840-
request->RegisterSubscriber(std::make_shared<TCompactionDataAccessorsSubscriber>(ResourceSubscribeActor, indexChanges, actualIndexInfo,
880+
const ui64 accessorsMemory = request->PredictAccessorsMemory(TablesManager.GetPrimaryIndex()->GetVersionedIndex().GetLastSchema()) +
881+
indexChanges->CalcMemoryForUsage();
882+
const auto subscriber = std::make_shared<TCompactionDataAccessorsSubscriber>(ResourceSubscribeActor, indexChanges, actualIndexInfo,
841883
Settings.CacheDataAfterCompaction, SelfId(), TabletID(), Counters.GetCompactionCounters(), GetLastCompletedTx(),
842-
CompactTaskSubscription));
843-
TablesManager.GetPrimaryIndex()->FetchDataAccessors(request);
884+
CompactTaskSubscription);
885+
NOlap::NResourceBroker::NSubscribe::ITask::StartResourceSubscription(
886+
ResourceSubscribeActor, std::make_shared<TAccessorsMemorySubscriber>(accessorsMemory, indexChanges->GetTaskIdentifier(),
887+
CompactTaskSubscription, std::move(request), subscriber, DataAccessorsManager.GetObjectPtrVerified()));
844888
}
845889

846890
class TWriteEvictPortionsDataAccessorsSubscriber: public TDataAccessorsSubscriberWithRead {
@@ -851,11 +895,9 @@ class TWriteEvictPortionsDataAccessorsSubscriber: public TDataAccessorsSubscribe
851895
virtual void DoOnRequestsFinishedImpl() override {
852896
ACFL_DEBUG("background", "ttl")("need_writes", true);
853897
auto ev = std::make_unique<TEvPrivate::TEvWriteIndex>(VersionedIndex, Changes, false);
854-
auto readSubscriber = std::make_shared<NOlap::NBlobOperations::NRead::ITask::TReadSubscriber>(
855-
std::make_shared<TTTLChangesReadTask>(std::move(ev), ShardActorId, ShardTabletId, Counters, SnapshotModification), 0,
856-
Changes->CalcMemoryForUsage(), Changes->GetTaskIdentifier(), TaskSubscriptionContext);
857-
858-
NOlap::NResourceBroker::NSubscribe::ITask::StartResourceSubscription(ResourceSubscribeActor, readSubscriber);
898+
ev->IndexChanges->ResourcesGuard = ExtractResourcesGuard();
899+
TActorContext::AsActorContext().Register(new NOlap::NBlobOperations::NRead::TActor(
900+
std::make_shared<TTTLChangesReadTask>(std::move(ev), ShardActorId, ShardTabletId, Counters, SnapshotModification)));
859901
}
860902

861903
public:
@@ -911,7 +953,8 @@ void TColumnShard::SetupMetadata() {
911953
}
912954

913955
bool TColumnShard::SetupTtl(const THashMap<ui64, NOlap::TTiering>& pathTtls) {
914-
if (!AppDataVerified().ColumnShardConfig.GetTTLEnabled() || !NYDBTest::TControllers::GetColumnShardController()->IsBackgroundEnabled(NYDBTest::ICSController::EBackground::TTL)) {
956+
if (!AppDataVerified().ColumnShardConfig.GetTTLEnabled() ||
957+
!NYDBTest::TControllers::GetColumnShardController()->IsBackgroundEnabled(NYDBTest::ICSController::EBackground::TTL)) {
915958
AFL_WARN(NKikimrServices::TX_COLUMNSHARD)("event", "skip_ttl")("reason", "disabled");
916959
return false;
917960
}
@@ -922,7 +965,8 @@ bool TColumnShard::SetupTtl(const THashMap<ui64, NOlap::TTiering>& pathTtls) {
922965
}
923966

924967
const ui64 memoryUsageLimit = HasAppData() ? AppDataVerified().ColumnShardConfig.GetTieringsMemoryLimit() : ((ui64)512 * 1024 * 1024);
925-
std::vector<std::shared_ptr<NOlap::TTTLColumnEngineChanges>> indexChanges = TablesManager.MutablePrimaryIndex().StartTtl(eviction, DataLocksManager, memoryUsageLimit);
968+
std::vector<std::shared_ptr<NOlap::TTTLColumnEngineChanges>> indexChanges =
969+
TablesManager.MutablePrimaryIndex().StartTtl(eviction, DataLocksManager, memoryUsageLimit);
926970

927971
if (indexChanges.empty()) {
928972
ACFL_DEBUG("background", "ttl")("skip_reason", "no_changes");
@@ -933,14 +977,21 @@ bool TColumnShard::SetupTtl(const THashMap<ui64, NOlap::TTiering>& pathTtls) {
933977
for (auto&& i : indexChanges) {
934978
i->Start(*this);
935979
auto request = i->ExtractDataAccessorsRequest();
980+
ui64 memoryUsage = 0;
981+
std::shared_ptr<TDataAccessorsSubscriber> subscriber;
936982
if (i->NeedConstruction()) {
937-
request->RegisterSubscriber(std::make_shared<TWriteEvictPortionsDataAccessorsSubscriber>(ResourceSubscribeActor, i,
938-
actualIndexInfo, Settings.CacheDataAfterCompaction, SelfId(), TabletID(), Counters.GetEvictionCounters(), GetLastCompletedTx(),
939-
TTLTaskSubscription));
983+
subscriber = std::make_shared<TWriteEvictPortionsDataAccessorsSubscriber>(ResourceSubscribeActor, i, actualIndexInfo,
984+
Settings.CacheDataAfterCompaction, SelfId(), TabletID(), Counters.GetEvictionCounters(), GetLastCompletedTx(),
985+
TTLTaskSubscription);
986+
memoryUsage = i->CalcMemoryForUsage();
940987
} else {
941-
request->RegisterSubscriber(std::make_shared<TNoWriteEvictPortionsDataAccessorsSubscriber>(SelfId(), i, actualIndexInfo));
988+
subscriber = std::make_shared<TNoWriteEvictPortionsDataAccessorsSubscriber>(SelfId(), i, actualIndexInfo);
942989
}
943-
TablesManager.GetPrimaryIndex()->FetchDataAccessors(request);
990+
const ui64 accessorsMemory =
991+
request->PredictAccessorsMemory(TablesManager.GetPrimaryIndex()->GetVersionedIndex().GetLastSchema()) + memoryUsage;
992+
NOlap::NResourceBroker::NSubscribe::ITask::StartResourceSubscription(
993+
ResourceSubscribeActor, std::make_shared<TAccessorsMemorySubscriber>(accessorsMemory, i->GetTaskIdentifier(), TTLTaskSubscription,
994+
std::move(request), subscriber, DataAccessorsManager.GetObjectPtrVerified()));
944995
}
945996
return true;
946997
}
@@ -953,6 +1004,7 @@ class TCleanupPortionsDataAccessorsSubscriber: public TDataAccessorsSubscriber {
9531004
virtual void DoOnRequestsFinishedImpl() override {
9541005
AFL_DEBUG(NKikimrServices::TX_COLUMNSHARD)("background", "cleanup")("changes_info", Changes->DebugString());
9551006
auto ev = std::make_unique<TEvPrivate::TEvWriteIndex>(VersionedIndex, Changes, false);
1007+
ev->IndexChanges->ResourcesGuard = ExtractResourcesGuard();
9561008
ev->SetPutStatus(NKikimrProto::OK); // No new blobs to write
9571009
NActors::TActivationContext::Send(ShardActorId, std::move(ev));
9581010
}
@@ -982,8 +1034,12 @@ void TColumnShard::SetupCleanupPortions() {
9821034

9831035
auto request = changes->ExtractDataAccessorsRequest();
9841036
auto actualIndexInfo = std::make_shared<NOlap::TVersionedIndex>(TablesManager.GetPrimaryIndex()->GetVersionedIndex());
985-
request->RegisterSubscriber(std::make_shared<TCleanupPortionsDataAccessorsSubscriber>(SelfId(), changes, actualIndexInfo));
986-
TablesManager.GetPrimaryIndex()->FetchDataAccessors(request);
1037+
const ui64 accessorsMemory = request->PredictAccessorsMemory(TablesManager.GetPrimaryIndex()->GetVersionedIndex().GetLastSchema());
1038+
const auto subscriber = std::make_shared<TCleanupPortionsDataAccessorsSubscriber>(SelfId(), changes, actualIndexInfo);
1039+
1040+
NOlap::NResourceBroker::NSubscribe::ITask::StartResourceSubscription(
1041+
ResourceSubscribeActor, std::make_shared<TAccessorsMemorySubscriber>(accessorsMemory, changes->GetTaskIdentifier(), TTLTaskSubscription,
1042+
std::move(request), subscriber, DataAccessorsManager.GetObjectPtrVerified()));
9871043
}
9881044

9891045
void TColumnShard::SetupCleanupTables() {

ydb/core/tx/columnshard/data_accessor/request.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ class TDataAccessorsRequest: public NColumnShard::TMonitoringObjectsCounter<TDat
208208

209209
TDataAccessorsRequest() = default;
210210

211+
ui64 PredictAccessorsMemory(const ISnapshotSchema::TPtr& schema) const {
212+
ui64 result = 0;
213+
for (auto&& i : PathIdStatus) {
214+
for (auto&& [_, p] : i.second.GetPortions()) {
215+
result += p->PredictAccessorsMemory(schema);
216+
}
217+
}
218+
return result;
219+
}
220+
211221
bool HasSubscriber() const {
212222
return !!Subscriber;
213223
}

ydb/core/tx/columnshard/engines/portions/portion_info.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ class TPortionInfo {
100100
TPortionInfo(TPortionInfo&&) = default;
101101
TPortionInfo& operator=(TPortionInfo&&) = default;
102102

103+
ui32 PredictAccessorsMemory(const ISnapshotSchema::TPtr& schema) const {
104+
return (GetRecordsCount() / 10000 + 1) * sizeof(TColumnRecord) * schema->GetColumnsCount() + schema->GetIndexesCount() * sizeof(TIndexChunk);
105+
}
106+
103107
ui32 PredictMetadataMemorySize(const ui32 columnsCount) const {
104108
return (GetRecordsCount() / 10000 + 1) * sizeof(TColumnRecord) * columnsCount;
105109
}

ydb/core/tx/columnshard/engines/scheme/versions/abstract_scheme.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,4 +339,8 @@ TConclusion<TWritePortionInfoWithBlobsResult> ISnapshotSchema::PrepareForWrite(c
339339
return TWritePortionInfoWithBlobsResult(std::move(constructor));
340340
}
341341

342+
ui32 ISnapshotSchema::GetIndexesCount() const {
343+
return GetIndexInfo().GetIndexes().size();
344+
}
345+
342346
} // namespace NKikimr::NOlap

ydb/core/tx/columnshard/engines/scheme/versions/abstract_scheme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class ISnapshotSchema {
7070
virtual const TSnapshot& GetSnapshot() const = 0;
7171
virtual ui64 GetVersion() const = 0;
7272
virtual ui32 GetColumnsCount() const = 0;
73+
ui32 GetIndexesCount() const;
7374

7475
std::set<ui32> GetPkColumnsIds() const;
7576

ydb/core/tx/columnshard/engines/storage/actualizer/tiering/tiering.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,15 @@ void TTieringActualizer::DoAddPortion(const TPortionInfo& portion, const TAddExt
9191
if (MaxByPortionId.contains(portion.GetPortionId())) {
9292
AddPortionImpl(portion, addContext.GetNow());
9393
} else {
94-
NewPortionIds.emplace(portion.GetPortionId());
94+
auto schema = portion.GetSchema(VersionedIndex);
95+
if (*TieringColumnId == schema->GetIndexInfo().GetPKColumnIds().front()) {
96+
NYDBTest::TControllers::GetColumnShardController()->OnMaxValueUsage();
97+
auto max = NArrow::TStatusValidator::GetValid(portion.GetMeta().GetFirstLastPK().GetFirst().Column(0).GetScalar(0));
98+
AFL_VERIFY(MaxByPortionId.emplace(portion.GetPortionId(), max).second);
99+
AddPortionImpl(portion, addContext.GetNow());
100+
} else {
101+
NewPortionIds.emplace(portion.GetPortionId());
102+
}
95103
}
96104
}
97105

@@ -102,15 +110,12 @@ void TTieringActualizer::ActualizePortionInfo(const TPortionDataAccessor& access
102110
auto& portion = accessor.GetPortionInfo();
103111
if (Tiering) {
104112
std::shared_ptr<ISnapshotSchema> portionSchema = portion.GetSchema(VersionedIndex);
105-
auto indexMeta = portionSchema->GetIndexInfo().GetIndexMetaMax(*TieringColumnId);
106113
std::shared_ptr<arrow::Scalar> max;
107-
if (indexMeta) {
114+
AFL_VERIFY(*TieringColumnId != portionSchema->GetIndexInfo().GetPKColumnIds().front());
115+
if (auto indexMeta = portionSchema->GetIndexInfo().GetIndexMetaMax(*TieringColumnId)) {
108116
NYDBTest::TControllers::GetColumnShardController()->OnStatisticsUsage(NIndexes::TIndexMetaContainer(indexMeta));
109117
const std::vector<TString> data = accessor.GetIndexInplaceDataVerified(indexMeta->GetIndexId());
110118
max = indexMeta->GetMaxScalarVerified(data, portionSchema->GetIndexInfo().GetColumnFieldVerified(*TieringColumnId)->type());
111-
} else if (*TieringColumnId == portionSchema->GetIndexInfo().GetPKColumnIds().front()) {
112-
NYDBTest::TControllers::GetColumnShardController()->OnMaxValueUsage();
113-
max = NArrow::TStatusValidator::GetValid(portion.GetMeta().GetFirstLastPK().GetFirst().Column(0).GetScalar(0));
114119
}
115120
AFL_VERIFY(MaxByPortionId.emplace(portion.GetPortionId(), max).second);
116121
}

ydb/core/tx/columnshard/ut_schema/ut_columnshard_schema.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ void TestTtl(bool reboots, bool internal, TTestSchema::TTableSpecials spec = {},
339339
UNIT_ASSERT(CheckSame(rb, PORTION_ROWS, spec.TtlColumn, ts[0]));
340340
}
341341

342-
if (spec.NeedTestStatistics()) {
342+
if (spec.NeedTestStatistics() && spec.TtlColumn != "timestamp") {
343343
AFL_VERIFY(csControllerGuard->GetStatisticsUsageCount().Val());
344344
AFL_VERIFY(!csControllerGuard->GetMaxValueUsageCount().Val());
345345
} else {
@@ -706,13 +706,13 @@ std::vector<std::pair<ui32, ui64>> TestTiers(bool reboots, const std::vector<TSt
706706
}
707707
}
708708

709-
if (specs[0].NeedTestStatistics()) {
710-
AFL_VERIFY(csControllerGuard->GetStatisticsUsageCount().Val());
711-
AFL_VERIFY(!csControllerGuard->GetMaxValueUsageCount().Val());
712-
} else {
713-
AFL_VERIFY(!csControllerGuard->GetStatisticsUsageCount().Val());
714-
AFL_VERIFY(csControllerGuard->GetMaxValueUsageCount().Val());
715-
}
709+
// if (specs[0].NeedTestStatistics()) {
710+
// AFL_VERIFY(csControllerGuard->GetStatisticsUsageCount().Val());
711+
// AFL_VERIFY(!csControllerGuard->GetMaxValueUsageCount().Val());
712+
// } else {
713+
// AFL_VERIFY(!csControllerGuard->GetStatisticsUsageCount().Val());
714+
// AFL_VERIFY(csControllerGuard->GetMaxValueUsageCount().Val());
715+
// }
716716

717717
return specRowsBytes;
718718
}

ydb/core/tx/tiering/ut/ut_tiers.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ using namespace NColumnShard;
2929

3030
class TFastTTLCompactionController: public NKikimr::NYDBTest::ICSController {
3131
public:
32+
virtual bool CheckPortionForEvict(const NOlap::TPortionInfo& /*portion*/) const override {
33+
return true;
34+
}
3235
virtual bool NeedForceCompactionBacketsConstruction() const override {
3336
return true;
3437
}

0 commit comments

Comments
 (0)