YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/integration-tests/tablet-split-itest-base.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#ifndef YB_INTEGRATION_TESTS_TABLET_SPLIT_ITEST_BASE_H
15
#define YB_INTEGRATION_TESTS_TABLET_SPLIT_ITEST_BASE_H
16
17
#include <chrono>
18
19
#include "yb/client/client_fwd.h"
20
#include "yb/client/txn-test-base.h"
21
22
#include "yb/docdb/docdb_fwd.h"
23
24
#include "yb/master/catalog_manager_if.h"
25
26
#include "yb/tablet/tablet_fwd.h"
27
28
#include "yb/tserver/tserver_fwd.h"
29
30
#include "yb/util/size_literals.h"
31
#include "yb/util/tsan_util.h"
32
33
namespace yb {
34
35
class TestWorkload;
36
37
namespace client {
38
39
class SnapshotTestUtil;
40
41
}
42
43
Result<size_t> SelectRowsCount(
44
    const client::YBSessionPtr& session, const client::TableHandle& table);
45
46
void DumpTableLocations(
47
    master::CatalogManagerIf* catalog_mgr, const client::YBTableName& table_name);
48
49
void DumpWorkloadStats(const TestWorkload& workload);
50
51
CHECKED_STATUS SplitTablet(master::CatalogManagerIf* catalog_mgr, const tablet::Tablet& tablet);
52
53
CHECKED_STATUS DoSplitTablet(master::CatalogManagerIf* catalog_mgr, const tablet::Tablet& tablet);
54
55
template <class MiniClusterType>
56
class TabletSplitITestBase : public client::TransactionTestBase<MiniClusterType> {
57
 protected:
58
  static constexpr std::chrono::duration<int64> kRpcTimeout =
59
      std::chrono::seconds(60) * kTimeMultiplier;
60
  static constexpr int kDefaultNumRows = 500;
61
  // We set small data block size, so we don't have to write much data to have multiple blocks.
62
  // We need multiple blocks to be able to detect split key (see BlockBasedTable::GetMiddleKey).
63
  static constexpr size_t kDbBlockSizeBytes = 2_KB;
64
 public:
65
  void SetUp() override;
66
67
  // Creates read request for tablet_id which reflects following query (see
68
  // client::KeyValueTableTest for schema and kXxx constants):
69
  // SELECT `kValueColumn` FROM `kTableName` WHERE `kKeyColumn` = `key`;
70
  // Uses YBConsistencyLevel::CONSISTENT_PREFIX as this is default for YQL clients.
71
  Result<tserver::ReadRequestPB> CreateReadRequest(const TabletId& tablet_id, int32_t key);
72
73
  // Creates write request for tablet_id which reflects following query (see
74
  // client::KeyValueTableTest for schema and kXxx constants):
75
  // INSERT INTO `kTableName`(`kValueColumn`) VALUES (`value`);
76
  tserver::WriteRequestPB CreateInsertRequest(
77
      const TabletId& tablet_id, int32_t key, int32_t value);
78
79
  // Writes `num_rows` rows into the specified table using `CreateInsertRequest`.
80
  // Returns a pair with min and max hash code written.
81
  Result<std::pair<docdb::DocKeyHash, docdb::DocKeyHash>> WriteRows(
82
      client::TableHandle* table, uint32_t num_rows, int32_t start_key, int32_t start_value);
83
84
  Result<std::pair<docdb::DocKeyHash, docdb::DocKeyHash>> WriteRows(
85
13
      client::TableHandle* table, uint32_t num_rows = 2000, int32_t start_key = 1) {
86
13
    return WriteRows(table, num_rows, start_key, start_key);
87
13
  }
Unexecuted instantiation: yb::TabletSplitITestBase<yb::MiniCluster>::WriteRows(yb::client::TableHandle*, unsigned int, int)
yb::TabletSplitITestBase<yb::ExternalMiniCluster>::WriteRows(yb::client::TableHandle*, unsigned int, int)
Line
Count
Source
85
13
      client::TableHandle* table, uint32_t num_rows = 2000, int32_t start_key = 1) {
86
13
    return WriteRows(table, num_rows, start_key, start_key);
87
13
  }
88
89
  Result<std::pair<docdb::DocKeyHash, docdb::DocKeyHash>> WriteRows(
90
13
      uint32_t num_rows = 2000, int32_t start_key = 1) {
91
13
    return WriteRows(&this->table_, num_rows, start_key);
92
13
  }
Unexecuted instantiation: yb::TabletSplitITestBase<yb::MiniCluster>::WriteRows(unsigned int, int)
yb::TabletSplitITestBase<yb::ExternalMiniCluster>::WriteRows(unsigned int, int)
Line
Count
Source
90
13
      uint32_t num_rows = 2000, int32_t start_key = 1) {
91
13
    return WriteRows(&this->table_, num_rows, start_key);
92
13
  }
93
94
  CHECKED_STATUS FlushTestTable();
95
96
  Result<std::pair<docdb::DocKeyHash, docdb::DocKeyHash>> WriteRowsAndFlush(
97
      uint32_t num_rows = kDefaultNumRows, int32_t start_key = 1);
98
99
  Result<docdb::DocKeyHash> WriteRowsAndGetMiddleHashCode(uint32_t num_rows);
100
101
  Result<scoped_refptr<master::TabletInfo>> GetSingleTestTabletInfo(
102
      master::CatalogManagerIf* catalog_manager);
103
104
8
  void CreateSingleTablet() {
105
8
    this->SetNumTablets(1);
106
8
    this->CreateTable();
107
8
  }
Unexecuted instantiation: yb::TabletSplitITestBase<yb::MiniCluster>::CreateSingleTablet()
yb::TabletSplitITestBase<yb::ExternalMiniCluster>::CreateSingleTablet()
Line
Count
Source
104
8
  void CreateSingleTablet() {
105
8
    this->SetNumTablets(1);
106
8
    this->CreateTable();
107
8
  }
108
109
0
  CHECKED_STATUS CheckRowsCount(size_t expected_num_rows) {
110
0
    auto rows_count = VERIFY_RESULT(SelectRowsCount(this->NewSession(), this->table_));
111
0
    SCHECK_EQ(rows_count, expected_num_rows, InternalError, "Got unexpected rows count");
112
0
    return Status::OK();
113
0
  }
Unexecuted instantiation: yb::TabletSplitITestBase<yb::MiniCluster>::CheckRowsCount(unsigned long)
Unexecuted instantiation: yb::TabletSplitITestBase<yb::ExternalMiniCluster>::CheckRowsCount(unsigned long)
114
115
0
  Result<TableId> GetTestTableId() {
116
0
    return GetTableId(this->client_.get(), client::kTableName);
117
0
  }
Unexecuted instantiation: yb::TabletSplitITestBase<yb::MiniCluster>::GetTestTableId()
Unexecuted instantiation: yb::TabletSplitITestBase<yb::ExternalMiniCluster>::GetTestTableId()
118
119
  // Make sure table contains only keys 1...num_keys without gaps.
120
  void CheckTableKeysInRange(const size_t num_keys);
121
122
 protected:
123
47
  virtual int64_t GetRF() { return 3; }
yb::TabletSplitITestBase<yb::MiniCluster>::GetRF()
Line
Count
Source
123
39
  virtual int64_t GetRF() { return 3; }
yb::TabletSplitITestBase<yb::ExternalMiniCluster>::GetRF()
Line
Count
Source
123
8
  virtual int64_t GetRF() { return 3; }
124
125
  std::unique_ptr<rpc::ProxyCache> proxy_cache_;
126
127
};
128
// Let compiler know about these explicit specializations since below subclasses inherit from them.
129
extern template class TabletSplitITestBase<MiniCluster>;
130
extern template class TabletSplitITestBase<ExternalMiniCluster>;
131
132
133
class TabletSplitITest : public TabletSplitITestBase<MiniCluster> {
134
 public:
135
  TabletSplitITest();
136
  ~TabletSplitITest();
137
138
  void SetUp() override;
139
140
  Result<TabletId> CreateSingleTabletAndSplit(uint32_t num_rows);
141
142
  Result<tserver::GetSplitKeyResponsePB> GetSplitKey(const std::string& tablet_id);
143
144
0
  Result<master::CatalogManagerIf*> catalog_manager() {
145
0
    return &CHECK_NOTNULL(VERIFY_RESULT(cluster_->GetLeaderMiniMaster()))->catalog_manager();
146
0
  }
147
148
  Result<master::TabletInfos> GetTabletInfosForTable(const TableId& table_id);
149
150
  // By default we wait until all split tablets are cleanup. expected_split_tablets could be
151
  // overridden if needed to test behaviour of split tablet when its deletion is disabled.
152
  // If num_replicas_online is 0, uses replication factor.
153
  CHECKED_STATUS WaitForTabletSplitCompletion(
154
      const size_t expected_non_split_tablets, const size_t expected_split_tablets = 0,
155
      size_t num_replicas_online = 0, const client::YBTableName& table = client::kTableName,
156
      bool core_dump_on_failure = true);
157
158
  Result<TabletId> SplitSingleTablet(docdb::DocKeyHash split_hash_code);
159
160
  Result<TabletId> SplitTabletAndValidate(
161
      docdb::DocKeyHash split_hash_code,
162
      size_t num_rows,
163
      bool parent_tablet_protected_from_deletion = false);
164
165
  // Checks source tablet behaviour after split:
166
  // - It should reject reads and writes.
167
  CHECKED_STATUS CheckSourceTabletAfterSplit(const TabletId& source_tablet_id);
168
169
  // Tests appropriate client requests structure update at YBClient side.
170
  // split_depth specifies how deep should we split original tablet until trying to write again.
171
  void SplitClientRequestsIds(int split_depth);
172
173
  // Returns all tablet peers in the cluster which are marked as being in
174
  // TABLET_DATA_SPLIT_COMPLETED state. In most of the test cases below, this corresponds to the
175
  // post-split parent/source tablet peers.
176
  Result<std::vector<tablet::TabletPeerPtr>> ListSplitCompleteTabletPeers();
177
178
  // Returns all tablet peers in the cluster which are not part of a transaction table and which are
179
  // not in TABLET_DATA_SPLIT_COMPLETED state. In most of the test cases below, this corresponds to
180
  // post-split children tablet peers.
181
  Result<std::vector<tablet::TabletPeerPtr>> ListPostSplitChildrenTabletPeers();
182
183
  // Wait for all peers to complete post-split compaction.
184
  CHECKED_STATUS WaitForTestTablePostSplitTabletsFullyCompacted(MonoDelta timeout);
185
186
  Result<int> NumPostSplitTabletPeersFullyCompacted();
187
188
  // Returns the smallest sst file size among all replicas for a given tablet id
189
  Result<uint64_t> GetMinSstFileSizeAmongAllReplicas(const std::string& tablet_id);
190
191
  // Checks active tablet replicas (all expect ones that have been split) to have all rows from 1 to
192
  // `num_rows` and nothing else.
193
  // If num_replicas_online is 0, uses replication factor.
194
  CHECKED_STATUS CheckPostSplitTabletReplicasData(
195
      size_t num_rows, size_t num_replicas_online = 0, size_t num_active_tablets = 2);
196
197
 protected:
198
  MonoDelta split_completion_timeout_ = std::chrono::seconds(40) * kTimeMultiplier;
199
  std::unique_ptr<client::SnapshotTestUtil> snapshot_util_;
200
};
201
202
203
class TabletSplitExternalMiniClusterITest : public TabletSplitITestBase<ExternalMiniCluster> {
204
 public:
205
  void SetFlags() override;
206
207
  CHECKED_STATUS SplitTablet(const std::string& tablet_id);
208
209
  CHECKED_STATUS FlushTabletsOnSingleTServer(
210
      size_t tserver_idx, const std::vector<yb::TabletId> tablet_ids, bool is_compaction);
211
212
  Result<std::set<TabletId>> GetTestTableTabletIds(size_t tserver_idx);
213
214
  Result<std::set<TabletId>> GetTestTableTabletIds();
215
216
  Result<vector<tserver::ListTabletsResponsePB_StatusAndSchemaPB>> ListTablets(size_t tserver_idx);
217
218
  Result<vector<tserver::ListTabletsResponsePB_StatusAndSchemaPB>> ListTablets();
219
220
  CHECKED_STATUS WaitForTabletsExcept(
221
      size_t num_tablets, size_t tserver_idx, const TabletId& exclude_tablet);
222
223
  CHECKED_STATUS WaitForTablets(size_t num_tablets, size_t tserver_idx);
224
225
  CHECKED_STATUS WaitForTablets(size_t num_tablets);
226
227
  CHECKED_STATUS SplitTabletCrashMaster(bool change_split_boundary, string* split_partition_key);
228
229
  Result<TabletId> GetOnlyTestTabletId(size_t tserver_idx);
230
231
  Result<TabletId> GetOnlyTestTabletId();
232
};
233
234
}  // namespace yb
235
236
#endif /* YB_INTEGRATION_TESTS_TABLET_SPLIT_ITEST_BASE_H */