Skip to content

Commit 271c9f9

Browse files
authored
[stable-24-3] Request DataShard compaction if scheme has been changed (#11532)
1 parent dea009b commit 271c9f9

24 files changed

+503
-122
lines changed

ydb/core/protos/table_stats.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,8 @@ message TTableStats {
6666
repeated TChannelStats Channels = 30;
6767

6868
optional TStoragePoolsStats StoragePools = 31;
69+
70+
// denotes that datashard should be background compacted
71+
// even if it is single parted
72+
optional bool HasSchemaChanges = 33;
6973
}

ydb/core/tablet_flat/flat_comp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ namespace NTable {
165165
/**
166166
* Returns row schema of the specified table
167167
*/
168-
virtual TIntrusiveConstPtr<TRowScheme> RowScheme(ui32 table) = 0;
168+
virtual TIntrusiveConstPtr<TRowScheme> RowScheme(ui32 table) const = 0;
169169

170170
/**
171171
* Returns schema of the specified table

ydb/core/tablet_flat/flat_executor.cpp

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4303,7 +4303,7 @@ const NTable::TScheme& TExecutor::DatabaseScheme()
43034303
return Scheme();
43044304
}
43054305

4306-
TIntrusiveConstPtr<NTable::TRowScheme> TExecutor::RowScheme(ui32 table)
4306+
TIntrusiveConstPtr<NTable::TRowScheme> TExecutor::RowScheme(ui32 table) const
43074307
{
43084308
return Database->GetRowScheme(table);
43094309
}
@@ -4344,6 +4344,80 @@ const NTable::TRowVersionRanges& TExecutor::TableRemovedRowVersions(ui32 table)
43444344
return Database->GetRemovedRowVersions(table);
43454345
}
43464346

4347+
bool TExecutor::HasSchemaChanges(ui32 table) const {
4348+
auto *tableInfo = Scheme().GetTableInfo(table);
4349+
auto rowScheme = RowScheme(table);
4350+
if (!tableInfo || !rowScheme) {
4351+
return false;
4352+
}
4353+
4354+
auto subset = Database->Subset(table, NTable::TEpoch::Max(), { } , { });
4355+
for (const auto& partView : subset->Flatten) {
4356+
if (HasSchemaChanges(partView, *tableInfo, *rowScheme)) {
4357+
return true;
4358+
}
4359+
}
4360+
4361+
return false;
4362+
}
4363+
4364+
bool TExecutor::HasSchemaChanges(const NTable::TPartView& partView, const NTable::TScheme::TTableInfo& tableInfo, const NTable::TRowScheme& rowScheme) const {
4365+
if (partView.Part->Stat.Rows == 0) {
4366+
return false;
4367+
}
4368+
4369+
{ // Check by key filter existence
4370+
bool partByKeyFilter = bool(partView->ByKey);
4371+
bool schemeByKeyFilter = tableInfo.ByKeyFilter;
4372+
if (partByKeyFilter != schemeByKeyFilter) {
4373+
return true;
4374+
}
4375+
}
4376+
4377+
{ // Check B-Tree index existence
4378+
if (AppData()->FeatureFlags.GetEnableLocalDBBtreeIndex() && !partView->IndexPages.HasBTree()) {
4379+
return true;
4380+
}
4381+
}
4382+
4383+
{ // Check families
4384+
size_t partFamiliesCount = partView->GroupsCount;
4385+
size_t schemeFamiliesCount = rowScheme.Families.size();
4386+
if (partFamiliesCount != schemeFamiliesCount) {
4387+
return true;
4388+
}
4389+
4390+
for (size_t index : xrange(rowScheme.Families.size())) {
4391+
auto familyId = rowScheme.Families[index];
4392+
static const NTable::TScheme::TFamily defaultFamilySettings;
4393+
const auto& family = tableInfo.Families.ValueRef(familyId, defaultFamilySettings); // Workaround for KIKIMR-17222
4394+
4395+
const auto* schemeGroupRoom = tableInfo.Rooms.FindPtr(family.Room);
4396+
Y_ABORT_UNLESS(schemeGroupRoom, "Cannot find room %" PRIu32 " in table %" PRIu32, family.Room, tableInfo.Id);
4397+
4398+
ui32 partGroupChannel = partView.Part->GetGroupChannel(NTable::NPage::TGroupId(index));
4399+
if (partGroupChannel != schemeGroupRoom->Main) {
4400+
return true;
4401+
}
4402+
}
4403+
}
4404+
4405+
{ // Check columns
4406+
THashMap<NTable::TTag, ui32> partColumnGroups, schemeColumnGroups;
4407+
for (const auto& column : partView->Scheme->AllColumns) {
4408+
partColumnGroups[column.Tag] = column.Group;
4409+
}
4410+
for (const auto& col : rowScheme.Cols) {
4411+
schemeColumnGroups[col.Tag] = col.Group;
4412+
}
4413+
if (partColumnGroups != schemeColumnGroups) {
4414+
return true;
4415+
}
4416+
}
4417+
4418+
return false;
4419+
}
4420+
43474421
ui64 TExecutor::BeginCompaction(THolder<NTable::TCompactionParams> params)
43484422
{
43494423
if (auto logl = Logger->Log(ELnLev::Info))
@@ -4383,37 +4457,29 @@ ui64 TExecutor::BeginCompaction(THolder<NTable::TCompactionParams> params)
43834457

43844458
for (size_t group : xrange(rowScheme->Families.size())) {
43854459
auto familyId = rowScheme->Families[group];
4386-
const auto* family = tableInfo->Families.FindPtr(familyId);
4387-
if (Y_UNLIKELY(!family)) {
4388-
// FIXME: workaround for KIKIMR-17222
4389-
// Column families with default settings may be missing in schema,
4390-
// so we have to use a static variable as a substitute
4391-
static const NTable::TScheme::TFamily defaultFamilySettings;
4392-
family = &defaultFamilySettings;
4393-
}
4394-
Y_ABORT_UNLESS(family, "Cannot find family %" PRIu32 " in table %" PRIu32, familyId, table);
4460+
static const NTable::TScheme::TFamily defaultFamilySettings;
4461+
const auto& family = tableInfo->Families.ValueRef(familyId, defaultFamilySettings); // Workaround for KIKIMR-17222
43954462

4396-
auto roomId = family->Room;
4397-
auto* room = tableInfo->Rooms.FindPtr(roomId);
4398-
Y_ABORT_UNLESS(room, "Cannot find room %" PRIu32 " in table %" PRIu32, roomId, table);
4463+
auto* room = tableInfo->Rooms.FindPtr(family.Room);
4464+
Y_ABORT_UNLESS(room, "Cannot find room %" PRIu32 " in table %" PRIu32, family.Room, table);
43994465

44004466
auto& pageGroup = comp->Layout.Groups.at(group);
44014467
auto& writeGroup = comp->Writer.Groups.at(group);
44024468

4403-
pageGroup.Codec = family->Codec;
4469+
pageGroup.Codec = family.Codec;
44044470
pageGroup.PageSize = policy->MinDataPageSize;
44054471
pageGroup.BTreeIndexNodeTargetSize = policy->MinBTreeIndexNodeSize;
44064472
pageGroup.BTreeIndexNodeKeysMin = policy->MinBTreeIndexNodeKeys;
44074473

4408-
writeGroup.Cache = Max(family->Cache, cache);
4474+
writeGroup.Cache = Max(family.Cache, cache);
44094475
writeGroup.MaxBlobSize = NBlockIO::BlockSize;
44104476
writeGroup.Channel = room->Main;
44114477
addChannel(room->Main);
44124478

44134479
if (group == 0) {
44144480
// Small/Large edges are taken from the leader family
4415-
comp->Layout.SmallEdge = family->Small;
4416-
comp->Layout.LargeEdge = family->Large;
4481+
comp->Layout.SmallEdge = family.Small;
4482+
comp->Layout.LargeEdge = family.Large;
44174483

44184484
// Small/Large channels are taken from the leader family
44194485
comp->Writer.BlobsChannel = room->Blobs;

ydb/core/tablet_flat/flat_executor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ class TExecutor
590590

591591
ui64 OwnerTabletId() const override;
592592
const NTable::TScheme& DatabaseScheme() override;
593-
TIntrusiveConstPtr<NTable::TRowScheme> RowScheme(ui32 table) override;
593+
TIntrusiveConstPtr<NTable::TRowScheme> RowScheme(ui32 table) const override;
594594
const NTable::TScheme::TTableInfo* TableScheme(ui32 table) override;
595595
ui64 TableMemSize(ui32 table, NTable::TEpoch epoch) override;
596596
NTable::TPartView TablePart(ui32 table, const TLogoBlobID& label) override;
@@ -651,6 +651,8 @@ class TExecutor
651651
bool CancelScan(ui32 tableId, ui64 taskId) override;
652652

653653
TFinishedCompactionInfo GetFinishedCompactionInfo(ui32 tableId) const override;
654+
bool HasSchemaChanges(ui32 table) const override;
655+
bool HasSchemaChanges(const NTable::TPartView& partView, const NTable::TScheme::TTableInfo& tableInfo, const NTable::TRowScheme& rowScheme) const;
654656
ui64 CompactBorrowed(ui32 tableId) override;
655657
ui64 CompactMemTable(ui32 tableId) override;
656658
ui64 CompactTable(ui32 tableId) override;

ydb/core/tablet_flat/flat_stat_table.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ bool BuildStats(const TSubset& subset, TStats& stats, ui64 rowCountResolution, u
2323
}
2424

2525
void GetPartOwners(const TSubset& subset, THashSet<ui64>& partOwners) {
26-
for (auto& pi : subset.Flatten) {
27-
partOwners.insert(pi->Label.TabletID());
26+
for (const auto& partView : subset.Flatten) {
27+
partOwners.insert(partView->Label.TabletID());
2828
}
29-
for (auto& pi : subset.ColdParts) {
30-
partOwners.insert(pi->Label.TabletID());
29+
for (const auto& coldPart : subset.ColdParts) {
30+
partOwners.insert(coldPart->Label.TabletID());
3131
}
32-
for (auto& pi : subset.TxStatus) {
33-
partOwners.insert(pi->Label.TabletID());
32+
for (const auto& txStatus : subset.TxStatus) {
33+
partOwners.insert(txStatus->Label.TabletID());
3434
}
3535
}
3636

ydb/core/tablet_flat/flat_table.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,13 +1398,12 @@ bool TTable::RemoveRowVersions(const TRowVersion& lower, const TRowVersion& uppe
13981398

13991399
TCompactionStats TTable::GetCompactionStats() const
14001400
{
1401-
TCompactionStats stats;
1402-
stats.MemRowCount = GetMemRowCount();
1403-
stats.MemDataSize = GetMemSize();
1404-
stats.MemDataWaste = GetMemWaste();
1405-
stats.PartCount = Flatten.size() + ColdParts.size();
1406-
1407-
return stats;
1401+
return {
1402+
.PartCount = Flatten.size() + ColdParts.size(),
1403+
.MemRowCount = GetMemRowCount(),
1404+
.MemDataSize = GetMemSize(),
1405+
.MemDataWaste = GetMemWaste(),
1406+
};
14081407
}
14091408

14101409
void TTable::SetTableObserver(TIntrusivePtr<ITableObserver> ptr) noexcept

ydb/core/tablet_flat/tablet_flat_executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ namespace NFlatExecutorSetup {
578578

579579
// edge and ts of last full compaction
580580
virtual TFinishedCompactionInfo GetFinishedCompactionInfo(ui32 tableId) const = 0;
581+
virtual bool HasSchemaChanges(ui32 table) const = 0;
581582

582583
// Forces full compaction of the specified table in the near future
583584
// Returns 0 if can't compact, otherwise compaction ID

ydb/core/tablet_flat/ut/flat_comp_ut_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class TSimpleBackend : public ICompactionBackend {
4747
return DB.GetScheme();
4848
}
4949

50-
TIntrusiveConstPtr<NKikimr::NTable::TRowScheme> RowScheme(ui32 table) override {
50+
TIntrusiveConstPtr<NKikimr::NTable::TRowScheme> RowScheme(ui32 table) const override {
5151
return DB.GetRowScheme(table);
5252
}
5353

ydb/core/tx/datashard/datashard.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ TDataShard::TDataShard(const TActorId &tablet, TTabletStorageInfo *info)
139139
, MaxTxLagMilliseconds(5*60*1000, 0, 30*24*3600*1000ll)
140140
, CanCancelROWithReadSets(0, 0, 1)
141141
, PerShardReadSizeLimit(5368709120, 0, 107374182400)
142-
, CpuUsageReportThreshlodPercent(60, -1, 146)
142+
, CpuUsageReportThresholdPercent(60, -1, 146)
143143
, CpuUsageReportIntervalSeconds(60, 0, 365*86400)
144-
, HighDataSizeReportThreshlodBytes(10ull<<30, -1, Max<i64>())
144+
, HighDataSizeReportThresholdBytes(10ull<<30, -1, Max<i64>())
145145
, HighDataSizeReportIntervalSeconds(60, 0, 365*86400)
146146
, DataTxProfileLogThresholdMs(0, 0, 86400000)
147147
, DataTxProfileBufferThresholdMs(0, 0, 86400000)
@@ -305,9 +305,9 @@ void TDataShard::IcbRegister() {
305305

306306
appData->Icb->RegisterSharedControl(CanCancelROWithReadSets, "DataShardControls.CanCancelROWithReadSets");
307307
appData->Icb->RegisterSharedControl(PerShardReadSizeLimit, "TxLimitControls.PerShardReadSizeLimit");
308-
appData->Icb->RegisterSharedControl(CpuUsageReportThreshlodPercent, "DataShardControls.CpuUsageReportThreshlodPercent");
308+
appData->Icb->RegisterSharedControl(CpuUsageReportThresholdPercent, "DataShardControls.CpuUsageReportThreshlodPercent");
309309
appData->Icb->RegisterSharedControl(CpuUsageReportIntervalSeconds, "DataShardControls.CpuUsageReportIntervalSeconds");
310-
appData->Icb->RegisterSharedControl(HighDataSizeReportThreshlodBytes, "DataShardControls.HighDataSizeReportThreshlodBytes");
310+
appData->Icb->RegisterSharedControl(HighDataSizeReportThresholdBytes, "DataShardControls.HighDataSizeReportThreshlodBytes");
311311
appData->Icb->RegisterSharedControl(HighDataSizeReportIntervalSeconds, "DataShardControls.HighDataSizeReportIntervalSeconds");
312312

313313
appData->Icb->RegisterSharedControl(BackupReadAheadLo, "DataShardControls.BackupReadAheadLo");

ydb/core/tx/datashard/datashard__compaction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ class TDataShard::TTxCompactTable : public NTabletFlatExecutor::TTransactionBase
108108
auto stats = txc.DB.GetCompactionStats(localTid);
109109
bool isEmpty = stats.PartCount == 0 && stats.MemDataSize == 0;
110110
bool isSingleParted = stats.PartCount == 1 && stats.MemDataSize == 0;
111-
if (isEmpty || isSingleParted && !hasBorrowed && !record.HasCompactSinglePartedShards()) {
111+
bool hasSchemaChanges = Self->Executor()->HasSchemaChanges(tableInfo.LocalTid);
112+
if (isEmpty || isSingleParted && !hasBorrowed && !hasSchemaChanges && !record.GetCompactSinglePartedShards()) {
112113
// nothing to compact
113114
LOG_DEBUG_S(ctx, NKikimrServices::TX_DATASHARD,
114115
"Background compaction of tablet# " << Self->TabletID()

0 commit comments

Comments
 (0)