YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/master/catalog_manager_util.h
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
#ifndef YB_MASTER_CATALOG_MANAGER_UTIL_H
15
#define YB_MASTER_CATALOG_MANAGER_UTIL_H
16
17
#include <unordered_map>
18
#include <vector>
19
20
#include "yb/consensus/consensus_fwd.h"
21
#include "yb/master/catalog_entity_info.h"
22
#include "yb/master/master_fwd.h"
23
#include "yb/master/ts_descriptor.h"
24
25
DECLARE_bool(transaction_tables_use_preferred_zones);
26
27
// Utility functions that can be shared between test and code for catalog manager.
28
namespace yb {
29
namespace master {
30
31
using ZoneToDescMap = std::unordered_map<string, TSDescriptorVector>;
32
33
struct Comparator;
34
35
class CatalogManagerUtil {
36
 public:
37
  // For the given set of descriptors, checks if the load is considered balanced across AZs in
38
  // multi AZ setup, else checks load distribution across tservers (single AZ).
39
  static CHECKED_STATUS IsLoadBalanced(const TSDescriptorVector& ts_descs);
40
41
  // For the given set of descriptors, checks if every tserver that shouldn't have leader load
42
  // actually has no leader load.
43
  // If transaction_tables_use_preferred_zones = false, then we also check if txn status tablet
44
  // leaders are spread evenly based on the information in `tables`.
45
  static CHECKED_STATUS AreLeadersOnPreferredOnly(
46
      const TSDescriptorVector& ts_descs,
47
      const ReplicationInfoPB& replication_info,
48
      const vector<scoped_refptr<TableInfo>>& tables = {});
49
50
  // Creates a mapping from tserver uuid to the number of transaction leaders present.
51
  static void CalculateTxnLeaderMap(std::map<std::string, int>* txn_map,
52
                                    int* num_txn_tablets,
53
                                    vector<scoped_refptr<TableInfo>> tables);
54
55
  // For the given set of descriptors, returns the map from each placement AZ to list of tservers
56
  // running in that zone.
57
  static CHECKED_STATUS GetPerZoneTSDesc(const TSDescriptorVector& ts_descs,
58
                                         ZoneToDescMap* zone_to_ts);
59
60
  // Checks whether two given cloud infos are identical.
61
  static bool IsCloudInfoEqual(const CloudInfoPB& lhs, const CloudInfoPB& rhs);
62
63
  // For the given placement info, checks whether a given cloud info is contained within it.
64
  static bool DoesPlacementInfoContainCloudInfo(const PlacementInfoPB& placement_info,
65
                                                const CloudInfoPB& cloud_info);
66
67
  // Checks whether the given placement info spans more than one region.
68
  static bool DoesPlacementInfoSpanMultipleRegions(const PlacementInfoPB& placement_info);
69
70
  // Called when registering a ts from raft, deduce a tservers placement from the peer's role
71
  // and cloud info.
72
  static Result<std::string> GetPlacementUuidFromRaftPeer(
73
      const ReplicationInfoPB& replication_info, const consensus::RaftPeerPB& peer);
74
75
  // Returns error if tablet partition is not covered by running inner tablets partitions.
76
  static CHECKED_STATUS CheckIfCanDeleteSingleTablet(const scoped_refptr<TabletInfo>& tablet);
77
78
  enum CloudInfoSimilarity {
79
    NO_MATCH = 0,
80
    CLOUD_MATCH = 1,
81
    REGION_MATCH = 2,
82
    ZONE_MATCH = 3
83
  };
84
85
  // Computes a similarity score between two cloudinfos (which may be prefixes).
86
  // 0: different clouds
87
  // 1: same cloud, different region
88
  // 2: same cloud and region, different zone
89
  // 3: same cloud and region and zone, or prefix matches
90
  static CloudInfoSimilarity ComputeCloudInfoSimilarity(const CloudInfoPB& ci1,
91
                                                        const CloudInfoPB& ci2);
92
93
  // Checks if one cloudinfo is a prefix of another. This assumes that ci1 and ci2 are
94
  // prefixes.
95
  static bool IsCloudInfoPrefix(const CloudInfoPB& ci1, const CloudInfoPB& ci2);
96
97
  // Validate if the specified placement information conforms to the rules.
98
  // Currently, the following assumption about placement blocks is made.
99
  // Every TS should have a unique placement block to which it can be mapped.
100
  // This translates to placement blocks being disjoint i.e. no placement
101
  // block string (C.R.Z format) should be proper prefix of another.
102
  // Validate placement information if passed.
103
  static CHECKED_STATUS IsPlacementInfoValid(const PlacementInfoPB& placement_info);
104
105
  template<class LoadState>
106
180k
  static void FillTableLoadState(const scoped_refptr<TableInfo>& table_info, LoadState* state) {
107
180k
    auto tablets = table_info->GetTablets(IncludeInactive::kTrue);
108
109
1.02M
    for (const auto& tablet : tablets) {
110
      // Ignore if tablet is not running.
111
1.02M
      {
112
1.02M
        auto tablet_lock = tablet->LockForRead();
113
1.02M
        if (!tablet_lock->is_running()) {
114
174k
          continue;
115
174k
        }
116
1.02M
      }
117
847k
      auto replica_locs = tablet->GetReplicaLocations();
118
119
2.48M
      for (const auto& loc : *replica_locs) {
120
        // Ignore replica if not present in the tserver list passed.
121
2.48M
        if (state->per_ts_load_.count(loc.first) == 0) {
122
18
          continue;
123
18
        }
124
        // Account for this load.
125
2.48M
        state->per_ts_load_[loc.first]++;
126
2.48M
      }
127
847k
    }
128
180k
  }
void yb::master::CatalogManagerUtil::FillTableLoadState<yb::master::CMPerTableLoadState>(scoped_refptr<yb::master::TableInfo> const&, yb::master::CMPerTableLoadState*)
Line
Count
Source
106
21.4k
  static void FillTableLoadState(const scoped_refptr<TableInfo>& table_info, LoadState* state) {
107
21.4k
    auto tablets = table_info->GetTablets(IncludeInactive::kTrue);
108
109
207k
    for (const auto& tablet : tablets) {
110
      // Ignore if tablet is not running.
111
207k
      {
112
207k
        auto tablet_lock = tablet->LockForRead();
113
207k
        if (!tablet_lock->is_running()) {
114
87.0k
          continue;
115
87.0k
        }
116
207k
      }
117
120k
      auto replica_locs = tablet->GetReplicaLocations();
118
119
364k
      for (const auto& loc : *replica_locs) {
120
        // Ignore replica if not present in the tserver list passed.
121
364k
        if (state->per_ts_load_.count(loc.first) == 0) {
122
0
          continue;
123
0
        }
124
        // Account for this load.
125
364k
        state->per_ts_load_[loc.first]++;
126
364k
      }
127
120k
    }
128
21.4k
  }
void yb::master::CatalogManagerUtil::FillTableLoadState<yb::master::CMGlobalLoadState>(scoped_refptr<yb::master::TableInfo> const&, yb::master::CMGlobalLoadState*)
Line
Count
Source
106
158k
  static void FillTableLoadState(const scoped_refptr<TableInfo>& table_info, LoadState* state) {
107
158k
    auto tablets = table_info->GetTablets(IncludeInactive::kTrue);
108
109
814k
    for (const auto& tablet : tablets) {
110
      // Ignore if tablet is not running.
111
814k
      {
112
814k
        auto tablet_lock = tablet->LockForRead();
113
814k
        if (!tablet_lock->is_running()) {
114
87.0k
          continue;
115
87.0k
        }
116
814k
      }
117
727k
      auto replica_locs = tablet->GetReplicaLocations();
118
119
2.11M
      for (const auto& loc : *replica_locs) {
120
        // Ignore replica if not present in the tserver list passed.
121
2.11M
        if (state->per_ts_load_.count(loc.first) == 0) {
122
18
          continue;
123
18
        }
124
        // Account for this load.
125
2.11M
        state->per_ts_load_[loc.first]++;
126
2.11M
      }
127
727k
    }
128
158k
  }
129
130
 private:
131
  CatalogManagerUtil();
132
133
  DISALLOW_COPY_AND_ASSIGN(CatalogManagerUtil);
134
};
135
136
class CMGlobalLoadState {
137
 public:
138
617k
  uint32_t GetGlobalLoad(const TabletServerId& id) {
139
617k
    return per_ts_load_[id];
140
617k
  }
141
  std::unordered_map<TabletServerId, uint32_t> per_ts_load_;
142
};
143
144
class CMPerTableLoadState {
145
 public:
146
  explicit CMPerTableLoadState(CMGlobalLoadState* global_state)
147
21.4k
    : global_load_state_(global_state) {}
148
149
  bool CompareLoads(const TabletServerId& ts1, const TabletServerId& ts2);
150
151
  void SortLoad();
152
153
  std::vector<TabletServerId> sorted_load_;
154
  std::unordered_map<TabletServerId, uint32_t> per_ts_load_;
155
  CMGlobalLoadState* global_load_state_;
156
};
157
158
struct Comparator {
159
161k
  explicit Comparator(CMPerTableLoadState* state) : state_(state) {}
160
161
499k
  bool operator()(const TabletServerId& id1, const TabletServerId& id2) {
162
499k
    return state_->CompareLoads(id1, id2);
163
499k
  }
164
165
  CMPerTableLoadState* state_;
166
};
167
168
} // namespace master
169
} // namespace yb
170
171
#endif // YB_MASTER_CATALOG_MANAGER_UTIL_H