YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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
54.6k
  static void FillTableLoadState(const scoped_refptr<TableInfo>& table_info, LoadState* state) {
107
54.6k
    auto tablets = table_info->GetTablets(IncludeInactive::kTrue);
108
109
445k
    for (const auto& tablet : tablets) {
110
      // Ignore if tablet is not running.
111
445k
      {
112
445k
        auto tablet_lock = tablet->LockForRead();
113
445k
        if (!tablet_lock->is_running()) {
114
112k
          continue;
115
112k
        }
116
333k
      }
117
333k
      auto replica_locs = tablet->GetReplicaLocations();
118
119
996k
      for (const auto& loc : *replica_locs) {
120
        // Ignore replica if not present in the tserver list passed.
121
996k
        if (state->per_ts_load_.count(loc.first) == 0) {
122
378
          continue;
123
378
        }
124
        // Account for this load.
125
996k
        state->per_ts_load_[loc.first]++;
126
996k
      }
127
333k
    }
128
54.6k
  }
_ZN2yb6master18CatalogManagerUtil18FillTableLoadStateINS0_19CMPerTableLoadStateEEEvRK13scoped_refptrINS0_9TableInfoEEPT_
Line
Count
Source
106
12.6k
  static void FillTableLoadState(const scoped_refptr<TableInfo>& table_info, LoadState* state) {
107
12.6k
    auto tablets = table_info->GetTablets(IncludeInactive::kTrue);
108
109
137k
    for (const auto& tablet : tablets) {
110
      // Ignore if tablet is not running.
111
137k
      {
112
137k
        auto tablet_lock = tablet->LockForRead();
113
137k
        if (!tablet_lock->is_running()) {
114
56.0k
          continue;
115
56.0k
        }
116
81.2k
      }
117
81.2k
      auto replica_locs = tablet->GetReplicaLocations();
118
119
246k
      for (const auto& loc : *replica_locs) {
120
        // Ignore replica if not present in the tserver list passed.
121
246k
        if (state->per_ts_load_.count(loc.first) == 0) {
122
0
          continue;
123
0
        }
124
        // Account for this load.
125
246k
        state->per_ts_load_[loc.first]++;
126
246k
      }
127
81.2k
    }
128
12.6k
  }
_ZN2yb6master18CatalogManagerUtil18FillTableLoadStateINS0_17CMGlobalLoadStateEEEvRK13scoped_refptrINS0_9TableInfoEEPT_
Line
Count
Source
106
42.0k
  static void FillTableLoadState(const scoped_refptr<TableInfo>& table_info, LoadState* state) {
107
42.0k
    auto tablets = table_info->GetTablets(IncludeInactive::kTrue);
108
109
307k
    for (const auto& tablet : tablets) {
110
      // Ignore if tablet is not running.
111
307k
      {
112
307k
        auto tablet_lock = tablet->LockForRead();
113
307k
        if (!tablet_lock->is_running()) {
114
56.0k
          continue;
115
56.0k
        }
116
251k
      }
117
251k
      auto replica_locs = tablet->GetReplicaLocations();
118
119
750k
      for (const auto& loc : *replica_locs) {
120
        // Ignore replica if not present in the tserver list passed.
121
750k
        if (state->per_ts_load_.count(loc.first) == 0) {
122
378
          continue;
123
378
        }
124
        // Account for this load.
125
749k
        state->per_ts_load_[loc.first]++;
126
749k
      }
127
251k
    }
128
42.0k
  }
129
130
 private:
131
  CatalogManagerUtil();
132
133
  DISALLOW_COPY_AND_ASSIGN(CatalogManagerUtil);
134
};
135
136
class CMGlobalLoadState {
137
 public:
138
351k
  uint32_t GetGlobalLoad(const TabletServerId& id) {
139
351k
    return per_ts_load_[id];
140
351k
  }
141
  std::unordered_map<TabletServerId, uint32_t> per_ts_load_;
142
};
143
144
class CMPerTableLoadState {
145
 public:
146
  explicit CMPerTableLoadState(CMGlobalLoadState* global_state)
147
12.6k
    : 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
94.8k
  explicit Comparator(CMPerTableLoadState* state) : state_(state) {}
160
161
288k
  bool operator()(const TabletServerId& id1, const TabletServerId& id2) {
162
288k
    return state_->CompareLoads(id1, id2);
163
288k
  }
164
165
  CMPerTableLoadState* state_;
166
};
167
168
} // namespace master
169
} // namespace yb
170
171
#endif // YB_MASTER_CATALOG_MANAGER_UTIL_H