|
2 | 2 | #include "datashard_ut_common_kqp.h"
|
3 | 3 | #include "datashard_ut_read_table.h"
|
4 | 4 |
|
| 5 | +#include <ydb/library/actors/core/mon.h> |
| 6 | + |
5 | 7 | namespace NKikimr {
|
6 | 8 |
|
7 | 9 | using namespace NKikimr::NDataShard;
|
@@ -162,6 +164,100 @@ Y_UNIT_TEST_SUITE(DataShardFollowers) {
|
162 | 164 | }
|
163 | 165 | }
|
164 | 166 |
|
| 167 | + Y_UNIT_TEST(FollowerRebootAfterSysCompaction) { |
| 168 | + TPortManager pm; |
| 169 | + TServerSettings serverSettings(pm.GetPort(2134)); |
| 170 | + serverSettings.SetDomainName("Root") |
| 171 | + .SetUseRealThreads(false) |
| 172 | + .SetEnableForceFollowers(true); |
| 173 | + |
| 174 | + Tests::TServer::TPtr server = new TServer(serverSettings); |
| 175 | + auto &runtime = *server->GetRuntime(); |
| 176 | + auto sender = runtime.AllocateEdgeActor(); |
| 177 | + |
| 178 | + runtime.SetLogPriority(NKikimrServices::TX_DATASHARD, NLog::PRI_TRACE); |
| 179 | + runtime.SetLogPriority(NKikimrServices::TX_PROXY, NLog::PRI_DEBUG); |
| 180 | + |
| 181 | + InitRoot(server, sender); |
| 182 | + |
| 183 | + CreateShardedTable(server, sender, "/Root", "table-1", |
| 184 | + TShardedTableOptions() |
| 185 | + .Shards(2) |
| 186 | + .Followers(1)); |
| 187 | + |
| 188 | + const auto shards = GetTableShards(server, sender, "/Root/table-1"); |
| 189 | + UNIT_ASSERT_VALUES_EQUAL(shards.size(), 2u); |
| 190 | + |
| 191 | + ExecSQL(server, sender, "UPSERT INTO `/Root/table-1` (key, value) VALUES (1, 11), (2, 22), (3, 33);"); |
| 192 | + |
| 193 | + // Wait for leader to promote the follower read edge (and stop writing to the Sys table) |
| 194 | + Cerr << "... sleeping" << Endl; |
| 195 | + runtime.SimulateSleep(TDuration::Seconds(1)); |
| 196 | + |
| 197 | + UNIT_ASSERT_VALUES_EQUAL( |
| 198 | + KqpSimpleStaleRoExec(runtime, |
| 199 | + "SELECT key, value FROM `/Root/table-1` WHERE key >= 1 AND key <= 3", |
| 200 | + "/Root"), |
| 201 | + "{ items { uint32_value: 1 } items { uint32_value: 11 } }, " |
| 202 | + "{ items { uint32_value: 2 } items { uint32_value: 22 } }, " |
| 203 | + "{ items { uint32_value: 3 } items { uint32_value: 33 } }"); |
| 204 | + |
| 205 | + // Now we ask the leader to compact the Sys table |
| 206 | + { |
| 207 | + NActorsProto::TRemoteHttpInfo pb; |
| 208 | + pb.SetMethod(HTTP_METHOD_GET); |
| 209 | + pb.SetPath("/executorInternals"); |
| 210 | + auto* p1 = pb.AddQueryParams(); |
| 211 | + p1->SetKey("force_compaction"); |
| 212 | + p1->SetValue("1"); |
| 213 | + SendViaPipeCache(runtime, shards.at(0), sender, |
| 214 | + std::make_unique<NMon::TEvRemoteHttpInfo>(std::move(pb))); |
| 215 | + auto ev = runtime.GrabEdgeEventRethrow<NMon::TEvRemoteHttpInfoRes>(sender); |
| 216 | + UNIT_ASSERT_C( |
| 217 | + ev->Get()->Html.Contains("Table will be compacted in the near future"), |
| 218 | + ev->Get()->Html); |
| 219 | + } |
| 220 | + |
| 221 | + // Allow table to finish compaction |
| 222 | + Cerr << "... sleeping" << Endl; |
| 223 | + runtime.SimulateSleep(TDuration::Seconds(1)); |
| 224 | + |
| 225 | + // Reboot follower |
| 226 | + Cerr << "... killing follower" << Endl; |
| 227 | + SendViaPipeCache(runtime, shards.at(0), sender, |
| 228 | + std::make_unique<TEvents::TEvPoison>(), |
| 229 | + { .Follower = true }); |
| 230 | + |
| 231 | + // Allow it to boot properly |
| 232 | + Cerr << "... sleeping" << Endl; |
| 233 | + runtime.SimulateSleep(TDuration::Seconds(1)); |
| 234 | + |
| 235 | + // Read from follower must succeed |
| 236 | + Cerr << "... checking" << Endl; |
| 237 | + UNIT_ASSERT_VALUES_EQUAL( |
| 238 | + KqpSimpleStaleRoExec(runtime, |
| 239 | + "SELECT key, value FROM `/Root/table-1` WHERE key >= 1 AND key <= 3", |
| 240 | + "/Root"), |
| 241 | + "{ items { uint32_value: 1 } items { uint32_value: 11 } }, " |
| 242 | + "{ items { uint32_value: 2 } items { uint32_value: 22 } }, " |
| 243 | + "{ items { uint32_value: 3 } items { uint32_value: 33 } }"); |
| 244 | + |
| 245 | + // Update row values and sleep |
| 246 | + Cerr << "... updating rows" << Endl; |
| 247 | + ExecSQL(server, sender, "UPSERT INTO `/Root/table-1` (key, value) VALUES (1, 44), (2, 55), (3, 66);"); |
| 248 | + runtime.SimulateSleep(TDuration::Seconds(1)); |
| 249 | + |
| 250 | + // Read from follower must see updated values |
| 251 | + Cerr << "... checking" << Endl; |
| 252 | + UNIT_ASSERT_VALUES_EQUAL( |
| 253 | + KqpSimpleStaleRoExec(runtime, |
| 254 | + "SELECT key, value FROM `/Root/table-1` WHERE key >= 1 AND key <= 3", |
| 255 | + "/Root"), |
| 256 | + "{ items { uint32_value: 1 } items { uint32_value: 44 } }, " |
| 257 | + "{ items { uint32_value: 2 } items { uint32_value: 55 } }, " |
| 258 | + "{ items { uint32_value: 3 } items { uint32_value: 66 } }"); |
| 259 | + } |
| 260 | + |
165 | 261 | } // Y_UNIT_TEST_SUITE(DataShardFollowers)
|
166 | 262 |
|
167 | 263 | } // namespace NKikimr
|
0 commit comments