YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/integration-tests/load_balancer_colocated_tables-test.cc
Line
Count
Source
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
#include <gtest/gtest.h>
15
16
#include "yb/client/client.h"
17
#include "yb/client/schema.h"
18
#include "yb/client/table.h"
19
#include "yb/client/table_creator.h"
20
#include "yb/client/yb_table_name.h"
21
22
#include "yb/common/common.pb.h"
23
#include "yb/common/entity_ids.h"
24
25
#include "yb/consensus/consensus.pb.h"
26
#include "yb/consensus/consensus.proxy.h"
27
28
#include "yb/integration-tests/external_mini_cluster.h"
29
#include "yb/integration-tests/load_balancer_test_util.h"
30
#include "yb/integration-tests/mini_cluster.h"
31
#include "yb/integration-tests/yb_table_test_base.h"
32
33
#include "yb/tools/yb-admin_client.h"
34
35
#include "yb/util/monotime.h"
36
#include "yb/util/result.h"
37
38
using namespace std::literals;
39
40
namespace yb {
41
namespace integration_tests {
42
43
const auto kDefaultTimeout = 30000ms;
44
constexpr int kNumTables = 3;
45
constexpr int kMovesPerTable = 1;
46
constexpr int kNumTxnTablets = 6;
47
48
// We need multiple tables in order to test load_balancer_max_concurrent_moves_per_table.
49
class LoadBalancerColocatedTablesTest : public YBTableTestBase {
50
 protected:
51
2
  bool use_yb_admin_client() override { return true; }
52
53
11
  bool use_external_mini_cluster() override { return true; }
54
55
1
  bool enable_ysql() override {
56
    // Create the transaction status table.
57
1
    return true;
58
1
  }
59
60
7
  int num_tablets() override {
61
7
    return 5;
62
7
  }
63
64
1
  void CustomizeExternalMiniCluster(ExternalMiniClusterOptions* opts) override {
65
1
    opts->extra_tserver_flags.push_back("--placement_cloud=c");
66
1
    opts->extra_tserver_flags.push_back("--placement_region=r");
67
1
    opts->extra_tserver_flags.push_back("--placement_zone=z${index}");
68
1
    opts->extra_master_flags.push_back("--load_balancer_max_concurrent_moves=10");
69
1
    opts->extra_master_flags.push_back("--load_balancer_max_concurrent_moves_per_table="
70
1
                                       + std::to_string(kMovesPerTable));
71
1
    opts->extra_master_flags.push_back("--enable_global_load_balancing=true");
72
    // This value needs to be divisible by three so that the transaction tablets are evenly divided
73
    // amongst the three tservers that we end up creating.
74
1
    opts->extra_master_flags.push_back("--transaction_table_num_tablets="
75
1
                                       + std::to_string(kNumTxnTablets));
76
1
  }
77
78
1
  void CreateTables() {
79
4
    for (int i = 1; i <= kNumTables; ++i) {
80
      // Autogenerated ids will fail the IsPgsqlId() CHECKs so we need to generate oids.
81
      // Currently just using 1111, 2222, 3333, etc.
82
3
      const uint32_t db_oid = i * 1000 + i * 100 + i * 10 + i;
83
3
      const uint32_t table_oid = db_oid;
84
3
      table_names_.emplace_back(YQL_DATABASE_PGSQL,
85
3
                               GetPgsqlNamespaceId(db_oid),
86
3
                               "my_database-" + std::to_string(i),
87
3
                               GetPgsqlTableId(db_oid, table_oid),
88
3
                               "kv-table-test-" + std::to_string(i));
89
3
    }
90
91
3
    for (const auto& tn : table_names_) {
92
3
      ASSERT_OK(client_->CreateNamespaceIfNotExists(tn.namespace_name(),
93
3
                                                    tn.namespace_type(),
94
3
                                                    "",                 /* creator_role_name */
95
3
                                                    tn.namespace_id(),  /* namespace_id */
96
3
                                                    "",                 /* source_namespace_id */
97
3
                                                    boost::none,        /* next_pg_oid */
98
3
                                                    true                /* colocated */));
99
100
3
      client::YBSchemaBuilder b;
101
3
      b.AddColumn("k")->Type(BINARY)->NotNull()->PrimaryKey();
102
3
      b.AddColumn("v")->Type(BINARY)->NotNull();
103
3
      ASSERT_OK(b.Build(&schema_));
104
105
3
      ASSERT_OK(NewTableCreator()->table_name(tn)
106
3
                                  .table_id(tn.table_id())
107
3
                                  .schema(&schema_)
108
3
                                  .colocated(true)
109
3
                                  .Create());
110
3
    }
111
1
  }
112
113
1
  void DeleteTables() {
114
3
    for (const auto& tn : table_names_) {
115
3
      ASSERT_OK(client_->DeleteTable(tn));
116
3
    }
117
1
    table_names_.clear();
118
1
  }
119
120
1
  void CreateTable() override {
121
1
    if (!table_exists_) {
122
1
      CreateTables();
123
1
      table_exists_ = true;
124
1
    }
125
1
  }
126
127
1
  void DeleteTable() override {
128
1
    if (table_exists_) {
129
1
      DeleteTables();
130
1
      table_exists_ = false;
131
1
    }
132
1
  }
133
134
  // Modified to create SQL tables.
135
3
  std::unique_ptr<client::YBTableCreator> NewTableCreator() override {
136
3
    std::unique_ptr<client::YBTableCreator> table_creator(client_->NewTableCreator());
137
3
    if (num_tablets() > 0) {
138
3
      table_creator->num_tablets(num_tablets());
139
3
    }
140
3
    table_creator->table_type(client::YBTableType::PGSQL_TABLE_TYPE);
141
3
    return table_creator;
142
3
  }
143
};
144
145
// See issue #4871 about the disable in TSAN.
146
TEST_F(LoadBalancerColocatedTablesTest,
147
1
       YB_DISABLE_TEST_IN_TSAN(GlobalLoadBalancingWithColocatedTables)) {
148
1
  const int rf = 3;
149
1
  std::vector<uint32_t> z0_tserver_loads;
150
  // Start with 3 tables with 5 tablets.
151
1
  ASSERT_OK(yb_admin_client_->ModifyPlacementInfo("c.r.z0,c.r.z1,c.r.z2", rf, ""));
152
153
  // Add two tservers to z0 and wait for everything to be balanced (globally and per table).
154
1
  std::vector<std::string> extra_opts;
155
1
  extra_opts.push_back("--placement_cloud=c");
156
1
  extra_opts.push_back("--placement_region=r");
157
1
  extra_opts.push_back("--placement_zone=z0");
158
1
  ASSERT_OK(external_mini_cluster()->AddTabletServer(true, extra_opts));
159
1
  ASSERT_OK(external_mini_cluster()->AddTabletServer(true, extra_opts));
160
1
  ASSERT_OK(external_mini_cluster()->WaitForTabletServerCount(num_tablet_servers() + 2,
161
1
      kDefaultTimeout));
162
163
  // Wait for load balancing to complete.
164
1
  WaitForLoadBalanceCompletion();
165
166
  // Assert that each table is balanced, and that we are globally balanced.
167
1
  ASSERT_OK(client_->IsLoadBalanced(kNumTables * num_tablets() * rf));
168
  // Each colocated table should have its tablet on a different TS in z0.
169
1
  z0_tserver_loads = ASSERT_RESULT(GetTserverLoads({ 0, 3, 4 }));
170
1
  ASSERT_TRUE(AreLoadsBalanced(z0_tserver_loads));
171
1
  ASSERT_EQ(z0_tserver_loads[0], 1);
172
1
  ASSERT_EQ(z0_tserver_loads[1], 1);
173
1
  ASSERT_EQ(z0_tserver_loads[2], 1);
174
1
}
175
176
} // namespace integration_tests
177
} // namespace yb