Skip to content

Commit ada3760

Browse files
authored
Preload follower sys tables data and index roots (#5835)
1 parent 24736e9 commit ada3760

19 files changed

+689
-165
lines changed

ydb/core/tablet_flat/flat_boot_bundle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ namespace NBoot {
107107
void TryFinalize()
108108
{
109109
if (!LeftReads) {
110-
for (auto req : Loader->Run()) {
110+
for (auto req : Loader->Run(false)) {
111111
LeftReads += Logic->LoadPages(this, req);
112112
}
113113
}

ydb/core/tablet_flat/flat_dbase_sz_env.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace NTable {
3535
auto *partStore = CheckedCast<const NTable::TPartStore*>(part);
3636

3737
auto info = partStore->PageCollections.at(groupId.Index).Get();
38-
auto type = EPage(info->PageCollection->Page(pageId).Type);
38+
auto type = info->GetPageType(pageId);
3939

4040
switch (type) {
4141
case EPage::FlatIndex:
@@ -55,11 +55,11 @@ namespace NTable {
5555
}
5656

5757
private:
58-
void AddPageSize(TInfo *info, TPageId page) noexcept
58+
void AddPageSize(TInfo *info, TPageId pageId) noexcept
5959
{
60-
if (Touched[info].insert(page).second) {
60+
if (Touched[info].insert(pageId).second) {
6161
Pages++;
62-
Bytes += info->PageCollection->Page(page).Size;
62+
Bytes += info->GetPageSize(pageId);
6363
}
6464
}
6565

ydb/core/tablet_flat/flat_executor.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ bool TExecutor::PrepareExternalPart(TPendingPartSwitch &partSwitch, TPendingPart
11931193
}
11941194

11951195
if (auto* stage = bundle.GetStage<TPendingPartSwitch::TLoaderStage>()) {
1196-
if (auto fetch = stage->Loader.Run()) {
1196+
if (auto fetch = stage->Loader.Run(PreloadTablesData.contains(partSwitch.TableId))) {
11971197
Y_ABORT_UNLESS(fetch.size() == 1, "Cannot handle loads from more than one page collection");
11981198

11991199
for (auto req : fetch) {
@@ -1935,6 +1935,17 @@ void TExecutor::PostponeTransaction(TAutoPtr<TSeat> seat, TPageCollectionTxEnv &
19351935

19361936
const std::pair<ui32, ui64> toLoad = PrivatePageCache->Request(pages, pad, pageCollectionInfo);
19371937
if (toLoad.first) {
1938+
if (auto logl = Logger->Log(ELnLev::Dbg03)) {
1939+
logl
1940+
<< NFmt::Do(*this) << " requests PageCollection " << pageCollectionInfo->PageCollection->Label()
1941+
<< " " << toLoad.second << " bytes, " << toLoad.first << " pages: [";
1942+
for (auto i : xrange(pages.size())) {
1943+
if (i != 0) logl << ", ";
1944+
logl << pages[i] << " " << ui32(pageCollectionInfo->GetPageType(pages[i]));
1945+
}
1946+
logl << "]";
1947+
}
1948+
19381949
auto *req = new NPageCollection::TFetch(0, pageCollectionInfo->PageCollection, std::move(pages), pad->GetWaitingTraceId());
19391950

19401951
loadPages += toLoad.first;
@@ -3469,7 +3480,7 @@ void TExecutor::Handle(NOps::TEvResult *ops, TProdCompact *msg, bool cancelled)
34693480
const auto &newPart = result.Part;
34703481

34713482
TPageCollectionProtoHelper::Snap(snap, newPart, tableId, logicResult.Changes.NewPartsLevel);
3472-
TPageCollectionProtoHelper(true, true).Do(bySwitchAux->AddHotBundles(), newPart);
3483+
TPageCollectionProtoHelper(true, false).Do(bySwitchAux->AddHotBundles(), newPart);
34733484
}
34743485
}
34753486

@@ -4773,5 +4784,9 @@ void TExecutor::ApplyCompactionChanges(
47734784
}
47744785
}
47754786

4787+
void TExecutor::SetPreloadTablesData(THashSet<ui32> tables) {
4788+
PreloadTablesData = std::move(tables);
4789+
}
4790+
47764791
}
47774792
}

ydb/core/tablet_flat/flat_executor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ class TExecutor
362362
TAutoPtr<NUtil::ILogger> Logger;
363363

364364
ui32 FollowerId = 0;
365+
THashSet<ui32> PreloadTablesData;
365366

366367
// This becomes true when executor enables the use of leases, e.g. starts persisting them
367368
// This may become false again when leases are not actively used for some time
@@ -687,6 +688,8 @@ class TExecutor
687688

688689
void RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> appCounters) override;
689690

691+
virtual void SetPreloadTablesData(THashSet<ui32> tables) override;
692+
690693
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
691694
return NKikimrServices::TActivity::FLAT_EXECUTOR;
692695
}

ydb/core/tablet_flat/flat_executor_ut.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6264,7 +6264,7 @@ Y_UNIT_TEST_SUITE(TFlatTableExecutorBTreeIndex) {
62646264
// after restart we have no pages in private cache
62656265
env.SendSync(new NFake::TEvExecute{ new TTxFullScan(readRows, failedAttempts) }, true);
62666266
UNIT_ASSERT_VALUES_EQUAL(readRows, 1000);
6267-
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 332);
6267+
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 330);
62686268
}
62696269

62706270
Y_UNIT_TEST(EnableLocalDBBtreeIndex_True) { // uses b-tree index
@@ -6302,7 +6302,7 @@ Y_UNIT_TEST_SUITE(TFlatTableExecutorBTreeIndex) {
63026302
// after restart we have no pages in private cache
63036303
env.SendSync(new NFake::TEvExecute{ new TTxFullScan(readRows, failedAttempts) }, true);
63046304
UNIT_ASSERT_VALUES_EQUAL(readRows, 1000);
6305-
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 332);
6305+
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 330);
63066306
}
63076307

63086308
Y_UNIT_TEST(EnableLocalDBBtreeIndex_True_EnableLocalDBFlatIndex_False) { // uses b-tree index
@@ -6341,7 +6341,7 @@ Y_UNIT_TEST_SUITE(TFlatTableExecutorBTreeIndex) {
63416341
// after restart we have no pages in private cache
63426342
env.SendSync(new NFake::TEvExecute{ new TTxFullScan(readRows, failedAttempts) }, true);
63436343
UNIT_ASSERT_VALUES_EQUAL(readRows, 1000);
6344-
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 332);
6344+
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 330);
63456345
}
63466346

63476347
Y_UNIT_TEST(EnableLocalDBBtreeIndex_False_EnableLocalDBFlatIndex_False) { // uses flat index
@@ -6468,7 +6468,7 @@ Y_UNIT_TEST_SUITE(TFlatTableExecutorBTreeIndex) {
64686468
// after restart we have no pages in private cache
64696469
env.SendSync(new NFake::TEvExecute{ new TTxFullScan(readRows, failedAttempts) }, true);
64706470
UNIT_ASSERT_VALUES_EQUAL(readRows, 1000);
6471-
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 332);
6471+
UNIT_ASSERT_VALUES_EQUAL(failedAttempts, 330);
64726472
}
64736473

64746474
}

ydb/core/tablet_flat/flat_ops_compact.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ namespace NTabletFlatExecutor {
315315
{ },
316316
std::move(result.Overlay));
317317

318-
auto fetch = loader.Run();
318+
auto fetch = loader.Run(false);
319319

320320
Y_ABORT_UNLESS(!fetch, "Just compacted part needs to load some pages");
321321

ydb/core/tablet_flat/flat_part_keys.h

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,80 +3,10 @@
33
#include "flat_part_iface.h"
44
#include "flat_part_index_iter_iface.h"
55
#include "flat_part_slice.h"
6-
#include "flat_sausage_fetch.h"
7-
#include "flat_sausagecache.h"
86

97
namespace NKikimr {
108
namespace NTable {
119

12-
class TKeysEnv : public IPages {
13-
public:
14-
using TCache = NTabletFlatExecutor::TPrivatePageCache::TInfo;
15-
16-
TKeysEnv(const TPart *part, TIntrusivePtr<TCache> cache)
17-
: Part(part)
18-
, Cache(std::move(cache))
19-
{
20-
}
21-
22-
TResult Locate(const TMemTable*, ui64, ui32) noexcept override
23-
{
24-
Y_ABORT("IPages::Locate(TMemTable*, ...) shouldn't be used here");
25-
}
26-
27-
TResult Locate(const TPart*, ui64, ELargeObj) noexcept override
28-
{
29-
Y_ABORT("IPages::Locate(TPart*, ...) shouldn't be used here");
30-
}
31-
32-
const TSharedData* TryGetPage(const TPart* part, TPageId pageId, TGroupId groupId) override
33-
{
34-
Y_ABORT_UNLESS(part == Part, "Unsupported part");
35-
Y_ABORT_UNLESS(groupId.IsMain(), "Unsupported column group");
36-
37-
if (auto* extra = ExtraPages.FindPtr(pageId)) {
38-
return extra;
39-
} else if (auto* cached = Cache->Lookup(pageId)) {
40-
// Save page in case it's evicted on the next iteration
41-
ExtraPages[pageId] = *cached;
42-
return cached;
43-
} else {
44-
NeedPages.insert(pageId);
45-
return nullptr;
46-
}
47-
}
48-
49-
void Check(bool has) const noexcept
50-
{
51-
Y_ABORT_UNLESS(bool(NeedPages) == has, "Loader does not have some ne");
52-
}
53-
54-
TAutoPtr<NPageCollection::TFetch> GetFetches()
55-
{
56-
if (NeedPages) {
57-
TVector<TPageId> pages(NeedPages.begin(), NeedPages.end());
58-
std::sort(pages.begin(), pages.end());
59-
return new NPageCollection::TFetch{ 0, Cache->PageCollection, std::move(pages) };
60-
} else {
61-
return nullptr;
62-
}
63-
}
64-
65-
void Save(ui32 cookie, NSharedCache::TEvResult::TLoaded&& loaded) noexcept
66-
{
67-
if (cookie == 0 && NeedPages.erase(loaded.PageId)) {
68-
ExtraPages[loaded.PageId] = TPinnedPageRef(loaded.Page).GetData();
69-
Cache->Fill(std::move(loaded));
70-
}
71-
}
72-
73-
private:
74-
const TPart* Part;
75-
TIntrusivePtr<TCache> Cache;
76-
THashMap<TPageId, TSharedData> ExtraPages;
77-
THashSet<TPageId> NeedPages;
78-
};
79-
8010
class TKeysLoader {
8111
public:
8212
explicit TKeysLoader(const TPart* part, IPages* env)

ydb/core/tablet_flat/flat_part_loader.cpp

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ TLoader::TLoader(TVector<TIntrusivePtr<TCache>> pageCollections,
2323
if (Packs.size() < 1) {
2424
Y_Fail("Cannot load TPart from " << Packs.size() << " page collections");
2525
}
26+
LoaderEnv = MakeHolder<TLoaderEnv>(Packs[0]);
2627
}
2728

2829
TLoader::~TLoader() { }
@@ -153,25 +154,45 @@ TAutoPtr<NPageCollection::TFetch> TLoader::StageCreatePartView() noexcept
153154
Y_ABORT_UNLESS(!PartView, "PartView already initialized in CreatePartView stage");
154155
Y_ABORT_UNLESS(Packs && Packs.front());
155156

156-
TVector<TPageId> load;
157-
for (auto page: { SchemeId, GlobsId,
158-
SmallId, LargeId, ByKeyId,
159-
GarbageStatsId, TxIdStatsId }) {
160-
if (page != Max<TPageId>() && !Packs[0]->Lookup(page))
161-
load.push_back(page);
157+
auto getPage = [&](TPageId pageId) {
158+
return pageId == Max<TPageId>()
159+
? nullptr
160+
: LoaderEnv->TryGetPage(nullptr, pageId, {});
161+
};
162+
163+
if (BTreeGroupIndexes) {
164+
// Note: preload root nodes only because we don't want to have multiple restarts here
165+
for (const auto& meta : BTreeGroupIndexes) {
166+
if (meta.LevelCount) getPage(meta.GetPageId());
167+
}
168+
for (const auto& meta : BTreeHistoricIndexes) {
169+
if (meta.LevelCount) getPage(meta.GetPageId());
170+
}
171+
} else if (FlatGroupIndexes) {
172+
for (auto indexPageId : FlatGroupIndexes) {
173+
getPage(indexPageId);
174+
}
175+
for (auto indexPageId : FlatHistoricIndexes) {
176+
getPage(indexPageId);
177+
}
178+
}
179+
180+
for (auto pageId: { SchemeId, GlobsId, SmallId, LargeId, ByKeyId, GarbageStatsId, TxIdStatsId }) {
181+
Y_DEBUG_ABORT_UNLESS(pageId == Max<TPageId>() || NeedIn(Packs[0]->GetPageType(pageId)));
182+
getPage(pageId);
162183
}
163184

164-
if (load) {
165-
return new NPageCollection::TFetch{ 0, Packs[0]->PageCollection, std::move(load) };
185+
if (auto fetch = LoaderEnv->GetFetch()) {
186+
return fetch;
166187
}
167188

168-
auto *scheme = GetPage(SchemeId);
169-
auto *large = GetPage(LargeId);
170-
auto *small = GetPage(SmallId);
171-
auto *blobs = GetPage(GlobsId);
172-
auto *byKey = GetPage(ByKeyId);
173-
auto *garbageStats = GetPage(GarbageStatsId);
174-
auto *txIdStats = GetPage(TxIdStatsId);
189+
auto *scheme = getPage(SchemeId);
190+
auto *large = getPage(LargeId);
191+
auto *small = getPage(SmallId);
192+
auto *blobs = getPage(GlobsId);
193+
auto *byKey = getPage(ByKeyId);
194+
auto *garbageStats = getPage(GarbageStatsId);
195+
auto *txIdStats = getPage(TxIdStatsId);
175196

176197
if (scheme == nullptr) {
177198
Y_ABORT("Scheme page is not loaded");
@@ -198,7 +219,7 @@ TAutoPtr<NPageCollection::TFetch> TLoader::StageCreatePartView() noexcept
198219
// Note: although we also have flat index, it shouldn't be loaded; so let's not count it here
199220
} else {
200221
for (auto indexPage : FlatGroupIndexes) {
201-
indexesRawSize += GetPageSize(indexPage);
222+
indexesRawSize += Packs[0]->GetPageSize(indexPage);
202223
}
203224
}
204225

@@ -242,7 +263,7 @@ TAutoPtr<NPageCollection::TFetch> TLoader::StageCreatePartView() noexcept
242263

243264
PartView = { partStore, std::move(overlay.Screen), std::move(overlay.Slices) };
244265

245-
KeysEnv = new TKeysEnv(PartView.Part.Get(), TPartStore::Storages(PartView).at(0));
266+
LoaderEnv->ProvidePart(PartView.Part.Get());
246267

247268
return nullptr;
248269
}
@@ -256,17 +277,17 @@ TAutoPtr<NPageCollection::TFetch> TLoader::StageSliceBounds() noexcept
256277
return nullptr;
257278
}
258279

259-
KeysEnv->Check(false); /* ensure there is no pending pages to load */
280+
LoaderEnv->EnsureNoNeedPages();
260281

261-
TKeysLoader loader(PartView.Part.Get(), KeysEnv.Get());
282+
TKeysLoader loader(PartView.Part.Get(), LoaderEnv.Get());
262283

263284
if (auto run = loader.Do(PartView.Screen)) {
264-
KeysEnv->Check(false); /* On success there shouldn't be left loads */
285+
LoaderEnv->EnsureNoNeedPages(); /* On success there shouldn't be left loads */
265286
PartView.Slices = std::move(run);
266287
TOverlay{ PartView.Screen, PartView.Slices }.Validate();
267288

268289
return nullptr;
269-
} else if (auto fetches = KeysEnv->GetFetches()) {
290+
} else if (auto fetches = LoaderEnv->GetFetch()) {
270291
return fetches;
271292
} else {
272293
Y_ABORT("Screen keys loader stalled without result");
@@ -288,17 +309,28 @@ void TLoader::StageDeltas() noexcept
288309
}
289310
}
290311

291-
void TLoader::Save(ui64 cookie, TArrayRef<NSharedCache::TEvResult::TLoaded> blocks) noexcept
312+
TAutoPtr<NPageCollection::TFetch> TLoader::StagePreloadData() noexcept
313+
{
314+
auto partStore = PartView.As<TPartStore>();
315+
316+
// Note: preload works only for main group pages
317+
auto total = partStore->PageCollections[0]->Total();
318+
319+
TVector<TPageId> toLoad(::Reserve(total));
320+
for (TPageId pageId : xrange(total)) {
321+
LoaderEnv->TryGetPage(PartView.Part.Get(), pageId, {});
322+
}
323+
324+
return LoaderEnv->GetFetch();
325+
}
326+
327+
void TLoader::Save(ui64 cookie, TArrayRef<NSharedCache::TEvResult::TLoaded> loadedPages) noexcept
292328
{
293329
Y_ABORT_UNLESS(cookie == 0, "Only the leader pack is used on load");
294330

295-
if (Stage == EStage::PartView) {
296-
for (auto& loaded : blocks) {
297-
Packs[0]->Fill(std::move(loaded), true);
298-
}
299-
} else if (Stage == EStage::Slice) {
300-
for (auto& loaded : blocks) {
301-
KeysEnv->Save(cookie, std::move(loaded));
331+
if (Stage == EStage::PartView || Stage == EStage::Slice || Stage == EStage::PreloadData) {
332+
for (auto& loaded : loadedPages) {
333+
LoaderEnv->Save(cookie, std::move(loaded));
302334
}
303335
} else {
304336
Y_Fail("Unexpected pages save on stage " << int(Stage));

0 commit comments

Comments
 (0)