Skip to content

Commit 30de5db

Browse files
vitalifazevaykin
authored andcommitted
Fix vector_index_build reboots test (#18900) (#18953)
1 parent d7117e4 commit 30de5db

File tree

7 files changed

+61
-115
lines changed

7 files changed

+61
-115
lines changed

ydb/core/tx/schemeshard/ut_helpers/helpers.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2627,4 +2627,31 @@ namespace NSchemeShardUT_Private {
26272627

26282628
return result;
26292629
}
2630+
2631+
void WriteVectorTableRows(TTestActorRuntime& runtime, ui64 schemeShardId, ui64 txId, const TString & tablePath, bool withValue, ui32 shard, ui32 min, ui32 max) {
2632+
TVector<TCell> cells;
2633+
ui8 str[6] = { 0 };
2634+
str[4] = (ui8)Ydb::Table::VectorIndexSettings::VECTOR_TYPE_UINT8;
2635+
for (ui32 key = min; key < max; ++key) {
2636+
str[0] = ((key+106)* 7) % 256;
2637+
str[1] = ((key+106)*17) % 256;
2638+
str[2] = ((key+106)*37) % 256;
2639+
str[3] = ((key+106)*47) % 256;
2640+
cells.emplace_back(TCell::Make(key));
2641+
cells.emplace_back(TCell((const char*)str, 5));
2642+
if (withValue) {
2643+
// optionally use the same value for an additional covered string column
2644+
cells.emplace_back(TCell((const char*)str, 5));
2645+
}
2646+
}
2647+
std::vector<ui32> columnIds{1, 2};
2648+
if (withValue) {
2649+
columnIds.push_back(3);
2650+
}
2651+
TSerializedCellMatrix matrix(cells, max-min, withValue ? 3 : 2);
2652+
WriteOp(runtime, schemeShardId, txId, tablePath,
2653+
shard, NKikimrDataEvents::TEvWrite::TOperation::OPERATION_UPSERT,
2654+
columnIds, std::move(matrix), true);
2655+
};
2656+
26302657
}

ydb/core/tx/schemeshard/ut_helpers/helpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,5 +653,7 @@ namespace NSchemeShardUT_Private {
653653
NKikimrMiniKQL::TResult ReadTable(TTestActorRuntime& runtime, ui64 tabletId,
654654
const TString& table, const TVector<TString>& pk, const TVector<TString>& columns, const TString& rangeFlags = "");
655655

656+
void WriteVectorTableRows(TTestActorRuntime& runtime, ui64 schemeShardId, ui64 txId, const TString & tablePath,
657+
bool withValue, ui32 shard, ui32 min, ui32 max);
656658

657659
} //NSchemeShardUT_Private

ydb/core/tx/schemeshard/ut_helpers/test_env.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,9 @@ bool NSchemeShardUT_Private::TTestWithReboots::PassUserRequests(TTestActorRuntim
11731173
event->Type == TEvIndexBuilder::EvCreateRequest ||
11741174
event->Type == TEvIndexBuilder::EvGetRequest ||
11751175
event->Type == TEvIndexBuilder::EvCancelRequest ||
1176-
event->Type == TEvIndexBuilder::EvForgetRequest
1176+
event->Type == TEvIndexBuilder::EvForgetRequest ||
1177+
// without it, ut_vector_index_build_reboots test hangs on GetRequest on the very first reboot
1178+
event->Type == TEvTablet::EvCommitResult
11771179
;
11781180
}
11791181

ydb/core/tx/schemeshard/ut_helpers/test_env.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ namespace NSchemeShardUT_Private {
154154

155155
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156156
// A wrapper to run test scenarios with reboots of schemeshard, hive and coordinator
157+
// The idea is to run the same test scenario multiple times and on each run restart a tablet **once**
158+
// on receiving a non-filtered event. A given tablet is restarted when it receives an event for which
159+
// PassUserRequests() doesn't return true. On the first run, it is restarted on the first such event,
160+
// on the second run - on the second event and so on.
157161
class TTestWithReboots {
158162
protected:
159163
struct TDatashardLogBatchingSwitch {

ydb/core/tx/schemeshard/ut_helpers/test_with_reboots.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ namespace NSchemeShardUT_Private {
66

77
class TTestWithTabletReboots: public TTestWithReboots {
88
public:
9+
explicit TTestWithTabletReboots(bool killOnCommit = false)
10+
: TTestWithReboots(killOnCommit)
11+
{}
912
void Run(std::function<void(TTestActorRuntime& runtime, bool& activeZone)> testScenario) {
1013
TDatashardLogBatchingSwitch logBatchingSwitch(false /* without batching */);
1114
RunWithTabletReboots(testScenario);
@@ -14,6 +17,9 @@ class TTestWithTabletReboots: public TTestWithReboots {
1417

1518
class TTestWithPipeResets: public TTestWithReboots {
1619
public:
20+
explicit TTestWithPipeResets(bool killOnCommit = false)
21+
: TTestWithReboots(killOnCommit)
22+
{}
1723
void Run(std::function<void(TTestActorRuntime& runtime, bool& activeZone)> testScenario) {
1824
TDatashardLogBatchingSwitch logBatchingSwitch(false /* without batching */);
1925
RunWithPipeResets(testScenario);

ydb/core/tx/schemeshard/ut_index_build/ut_vector_index_build.cpp

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -90,27 +90,9 @@ Y_UNIT_TEST_SUITE (VectorIndexBuildTest) {
9090
env.TestWaitNotification(runtime, txId, tenantSchemeShard);
9191

9292
// Write data directly into shards
93-
auto fillRows = [&](const TString & tablePath, ui32 shard, ui32 min, ui32 max) {
94-
TVector<TCell> cells;
95-
ui8 str[6] = { 0 };
96-
str[4] = (ui8)Ydb::Table::VectorIndexSettings::VECTOR_TYPE_UINT8;
97-
for (ui32 key = min; key < max; ++key) {
98-
str[0] = ((key+106)* 7) % 256;
99-
str[1] = ((key+106)*17) % 256;
100-
str[2] = ((key+106)*37) % 256;
101-
str[3] = ((key+106)*47) % 256;
102-
cells.emplace_back(TCell::Make(key));
103-
cells.emplace_back(TCell((const char*)str, 5));
104-
}
105-
std::vector<ui32> columnIds{1, 2};
106-
TSerializedCellMatrix matrix(cells, max-min, 2);
107-
WriteOp(runtime, tenantSchemeShard, ++txId, tablePath,
108-
shard, NKikimrDataEvents::TEvWrite::TOperation::OPERATION_UPSERT,
109-
columnIds, std::move(matrix), true);
110-
};
111-
fillRows("/MyRoot/ServerLessDB/Table", 0, 0, 50);
112-
fillRows("/MyRoot/ServerLessDB/Table", 1, 50, 150);
113-
fillRows("/MyRoot/ServerLessDB/Table", 2, 150, 200);
93+
WriteVectorTableRows(runtime, tenantSchemeShard, ++txId, "/MyRoot/ServerLessDB/Table", false, 0, 0, 50);
94+
WriteVectorTableRows(runtime, tenantSchemeShard, ++txId, "/MyRoot/ServerLessDB/Table", false, 1, 50, 150);
95+
WriteVectorTableRows(runtime, tenantSchemeShard, ++txId, "/MyRoot/ServerLessDB/Table", false, 2, 150, 200);
11496

11597
runtime.SetLogPriority(NKikimrServices::TX_DATASHARD, NLog::PRI_TRACE);
11698
runtime.SetLogPriority(NKikimrServices::BUILD_INDEX, NLog::PRI_TRACE);
@@ -293,7 +275,7 @@ Y_UNIT_TEST_SUITE (VectorIndexBuildTest) {
293275
)");
294276
env.TestWaitNotification(runtime, txId, tenantSchemeShard);
295277

296-
fillRows("/MyRoot/CommonDB/Table", 0, 100, 300);
278+
WriteVectorTableRows(runtime, tenantSchemeShard, ++txId, "/MyRoot/CommonDB/Table", false, 0, 100, 300);
297279

298280
TVector<TString> billRecords;
299281
observerHolder = runtime.AddObserver<NMetering::TEvMetering::TEvWriteMeteringJson>([&](NMetering::TEvMetering::TEvWriteMeteringJson::TPtr& event) {

ydb/core/tx/schemeshard/ut_vector_index_build_reboots/ut_vector_index_build_reboots.cpp

Lines changed: 15 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -8,107 +8,30 @@ using namespace NSchemeShard;
88
using namespace NSchemeShardUT_Private;
99

1010

11-
static void WriteRows(TTestActorRuntime& runtime, ui64 tabletId, ui32 key, ui32 index) {
12-
TString writeQuery = Sprintf(R"(
13-
(
14-
(let keyNull '( '('key (Null) ) ) )
15-
(let row0 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
16-
(let key0 '( '('key (Uint32 '%u ) ) ) )
17-
(let row0 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
18-
(let key1 '( '('key (Uint32 '%u ) ) ) )
19-
(let row1 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
20-
(let key2 '( '('key (Uint32 '%u ) ) ) )
21-
(let row2 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
22-
(let key3 '( '('key (Uint32 '%u ) ) ) )
23-
(let row3 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
24-
(let key4 '( '('key (Uint32 '%u ) ) ) )
25-
(let row4 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
26-
(let key5 '( '('key (Uint32 '%u ) ) ) )
27-
(let row5 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
28-
(let key6 '( '('key (Uint32 '%u ) ) ) )
29-
(let row6 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
30-
(let key7 '( '('key (Uint32 '%u ) ) ) )
31-
(let row7 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
32-
(let key8 '( '('key (Uint32 '%u ) ) ) )
33-
(let row8 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
34-
(let key9 '( '('key (Uint32 '%u ) ) ) )
35-
(let row9 '( '('embedding (String '%s ) ) '('value (String 'aaaa) ) ) )
36-
37-
(return (AsList
38-
(UpdateRow '__user__Table keyNull row0)
39-
(UpdateRow '__user__Table key0 row0)
40-
(UpdateRow '__user__Table key1 row1)
41-
(UpdateRow '__user__Table key2 row2)
42-
(UpdateRow '__user__Table key3 row3)
43-
(UpdateRow '__user__Table key4 row4)
44-
(UpdateRow '__user__Table key5 row5)
45-
(UpdateRow '__user__Table key6 row6)
46-
(UpdateRow '__user__Table key7 row7)
47-
(UpdateRow '__user__Table key8 row8)
48-
(UpdateRow '__user__Table key9 row9)
49-
)
50-
)
51-
)
52-
)",
53-
std::to_string(1000*index + 0).c_str(),
54-
1000*key + 0, std::to_string(1000*index + 0).c_str(),
55-
1000*key + 1, std::to_string(1000*index + 1).c_str(),
56-
1000*key + 2, std::to_string(1000*index + 2).c_str(),
57-
1000*key + 3, std::to_string(1000*index + 3).c_str(),
58-
1000*key + 4, std::to_string(1000*index + 4).c_str(),
59-
1000*key + 5, std::to_string(1000*index + 5).c_str(),
60-
1000*key + 6, std::to_string(1000*index + 6).c_str(),
61-
1000*key + 7, std::to_string(1000*index + 7).c_str(),
62-
1000*key + 8, std::to_string(1000*index + 8).c_str(),
63-
1000*key + 9, std::to_string(1000*index + 9).c_str());
64-
65-
NKikimrMiniKQL::TResult result;
66-
TString err;
67-
NKikimrProto::EReplyStatus status = LocalMiniKQL(runtime, tabletId, writeQuery, result, err);
68-
UNIT_ASSERT_VALUES_EQUAL(err, "");
69-
UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::EReplyStatus::OK);;
70-
}
71-
7211
Y_UNIT_TEST_SUITE(VectorIndexBuildTestReboots) {
7312
Y_UNIT_TEST_WITH_REBOOTS(BaseCase) {
74-
T t;
13+
// Without killOnCommit, the schemeshard doesn't get rebooted on TEvDataShard::Ev***KMeansResponse's,
14+
// and thus the vector index build process is never interrupted at all because there are no other
15+
// events to reboot on.
16+
T t(true /*killOnCommit*/);
7517
t.Run([&](TTestActorRuntime& runtime, bool& activeZone) {
7618
{
7719
TInactiveZone inactive(activeZone);
7820

7921
TestCreateTable(runtime, ++t.TxId, "/MyRoot", R"(
80-
Name: "dir/Table"
81-
Columns { Name: "key" Type: "Uint32" }
82-
Columns { Name: "embedding" Type: "String" }
83-
Columns { Name: "value" Type: "String" }
84-
KeyColumnNames: ["key"]
85-
UniformPartitionsCount: 2
86-
)");
22+
Name: "dir/Table"
23+
Columns { Name: "key" Type: "Uint32" }
24+
Columns { Name: "embedding" Type: "String" }
25+
Columns { Name: "value" Type: "String" }
26+
KeyColumnNames: ["key"]
27+
SplitBoundary { KeyPrefix { Tuple { Optional { Uint32: 50 } } } }
28+
SplitBoundary { KeyPrefix { Tuple { Optional { Uint32: 150 } } } }
29+
)");
8730
t.TestEnv->TestWaitNotification(runtime, t.TxId);
8831

89-
for (ui32 delta = 0; delta < 2; ++delta) {
90-
WriteRows(runtime, TTestTxConfig::FakeHiveTablets, 1 + delta, 100 + delta);
91-
}
92-
93-
// Check src shard has the lead key as null
94-
{
95-
NKikimrMiniKQL::TResult result;
96-
TString err;
97-
ui32 status = LocalMiniKQL(runtime, TTestTxConfig::FakeHiveTablets, R"(
98-
(
99-
(let range '('('key (Null) (Void))))
100-
(let columns '('key 'embedding))
101-
(let result (SelectRange '__user__Table range columns '()))
102-
(return (AsList (SetResult 'Result result)))
103-
)
104-
)", result, err);
105-
106-
UNIT_ASSERT_VALUES_EQUAL_C(status, static_cast<ui32>(NKikimrProto::OK), err);
107-
UNIT_ASSERT_VALUES_EQUAL(err, "");
108-
109-
// V -- here the null key
110-
NKqp::CompareYson(R"([[[[[["101000"];#];[["100000"];["1000"]];[["100001"];["1001"]];[["100002"];["1002"]];[["100003"];["1003"]];[["100004"];["1004"]];[["100005"];["1005"]];[["100006"];["1006"]];[["100007"];["1007"]];[["100008"];["1008"]];[["100009"];["1009"]];[["101000"];["2000"]];[["101001"];["2001"]];[["101002"];["2002"]];[["101003"];["2003"]];[["101004"];["2004"]];[["101005"];["2005"]];[["101006"];["2006"]];[["101007"];["2007"]];[["101008"];["2008"]];[["101009"];["2009"]]];%false]]])", result);
111-
}
32+
WriteVectorTableRows(runtime, TTestTxConfig::SchemeShard, ++t.TxId, "/MyRoot/dir/Table", true, 0, 0, 50);
33+
WriteVectorTableRows(runtime, TTestTxConfig::SchemeShard, ++t.TxId, "/MyRoot/dir/Table", true, 1, 50, 150);
34+
WriteVectorTableRows(runtime, TTestTxConfig::SchemeShard, ++t.TxId, "/MyRoot/dir/Table", true, 2, 150, 200);
11235
}
11336

11437
AsyncBuildVectorIndex(runtime, ++t.TxId, TTestTxConfig::SchemeShard, "/MyRoot", "/MyRoot/dir/Table", "index1", "embedding", {"value"});

0 commit comments

Comments
 (0)