|
12 | 12 | #include <ydb/core/protos/counters_hive.pb.h>
|
13 | 13 | #include <ydb/core/protos/follower_group.pb.h>
|
14 | 14 | #include <ydb/core/protos/schemeshard/operations.pb.h>
|
| 15 | +#include <ydb/core/protos/tx_proxy.pb.h> |
15 | 16 | #include <ydb/core/mind/bscontroller/bsc.h>
|
16 | 17 | #include <ydb/core/mind/tenant_pool.h>
|
17 | 18 | #include <ydb/core/tablet_flat/tablet_flat_executed.h>
|
@@ -5876,6 +5877,119 @@ Y_UNIT_TEST_SUITE(THiveTest) {
|
5876 | 5877 | }
|
5877 | 5878 | }
|
5878 | 5879 |
|
| 5880 | + Y_UNIT_TEST(TestFollowerCompatability1) { |
| 5881 | + static constexpr ui32 NUM_NODES = 3; |
| 5882 | + TTestBasicRuntime runtime(NUM_NODES, NUM_NODES); // num nodes = num dcs |
| 5883 | + Setup(runtime, true); |
| 5884 | + TVector<ui64> tabletIds; |
| 5885 | + const ui64 hiveTablet = MakeDefaultHiveID(); |
| 5886 | + const ui64 testerTablet = MakeTabletID(false, 1); |
| 5887 | + CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive, 0); |
| 5888 | + { |
| 5889 | + TDispatchOptions options; |
| 5890 | + options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount()); |
| 5891 | + runtime.DispatchEvents(options); |
| 5892 | + } |
| 5893 | + TTabletTypes::EType tabletType = TTabletTypes::Dummy; |
| 5894 | + // RequireAllDataCenters = true, FollowerCountPerDataCenter = false |
| 5895 | + // This confguration is nonsensical, and followers are never created like that |
| 5896 | + // Yet, there might be some followers like that remaining from the olden pre-follower-groups days |
| 5897 | + THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS)); |
| 5898 | + ev->Record.SetObjectId(1); |
| 5899 | + auto* followerGroup = ev->Record.AddFollowerGroups(); |
| 5900 | + followerGroup->SetFollowerCount(NUM_NODES); |
| 5901 | + followerGroup->SetFollowerCountPerDataCenter(false); |
| 5902 | + followerGroup->SetRequireAllDataCenters(true); |
| 5903 | + ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true); |
| 5904 | + // restart everything |
| 5905 | + for (ui32 i = 0; i < NUM_NODES; ++i) { |
| 5906 | + SendKillLocal(runtime, i); |
| 5907 | + } |
| 5908 | + runtime.Register(CreateTabletKiller(hiveTablet)); |
| 5909 | + for (ui32 i = 0; i < NUM_NODES; ++i) { |
| 5910 | + CreateLocal(runtime, i); |
| 5911 | + } |
| 5912 | + { |
| 5913 | + TDispatchOptions options; |
| 5914 | + options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, runtime.GetNodeCount()); |
| 5915 | + runtime.DispatchEvents(options); |
| 5916 | + } |
| 5917 | + { |
| 5918 | + TDispatchOptions options; |
| 5919 | + options.FinalEvents.emplace_back(TEvLocal::EvTabletStatus, 3); |
| 5920 | + runtime.DispatchEvents(options, TDuration::Seconds(1)); |
| 5921 | + } |
| 5922 | + // test every node has a follower running |
| 5923 | + NTabletPipe::TClientConfig pipeConfig; |
| 5924 | + pipeConfig.ForceLocal = true; |
| 5925 | + pipeConfig.AllowFollower = true; |
| 5926 | + pipeConfig.ForceFollower = true; |
| 5927 | + for (ui32 node = 0; node < NUM_NODES; ++node) { |
| 5928 | + MakeSureTabletIsUp(runtime, tabletId, node, &pipeConfig); |
| 5929 | + } |
| 5930 | + } |
| 5931 | + |
| 5932 | + Y_UNIT_TEST(TestFollowerCompatability2) { |
| 5933 | + static constexpr ui32 NUM_NODES = 3; |
| 5934 | + TTestBasicRuntime runtime(NUM_NODES, NUM_NODES); // num nodes = num dcs |
| 5935 | + Setup(runtime, true); |
| 5936 | + TVector<ui64> tabletIds; |
| 5937 | + const ui64 hiveTablet = MakeDefaultHiveID(); |
| 5938 | + const ui64 testerTablet = MakeTabletID(false, 1); |
| 5939 | + const TActorId senderA = runtime.AllocateEdgeActor(0); |
| 5940 | + SendKillLocal(runtime, 0); // node 0 exists but does not run local - to simulate a case where a db does not have nodes in every dc |
| 5941 | + CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive, 0); |
| 5942 | + { |
| 5943 | + TDispatchOptions options; |
| 5944 | + options.FinalEvents.emplace_back(TEvLocal::EvSyncTablets, 2); |
| 5945 | + runtime.DispatchEvents(options); |
| 5946 | + } |
| 5947 | + TTabletTypes::EType tabletType = TTabletTypes::Dummy; |
| 5948 | + THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500, tabletType, BINDED_CHANNELS)); |
| 5949 | + ev->Record.SetObjectId(1); |
| 5950 | + auto* followerGroup = ev->Record.AddFollowerGroups(); |
| 5951 | + followerGroup->SetFollowerCount(1); |
| 5952 | + followerGroup->SetFollowerCountPerDataCenter(true); |
| 5953 | + followerGroup->SetRequireAllDataCenters(true); |
| 5954 | + ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true); |
| 5955 | + |
| 5956 | + // drop dc column from followers - to imitate that they were created on an older version |
| 5957 | + TStringBuilder program; |
| 5958 | + program << "((let result (AsList "; |
| 5959 | + for (unsigned i = 1; i < 3; ++i) { |
| 5960 | + program << "(UpdateRow 'TabletFollowerTablet '('('TabletID (Uint64 '" << tabletId <<")) '('FollowerID (Uint64 '" << i << "))) '('('DataCenter)))"; |
| 5961 | + } |
| 5962 | + program << ")) (return result))"; |
| 5963 | + auto mkql = std::make_unique<TEvTablet::TEvLocalMKQL>(); |
| 5964 | + mkql->Record.MutableProgram()->MutableProgram()->SetText(program); |
| 5965 | + runtime.SendToPipe(hiveTablet, senderA, mkql.release()); |
| 5966 | + { |
| 5967 | + TAutoPtr<IEventHandle> handle; |
| 5968 | + runtime.GrabEdgeEvent<TEvTablet::TEvLocalMKQLResponse>(handle); |
| 5969 | + } |
| 5970 | + |
| 5971 | + runtime.Register(CreateTabletKiller(hiveTablet)); |
| 5972 | + runtime.DispatchEvents({}, TDuration::MilliSeconds(50)); |
| 5973 | + |
| 5974 | + // There should be exactly 2 followers, with ids 1 and 2 |
| 5975 | + // (that is, there should not be a follower created for the dc that node 0 is in) |
| 5976 | + |
| 5977 | + THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>(); |
| 5978 | + request->Record.SetReturnFollowers(true); |
| 5979 | + runtime.SendToPipe(hiveTablet, senderA, request.Release()); |
| 5980 | + TAutoPtr<IEventHandle> handle; |
| 5981 | + TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle); |
| 5982 | + unsigned followers = 0; |
| 5983 | + for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) { |
| 5984 | + auto followerId = tablet.GetFollowerID(); |
| 5985 | + if (followerId > 0) { |
| 5986 | + UNIT_ASSERT_LE(followerId, 2); |
| 5987 | + ++followers; |
| 5988 | + } |
| 5989 | + } |
| 5990 | + UNIT_ASSERT_VALUES_EQUAL(followers, 2); |
| 5991 | + } |
| 5992 | + |
5879 | 5993 | Y_UNIT_TEST(TestCreateExternalTablet) {
|
5880 | 5994 | TTestBasicRuntime runtime(1, false);
|
5881 | 5995 | Setup(runtime, true);
|
|
0 commit comments