YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/master/catalog_entity_info.cc
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
33
#include "yb/master/catalog_entity_info.h"
34
35
#include <string>
36
37
#include "yb/common/doc_hybrid_time.h"
38
#include "yb/common/transaction.h"
39
#include "yb/common/wire_protocol.h"
40
41
#include "yb/master/master_client.pb.h"
42
#include "yb/master/master_defaults.h"
43
#include "yb/master/master_error.h"
44
#include "yb/master/ts_descriptor.h"
45
46
#include "yb/gutil/map-util.h"
47
#include "yb/util/atomic.h"
48
#include "yb/util/format.h"
49
#include "yb/util/status_format.h"
50
#include "yb/util/string_util.h"
51
52
using std::string;
53
54
using strings::Substitute;
55
56
DECLARE_int32(tserver_unresponsive_timeout_ms);
57
58
namespace yb {
59
namespace master {
60
61
// ================================================================================================
62
// TabletReplica
63
// ================================================================================================
64
65
517k
string TabletReplica::ToString() const {
66
517k
  return Format("{ ts_desc: $0, state: $1, role: $2, member_type: $3, "
67
517k
                "should_disable_lb_move: $4, fs_data_dir: $5, "
68
517k
                "total_space_used: $6, time since update: $7ms }",
69
517k
                ts_desc->permanent_uuid(),
70
517k
                tablet::RaftGroupStatePB_Name(state),
71
517k
                PeerRole_Name(role),
72
517k
                consensus::PeerMemberType_Name(member_type),
73
517k
                should_disable_lb_move, fs_data_dir,
74
517k
                drive_info.sst_files_size + drive_info.wal_files_size,
75
517k
                MonoTime::Now().GetDeltaSince(time_updated).ToMilliseconds());
76
517k
}
77
78
327k
void TabletReplica::UpdateFrom(const TabletReplica& source) {
79
327k
  state = source.state;
80
327k
  role = source.role;
81
327k
  member_type = source.member_type;
82
327k
  should_disable_lb_move = source.should_disable_lb_move;
83
327k
  fs_data_dir = source.fs_data_dir;
84
327k
  time_updated = MonoTime::Now();
85
327k
}
86
87
2.39M
void TabletReplica::UpdateDriveInfo(const TabletReplicaDriveInfo& info) {
88
2.39M
  drive_info = info;
89
2.39M
}
90
91
11.5M
bool TabletReplica::IsStale() const {
92
11.5M
  MonoTime now(MonoTime::Now());
93
11.5M
  if (now.GetDeltaSince(time_updated).ToMilliseconds() >=
94
11.5M
      GetAtomicFlag(&FLAGS_tserver_unresponsive_timeout_ms)) {
95
6.49M
    return true;
96
6.49M
  }
97
5.02M
  return false;
98
11.5M
}
99
100
127k
bool TabletReplica::IsStarting() const {
101
127k
  return (state == tablet::NOT_STARTED || 
state == tablet::BOOTSTRAPPING127k
);
102
127k
}
103
104
// ================================================================================================
105
// TabletInfo
106
// ================================================================================================
107
108
class TabletInfo::LeaderChangeReporter {
109
 public:
110
  explicit LeaderChangeReporter(TabletInfo* info)
111
441k
      : info_(info), old_leader_(info->GetLeaderUnlocked()) {
112
441k
  }
113
114
441k
  ~LeaderChangeReporter() {
115
441k
    auto new_leader = info_->GetLeaderUnlocked();
116
441k
    if (old_leader_ != new_leader) {
117
59.7k
      LOG(INFO) << "T " << info_->tablet_id() << ": Leader changed from "
118
59.7k
                << yb::ToString(old_leader_) << " to " << yb::ToString(new_leader);
119
59.7k
    }
120
441k
  }
121
 private:
122
  TabletInfo* info_;
123
  TSDescriptor* old_leader_;
124
};
125
126
TabletInfo::TabletInfo(const scoped_refptr<TableInfo>& table, TabletId tablet_id)
127
    : tablet_id_(std::move(tablet_id)),
128
      table_(table),
129
      last_update_time_(MonoTime::Now()),
130
100k
      reported_schema_version_({}) {
131
  // Have to pre-initialize to an empty map, in case of access before the first setter is called.
132
100k
  replica_locations_ = std::make_shared<TabletReplicaMap>();
133
100k
}
134
135
2.17k
TabletInfo::~TabletInfo() {
136
2.17k
}
137
138
void TabletInfo::SetReplicaLocations(
139
113k
    std::shared_ptr<TabletReplicaMap> replica_locations) {
140
113k
  std::lock_guard<simple_spinlock> l(lock_);
141
113k
  LeaderChangeReporter leader_change_reporter(this);
142
113k
  last_update_time_ = MonoTime::Now();
143
113k
  replica_locations_ = replica_locations;
144
113k
}
145
146
92.0M
CHECKED_STATUS TabletInfo::CheckRunning() const {
147
92.0M
  if (!table()->is_running()) {
148
255
    return STATUS_EC_FORMAT(Expired, MasterError(MasterErrorPB::TABLE_NOT_RUNNING),
149
255
                            "Table is not running: $0", table()->ToStringWithState());
150
255
  }
151
152
92.0M
  return Status::OK();
153
92.0M
}
154
155
92.0M
CHECKED_STATUS TabletInfo::GetLeaderNotFoundStatus() const {
156
92.0M
  RETURN_NOT_OK(CheckRunning());
157
158
92.0M
  return STATUS_FORMAT(
159
92.0M
      NotFound,
160
92.0M
      "No leader found for tablet $0 with $1 replicas: $2.",
161
92.0M
      ToString(), replica_locations_->size(), *replica_locations_);
162
92.0M
}
163
164
4.12M
Result<TSDescriptor*> TabletInfo::GetLeader() const {
165
4.12M
  std::lock_guard<simple_spinlock> l(lock_);
166
4.12M
  auto result = GetLeaderUnlocked();
167
4.12M
  if (result) {
168
3.96M
    return result;
169
3.96M
  }
170
160k
  return GetLeaderNotFoundStatus();
171
4.12M
}
172
173
95.3M
Result<TabletReplicaDriveInfo> TabletInfo::GetLeaderReplicaDriveInfo() const {
174
95.3M
  std::lock_guard<simple_spinlock> l(lock_);
175
176
95.3M
  for (const auto& pair : *replica_locations_) {
177
6.92M
    if (pair.second.role == PeerRole::LEADER) {
178
3.50M
      return pair.second.drive_info;
179
3.50M
    }
180
6.92M
  }
181
91.8M
  return GetLeaderNotFoundStatus();
182
95.3M
}
183
184
5.00M
TSDescriptor* TabletInfo::GetLeaderUnlocked() const {
185
10.3M
  for (const auto& pair : *replica_locations_) {
186
10.3M
    if (pair.second.role == PeerRole::LEADER) {
187
4.48M
      return pair.second.ts_desc;
188
4.48M
    }
189
10.3M
  }
190
526k
  return nullptr;
191
5.00M
}
192
193
5.83M
std::shared_ptr<const TabletReplicaMap> TabletInfo::GetReplicaLocations() const {
194
5.83M
  std::lock_guard<simple_spinlock> l(lock_);
195
5.83M
  return replica_locations_;
196
5.83M
}
197
198
327k
void TabletInfo::UpdateReplicaLocations(const TabletReplica& replica) {
199
327k
  std::lock_guard<simple_spinlock> l(lock_);
200
327k
  LeaderChangeReporter leader_change_reporter(this);
201
327k
  last_update_time_ = MonoTime::Now();
202
  // Make a new shared_ptr, copying the data, to ensure we don't race against access to data from
203
  // clients that already have the old shared_ptr.
204
327k
  replica_locations_ = std::make_shared<TabletReplicaMap>(*replica_locations_);
205
327k
  auto it = replica_locations_->find(replica.ts_desc->permanent_uuid());
206
327k
  if (it == replica_locations_->end()) {
207
86
    replica_locations_->emplace(replica.ts_desc->permanent_uuid(), replica);
208
86
    return;
209
86
  }
210
327k
  it->second.UpdateFrom(replica);
211
327k
}
212
213
void TabletInfo::UpdateReplicaDriveInfo(const std::string& ts_uuid,
214
2.20M
                                        const TabletReplicaDriveInfo& drive_info) {
215
2.20M
  std::lock_guard<simple_spinlock> l(lock_);
216
  // Make a new shared_ptr, copying the data, to ensure we don't race against access to data from
217
  // clients that already have the old shared_ptr.
218
2.20M
  replica_locations_ = std::make_shared<TabletReplicaMap>(*replica_locations_);
219
2.20M
  auto it = replica_locations_->find(ts_uuid);
220
2.20M
  if (it == replica_locations_->end()) {
221
567
    return;
222
567
  }
223
2.19M
  it->second.UpdateDriveInfo(drive_info);
224
2.19M
}
225
226
48.3k
void TabletInfo::set_last_update_time(const MonoTime& ts) {
227
48.3k
  std::lock_guard<simple_spinlock> l(lock_);
228
48.3k
  last_update_time_ = ts;
229
48.3k
}
230
231
38.3k
MonoTime TabletInfo::last_update_time() const {
232
38.3k
  std::lock_guard<simple_spinlock> l(lock_);
233
38.3k
  return last_update_time_;
234
38.3k
}
235
236
97.3k
bool TabletInfo::set_reported_schema_version(const TableId& table_id, uint32_t version) {
237
97.3k
  std::lock_guard<simple_spinlock> l(lock_);
238
97.3k
  if (reported_schema_version_.count(table_id) == 0 ||
239
97.3k
      
version > reported_schema_version_[table_id]48.3k
) {
240
71.0k
    reported_schema_version_[table_id] = version;
241
71.0k
    return true;
242
71.0k
  }
243
26.2k
  return false;
244
97.3k
}
245
246
74.7k
uint32_t TabletInfo::reported_schema_version(const TableId& table_id) {
247
74.7k
  std::lock_guard<simple_spinlock> l(lock_);
248
74.7k
  if (reported_schema_version_.count(table_id) == 0) {
249
26
    return 0;
250
26
  }
251
74.7k
  return reported_schema_version_[table_id];
252
74.7k
}
253
254
3.50M
bool TabletInfo::colocated() const {
255
3.50M
  return LockForRead()->pb.colocated();
256
3.50M
}
257
258
92.2M
string TabletInfo::ToString() const {
259
92.2M
  return Substitute("$0 (table $1)", tablet_id_,
260
92.2M
                    (table_ != nullptr ? 
table_->ToString()92.2M
:
"MISSING"213
));
261
92.2M
}
262
263
void TabletInfo::RegisterLeaderStepDownFailure(const TabletServerId& dest_leader,
264
54.0k
                                               MonoDelta time_since_stepdown_failure) {
265
54.0k
  std::lock_guard<simple_spinlock> l(lock_);
266
54.0k
  leader_stepdown_failure_times_[dest_leader] = MonoTime::Now() - time_since_stepdown_failure;
267
54.0k
}
268
269
void TabletInfo::GetLeaderStepDownFailureTimes(MonoTime forget_failures_before,
270
3.94M
                                               LeaderStepDownFailureTimes* dest) {
271
3.94M
  std::lock_guard<simple_spinlock> l(lock_);
272
3.94M
  for (auto iter = leader_stepdown_failure_times_.begin();
273
4.22M
       iter != leader_stepdown_failure_times_.end(); ) {
274
279k
    if (iter->second < forget_failures_before) {
275
4.55k
      iter = leader_stepdown_failure_times_.erase(iter);
276
275k
    } else {
277
275k
      iter++;
278
275k
    }
279
279k
  }
280
3.94M
  *dest = leader_stepdown_failure_times_;
281
3.94M
}
282
283
121k
void PersistentTabletInfo::set_state(SysTabletsEntryPB::State state, const string& msg) {
284
121k
  pb.set_state(state);
285
121k
  pb.set_state_msg(msg);
286
121k
}
287
288
// ================================================================================================
289
// TableInfo
290
// ================================================================================================
291
292
TableInfo::TableInfo(TableId table_id,
293
                     scoped_refptr<TasksTracker> tasks_tracker)
294
    : table_id_(std::move(table_id)),
295
499k
      tasks_tracker_(tasks_tracker) {
296
499k
}
297
298
3.71k
TableInfo::~TableInfo() {
299
3.71k
}
300
301
596k
const TableName TableInfo::name() const {
302
596k
  return LockForRead()->pb.name();
303
596k
}
304
305
92.0M
bool TableInfo::is_running() const {
306
92.0M
  return LockForRead()->is_running();
307
92.0M
}
308
309
94.3M
bool TableInfo::is_deleted() const {
310
94.3M
  return LockForRead()->is_deleted();
311
94.3M
}
312
313
93.9M
string TableInfo::ToString() const {
314
93.9M
  return Substitute("$0 [id=$1]", LockForRead()->pb.name(), table_id_);
315
93.9M
}
316
317
260
string TableInfo::ToStringWithState() const {
318
260
  auto l = LockForRead();
319
260
  return Substitute("$0 [id=$1, state=$2]",
320
260
      l->pb.name(), table_id_, SysTablesEntryPB::State_Name(l->pb.state()));
321
260
}
322
323
1.33M
const NamespaceId TableInfo::namespace_id() const {
324
1.33M
  return LockForRead()->namespace_id();
325
1.33M
}
326
327
69.6k
const NamespaceName TableInfo::namespace_name() const {
328
69.6k
  return LockForRead()->namespace_name();
329
69.6k
}
330
331
4.03M
const Status TableInfo::GetSchema(Schema* schema) const {
332
4.03M
  return SchemaFromPB(LockForRead()->schema(), schema);
333
4.03M
}
334
335
5.31M
bool TableInfo::colocated() const {
336
5.31M
  return LockForRead()->pb.colocated();
337
5.31M
}
338
339
574k
std::string TableInfo::indexed_table_id() const {
340
574k
  return LockForRead()->indexed_table_id();
341
574k
}
342
343
0
bool TableInfo::is_local_index() const {
344
0
  auto l = LockForRead();
345
0
  return l->pb.has_index_info() ? l->pb.index_info().is_local()
346
0
                                : l->pb.is_local_index();
347
0
}
348
349
5.94k
bool TableInfo::is_unique_index() const {
350
5.94k
  auto l = LockForRead();
351
5.94k
  return l->pb.has_index_info() ? l->pb.index_info().is_unique()
352
5.94k
                                : 
l->pb.is_unique_index()0
;
353
5.94k
}
354
355
189M
TableType TableInfo::GetTableType() const {
356
189M
  return LockForRead()->pb.table_type();
357
189M
}
358
359
457k
void TableInfo::AddTablet(const TabletInfoPtr& tablet) {
360
457k
  std::lock_guard<decltype(lock_)> l(lock_);
361
457k
  AddTabletUnlocked(tablet);
362
457k
}
363
364
10
void TableInfo::ReplaceTablet(const TabletInfoPtr& old_tablet, const TabletInfoPtr& new_tablet) {
365
10
  std::lock_guard<decltype(lock_)> l(lock_);
366
10
  auto it = partitions_.find(old_tablet->metadata().dirty().pb.partition().partition_key_start());
367
10
  if (it != partitions_.end() && it->second == old_tablet.get()) {
368
10
    partitions_.erase(it);
369
10
  }
370
10
  AddTabletUnlocked(new_tablet);
371
10
}
372
373
374
42.8k
void TableInfo::AddTablets(const TabletInfos& tablets) {
375
42.8k
  std::lock_guard<decltype(lock_)> l(lock_);
376
83.0k
  for (const auto& tablet : tablets) {
377
83.0k
    AddTabletUnlocked(tablet);
378
83.0k
  }
379
42.8k
}
380
381
1.02M
void TableInfo::ClearTabletMaps(DeactivateOnly deactivate_only) {
382
1.02M
  std::lock_guard<decltype(lock_)> l(lock_);
383
1.02M
  partitions_.clear();
384
1.02M
  if (!deactivate_only) {
385
1.02M
    tablets_.clear();
386
1.02M
  }
387
1.02M
}
388
389
540k
void TableInfo::AddTabletUnlocked(const TabletInfoPtr& tablet) {
390
540k
  const auto& dirty = tablet->metadata().dirty();
391
540k
  if (dirty.is_deleted()) {
392
0
    return;
393
0
  }
394
540k
  const auto& tablet_meta = dirty.pb;
395
540k
  tablets_.emplace(tablet->id(), tablet.get());
396
397
540k
  if (dirty.is_hidden()) {
398
0
    return;
399
0
  }
400
401
540k
  const auto& partition_key_start = tablet_meta.partition().partition_key_start();
402
540k
  auto p = partitions_.emplace(partition_key_start, tablet.get());
403
540k
  if (p.second) {
404
540k
    return;
405
540k
  }
406
407
56
  auto it = p.first;
408
56
  auto old_tablet_lock = it->second->LockForRead();
409
56
  const auto old_split_depth = old_tablet_lock->pb.split_depth();
410
56
  if (tablet_meta.split_depth() > old_split_depth || 
old_tablet_lock->is_deleted()1
) {
411
55
    VLOG(1) << "Replacing tablet " << it->second->tablet_id()
412
0
            << " (split_depth = " << old_split_depth << ")"
413
0
            << " with tablet " << tablet->tablet_id()
414
0
            << " (split_depth = " << tablet_meta.split_depth() << ")";
415
55
    it->second = tablet.get();
416
55
    return;
417
55
  }
418
419
1
  LOG_IF(DFATAL, tablet_meta.split_depth() == old_split_depth)
420
0
      << "Two tablets with the same partition key start and split depth: "
421
0
      << tablet_meta.ShortDebugString() << " and " << old_tablet_lock->pb.ShortDebugString();
422
423
  // TODO: can we assert that the replaced tablet is not in Running state?
424
  // May be a little tricky since we don't know whether to look at its committed or
425
  // uncommitted state.
426
1
}
427
428
24.9k
bool TableInfo::RemoveTablet(const TabletId& tablet_id, DeactivateOnly deactivate_only) {
429
24.9k
  std::lock_guard<decltype(lock_)> l(lock_);
430
24.9k
  return RemoveTabletUnlocked(tablet_id, deactivate_only);
431
24.9k
}
432
433
0
bool TableInfo::RemoveTablets(const TabletInfos& tablets, DeactivateOnly deactivate_only) {
434
0
  std::lock_guard<decltype(lock_)> l(lock_);
435
0
  bool all_were_removed = true;
436
0
  for (const auto& tablet : tablets) {
437
0
    if (!RemoveTabletUnlocked(tablet->id(), deactivate_only)) {
438
0
      all_were_removed = false;
439
0
    }
440
0
  }
441
0
  return all_were_removed;
442
0
}
443
444
24.9k
bool TableInfo::RemoveTabletUnlocked(const TabletId& tablet_id, DeactivateOnly deactivate_only) {
445
24.9k
  auto it = tablets_.find(tablet_id);
446
24.9k
  if (it == tablets_.end()) {
447
0
    return false;
448
0
  }
449
24.9k
  bool result = false;
450
24.9k
  auto partitions_it = partitions_.find(
451
24.9k
      it->second->metadata().dirty().pb.partition().partition_key_start());
452
24.9k
  if (partitions_it != partitions_.end() && 
partitions_it->second == it->second24.9k
) {
453
24.8k
    partitions_.erase(partitions_it);
454
24.8k
    result = true;
455
24.8k
  }
456
24.9k
  if (!deactivate_only) {
457
4
    tablets_.erase(it);
458
4
  }
459
24.9k
  return result;
460
24.9k
}
461
462
228k
void TableInfo::GetTabletsInRange(const GetTableLocationsRequestPB* req, TabletInfos* ret) const {
463
228k
  if (req->has_include_inactive() && 
req->include_inactive()492
) {
464
0
    GetInactiveTabletsInRange(
465
0
        req->partition_key_start(), req->partition_key_end(),
466
0
        ret, req->max_returned_locations());
467
228k
  } else {
468
228k
    GetTabletsInRange(
469
228k
        req->partition_key_start(), req->partition_key_end(),
470
228k
        ret, req->max_returned_locations());
471
228k
  }
472
228k
}
473
474
void TableInfo::GetTabletsInRange(
475
    const std::string& partition_key_start, const std::string& partition_key_end,
476
228k
    TabletInfos* ret, const int32_t max_returned_locations) const {
477
228k
  SharedLock<decltype(lock_)> l(lock_);
478
228k
  decltype(partitions_)::const_iterator it, it_end;
479
228k
  if (partition_key_start.empty()) {
480
223k
    it = partitions_.begin();
481
223k
  } else {
482
5.08k
    it = partitions_.upper_bound(partition_key_start);
483
5.08k
    if (it != partitions_.begin()) {
484
5.02k
      --it;
485
5.02k
    }
486
5.08k
  }
487
228k
  if (partition_key_end.empty()) {
488
228k
    it_end = partitions_.end();
489
228k
  } else {
490
64
    it_end = partitions_.upper_bound(partition_key_end);
491
64
  }
492
493
228k
  int32_t count = 0;
494
628k
  for (; it != it_end && 
count < max_returned_locations407k
;
++it400k
) {
495
400k
    ret->push_back(it->second);
496
400k
    count++;
497
400k
  }
498
228k
}
499
500
void TableInfo::GetInactiveTabletsInRange(
501
    const std::string& partition_key_start, const std::string& partition_key_end,
502
0
    TabletInfos* ret, const int32_t max_returned_locations) const {
503
0
  SharedLock<decltype(lock_)> l(lock_);
504
0
  int32_t count = 0;
505
0
  for (const auto& p : tablets_) {
506
0
    if (count >= max_returned_locations) {
507
0
      break;
508
0
    }
509
0
    if (!partition_key_start.empty() &&
510
0
        p.second->metadata().dirty().pb.partition().partition_key_start() < partition_key_start) {
511
0
      continue;
512
0
    }
513
0
    if (!partition_key_end.empty() &&
514
0
        p.second->metadata().dirty().pb.partition().partition_key_start() > partition_key_end) {
515
0
      continue;
516
0
    }
517
0
    ret->push_back(p.second);
518
0
    count++;
519
0
  }
520
0
}
521
522
27.7k
bool TableInfo::IsAlterInProgress(uint32_t version) const {
523
27.7k
  SharedLock<decltype(lock_)> l(lock_);
524
74.7k
  for (const auto& e : partitions_) {
525
74.7k
    if (e.second->reported_schema_version(table_id_) < version) {
526
17.1k
      
VLOG_WITH_PREFIX_AND_FUNC0
(3)
527
0
          << "ALTER in progress due to tablet "
528
0
          << e.second->ToString() << " because reported schema "
529
0
          << e.second->reported_schema_version(table_id_) << " < expected " << version;
530
17.1k
      return true;
531
17.1k
    }
532
74.7k
  }
533
10.5k
  return false;
534
27.7k
}
535
536
4
bool TableInfo::AreAllTabletsHidden() const {
537
4
  SharedLock<decltype(lock_)> l(lock_);
538
12
  for (const auto& e : tablets_) {
539
12
    if (!e.second->LockForRead()->is_hidden()) {
540
0
      VLOG_WITH_PREFIX_AND_FUNC(4) << "Not hidden tablet: " << e.second->ToString();
541
0
      return false;
542
0
    }
543
12
  }
544
4
  return true;
545
4
}
546
547
16.5k
bool TableInfo::AreAllTabletsDeleted() const {
548
16.5k
  SharedLock<decltype(lock_)> l(lock_);
549
42.7k
  for (const auto& e : tablets_) {
550
42.7k
    if (!e.second->LockForRead()->is_deleted()) {
551
8.14k
      
VLOG_WITH_PREFIX_AND_FUNC0
(4) << "Not deleted tablet: " << e.second->ToString()0
;
552
8.14k
      return false;
553
8.14k
    }
554
42.7k
  }
555
8.42k
  return true;
556
16.5k
}
557
558
438k
bool TableInfo::IsCreateInProgress() const {
559
438k
  SharedLock<decltype(lock_)> l(lock_);
560
991k
  for (const auto& e : partitions_) {
561
991k
    auto tablet_info_lock = e.second->LockForRead();
562
991k
    if (!tablet_info_lock->is_running() && 
tablet_info_lock->pb.split_depth() == 035.7k
) {
563
31.3k
      return true;
564
31.3k
    }
565
991k
  }
566
407k
  return false;
567
438k
}
568
569
947
Status TableInfo::SetIsBackfilling() {
570
947
  const auto table_lock = LockForRead();
571
947
  std::lock_guard<decltype(lock_)> l(lock_);
572
947
  if (is_backfilling_) {
573
41
    return STATUS(AlreadyPresent, "Backfill already in progress", id(),
574
41
                  MasterError(MasterErrorPB::SPLIT_OR_BACKFILL_IN_PROGRESS));
575
41
  }
576
577
4.40k
  
for (const auto& tablet_it : partitions_)906
{
578
4.40k
    const auto& tablet = tablet_it.second;
579
4.40k
    if (tablet->LockForRead()->pb.state() != SysTabletsEntryPB::RUNNING) {
580
0
      return STATUS_EC_FORMAT(IllegalState,
581
0
                              MasterError(MasterErrorPB::SPLIT_OR_BACKFILL_IN_PROGRESS),
582
0
                              "Some tablets are not running, table_id: $0 tablet_id: $1",
583
0
                              id(), tablet->tablet_id());
584
0
    }
585
4.40k
  }
586
906
  is_backfilling_ = true;
587
906
  return Status::OK();
588
906
}
589
590
8.30k
void TableInfo::SetCreateTableErrorStatus(const Status& status) {
591
8.30k
  std::lock_guard<decltype(lock_)> l(lock_);
592
8.30k
  create_table_error_ = status;
593
8.30k
}
594
595
40.2k
Status TableInfo::GetCreateTableErrorStatus() const {
596
40.2k
  SharedLock<decltype(lock_)> l(lock_);
597
40.2k
  return create_table_error_;
598
40.2k
}
599
600
77.1M
std::size_t TableInfo::NumLBTasks() const {
601
77.1M
  SharedLock<decltype(lock_)> l(lock_);
602
77.1M
  return std::count_if(pending_tasks_.begin(),
603
77.1M
                       pending_tasks_.end(),
604
77.1M
                       [](auto task) 
{ return task->started_by_lb(); }270k
);
605
77.1M
}
606
607
0
std::size_t TableInfo::NumTasks() const {
608
0
  SharedLock<decltype(lock_)> l(lock_);
609
0
  return pending_tasks_.size();
610
0
}
611
612
15.9M
bool TableInfo::HasTasks() const {
613
15.9M
  SharedLock<decltype(lock_)> l(lock_);
614
18.4E
  VLOG_WITH_PREFIX_AND_FUNC(3) << AsString(pending_tasks_);
615
15.9M
  return !pending_tasks_.empty();
616
15.9M
}
617
618
10.8k
bool TableInfo::HasTasks(server::MonitoredTask::Type type) const {
619
10.8k
  SharedLock<decltype(lock_)> l(lock_);
620
10.8k
  for (auto task : pending_tasks_) {
621
7.36k
    if (task->type() == type) {
622
6.88k
      return true;
623
6.88k
    }
624
7.36k
  }
625
3.99k
  return false;
626
10.8k
}
627
628
421k
void TableInfo::AddTask(std::shared_ptr<server::MonitoredTask> task) {
629
421k
  bool abort_task = false;
630
421k
  {
631
421k
    std::lock_guard<decltype(lock_)> l(lock_);
632
421k
    if (
!closing_421k
) {
633
421k
      pending_tasks_.insert(task);
634
421k
      if (tasks_tracker_) {
635
421k
        tasks_tracker_->AddTask(task);
636
421k
      }
637
18.4E
    } else {
638
18.4E
      abort_task = true;
639
18.4E
    }
640
421k
  }
641
  // We need to abort these tasks without holding the lock because when a task is destroyed it tries
642
  // to acquire the same lock to remove itself from pending_tasks_.
643
421k
  if (abort_task) {
644
0
    task->AbortAndReturnPrevState(STATUS(Expired, "Table closing"));
645
0
  }
646
421k
}
647
648
421k
bool TableInfo::RemoveTask(const std::shared_ptr<server::MonitoredTask>& task) {
649
421k
  bool result;
650
421k
  {
651
421k
    std::lock_guard<decltype(lock_)> l(lock_);
652
421k
    pending_tasks_.erase(task);
653
421k
    result = pending_tasks_.empty();
654
421k
  }
655
421k
  VLOG
(1) << "Removed task " << task.get() << " " << task->description()52
;
656
421k
  return result;
657
421k
}
658
659
// Aborts tasks which have their rpc in progress, rest of them are aborted and also erased
660
// from the pending list.
661
13.9k
void TableInfo::AbortTasks() {
662
13.9k
  AbortTasksAndCloseIfRequested( /* close */ false);
663
13.9k
}
664
665
3.62k
void TableInfo::AbortTasksAndClose() {
666
3.62k
  AbortTasksAndCloseIfRequested( /* close */ true);
667
3.62k
}
668
669
17.5k
void TableInfo::AbortTasksAndCloseIfRequested(bool close) {
670
17.5k
  std::vector<std::shared_ptr<server::MonitoredTask>> abort_tasks;
671
17.5k
  {
672
17.5k
    std::lock_guard<decltype(lock_)> l(lock_);
673
17.5k
    if (close) {
674
3.62k
      closing_ = true;
675
3.62k
    }
676
17.5k
    abort_tasks.reserve(pending_tasks_.size());
677
17.5k
    abort_tasks.assign(pending_tasks_.cbegin(), pending_tasks_.cend());
678
17.5k
  }
679
17.5k
  if (abort_tasks.empty()) {
680
17.5k
    return;
681
17.5k
  }
682
68
  auto status = close ? 
STATUS1
(Expired, "Table closing") :
STATUS67
(Aborted, "Table closing");
683
  // We need to abort these tasks without holding the lock because when a task is destroyed it tries
684
  // to acquire the same lock to remove itself from pending_tasks_.
685
330
  for (const auto& task : abort_tasks) {
686
330
    
VLOG_WITH_FUNC0
(1)
687
0
        << (close ? "Close and abort" : "Abort") << " task " << task.get() << " "
688
0
        << task->description();
689
330
    task->AbortAndReturnPrevState(status);
690
330
  }
691
68
}
692
693
3.62k
void TableInfo::WaitTasksCompletion() {
694
3.62k
  int wait_time = 5;
695
3.62k
  while (1) {
696
3.62k
    std::vector<std::shared_ptr<server::MonitoredTask>> waiting_on_for_debug;
697
3.62k
    {
698
3.62k
      SharedLock<decltype(lock_)> l(lock_);
699
3.62k
      if (pending_tasks_.empty()) {
700
3.62k
        break;
701
3.62k
      } else 
if (VLOG_IS_ON(1))0
{
702
0
        waiting_on_for_debug.reserve(pending_tasks_.size());
703
0
        waiting_on_for_debug.assign(pending_tasks_.cbegin(), pending_tasks_.cend());
704
0
      }
705
3.62k
    }
706
0
    for (const auto& task : waiting_on_for_debug) {
707
0
      VLOG(1) << "Waiting for Aborting task " << task.get() << " " << task->description();
708
0
    }
709
0
    base::SleepForMilliseconds(wait_time);
710
0
    wait_time = std::min(wait_time * 5 / 4, 10000);
711
0
  }
712
3.62k
}
713
714
94.0M
std::unordered_set<std::shared_ptr<server::MonitoredTask>> TableInfo::GetTasks() {
715
94.0M
  SharedLock<decltype(lock_)> l(lock_);
716
94.0M
  return pending_tasks_;
717
94.0M
}
718
719
93.1M
std::size_t TableInfo::NumPartitions() const {
720
93.1M
  SharedLock<decltype(lock_)> l(lock_);
721
93.1M
  return partitions_.size();
722
93.1M
}
723
724
0
bool TableInfo::HasPartitions(const std::vector<PartitionKey> other) const {
725
0
  SharedLock<decltype(lock_)> l(lock_);
726
0
  if (partitions_.size() != other.size()) {
727
0
    return false;
728
0
  }
729
0
  int i = 0;
730
0
  for (const auto& entry : partitions_) {
731
0
    if (entry.first != other[i++]) {
732
0
      return false;
733
0
    }
734
0
  }
735
0
  return true;
736
0
}
737
738
94.7M
TabletInfos TableInfo::GetTablets(IncludeInactive include_inactive) const {
739
94.7M
  TabletInfos result;
740
94.7M
  SharedLock<decltype(lock_)> l(lock_);
741
94.7M
  if (include_inactive) {
742
185k
    result.reserve(tablets_.size());
743
1.04M
    for (const auto& p : tablets_) {
744
1.04M
      result.push_back(p.second);
745
1.04M
    }
746
94.5M
  } else {
747
94.5M
    result.reserve(partitions_.size());
748
99.9M
    for (const auto& p : partitions_) {
749
99.9M
      result.push_back(p.second);
750
99.9M
    }
751
94.5M
  }
752
94.7M
  return result;
753
94.7M
}
754
755
81
TabletInfoPtr TableInfo::GetColocatedTablet() const {
756
81
  SharedLock<decltype(lock_)> l(lock_);
757
81
  if (colocated() && !partitions_.empty()) {
758
81
    return partitions_.begin()->second;
759
81
  }
760
0
  return nullptr;
761
81
}
762
763
6.48k
IndexInfo TableInfo::GetIndexInfo(const TableId& index_id) const {
764
6.48k
  auto l = LockForRead();
765
24.3k
  for (const auto& index_info_pb : l->pb.indexes()) {
766
24.3k
    if (index_info_pb.table_id() == index_id) {
767
6.48k
      return IndexInfo(index_info_pb);
768
6.48k
    }
769
24.3k
  }
770
0
  return IndexInfo();
771
6.48k
}
772
773
1.77M
bool TableInfo::UsesTablespacesForPlacement() const {
774
1.77M
  auto l = LockForRead();
775
  // Global transaction table is excluded due to not having a tablespace id set.
776
1.77M
  bool is_transaction_table_using_tablespaces =
777
1.77M
      l->pb.table_type() == TRANSACTION_STATUS_TABLE_TYPE &&
778
1.77M
      
l->pb.has_transaction_table_tablespace_id()232k
;
779
1.77M
  bool is_regular_pgsql_table =
780
1.77M
      l->pb.table_type() == PGSQL_TABLE_TYPE && 
!IsColocatedUserTable()723k
&&
781
1.77M
      
l->namespace_id() != kPgSequencesDataNamespaceId723k
&&
782
1.77M
      
!IsColocatedParentTable()709k
;
783
1.77M
  return is_transaction_table_using_tablespaces || 
is_regular_pgsql_table1.76M
;
784
1.77M
}
785
786
597k
bool TableInfo::IsTablegroupParentTable() const {
787
597k
  return id().find(master::kTablegroupParentTableIdSuffix) != std::string::npos;
788
597k
}
789
790
1.30M
bool TableInfo::IsColocatedParentTable() const {
791
1.30M
  return id().find(master::kColocatedParentTableIdSuffix) != std::string::npos;
792
1.30M
}
793
794
5.14M
bool TableInfo::IsColocatedUserTable() const {
795
5.14M
  return colocated() && 
!IsColocatedParentTable()80.9k
&&
!IsTablegroupParentTable()75.8k
;
796
5.14M
}
797
798
48.4k
TablespaceId TableInfo::TablespaceIdForTableCreation() const {
799
48.4k
  SharedLock<decltype(lock_)> l(lock_);
800
48.4k
  return tablespace_id_for_table_creation_;
801
48.4k
}
802
803
186
void TableInfo::SetTablespaceIdForTableCreation(const TablespaceId& tablespace_id) {
804
186
  std::lock_guard<decltype(lock_)> l(lock_);
805
186
  tablespace_id_for_table_creation_ = tablespace_id;
806
186
}
807
808
47.5k
void PersistentTableInfo::set_state(SysTablesEntryPB::State state, const string& msg) {
809
47.5k
  
VLOG_WITH_FUNC8
(2) << "Setting state for " << name() << " to "
810
8
                    << SysTablesEntryPB::State_Name(state) << " reason: " << msg;
811
47.5k
  pb.set_state(state);
812
47.5k
  pb.set_state_msg(msg);
813
47.5k
}
814
815
6
bool PersistentTableInfo::is_index() const {
816
6
  return !indexed_table_id().empty();
817
6
}
818
819
574k
const std::string& PersistentTableInfo::indexed_table_id() const {
820
574k
  static const std::string kEmptyString;
821
574k
  return pb.has_index_info()
822
574k
             ? 
pb.index_info().indexed_table_id()21.6k
823
574k
             : 
pb.has_indexed_table_id()552k
?
pb.indexed_table_id()0
:
kEmptyString552k
;
824
574k
}
825
826
827
// ================================================================================================
828
// DeletedTableInfo
829
// ================================================================================================
830
831
0
DeletedTableInfo::DeletedTableInfo(const TableInfo* table) : table_id_(table->id()) {
832
0
  auto tablets = table->GetTablets();
833
834
0
  for (const scoped_refptr<TabletInfo>& tablet : tablets) {
835
0
    auto tablet_lock = tablet->LockForRead();
836
0
    auto replica_locations = tablet->GetReplicaLocations();
837
838
0
    for (const TabletReplicaMap::value_type& r : *replica_locations) {
839
0
      tablet_set_.insert(TabletSet::value_type(
840
0
          r.second.ts_desc->permanent_uuid(), tablet->id()));
841
0
    }
842
0
  }
843
0
}
844
845
0
std::size_t DeletedTableInfo::NumTablets() const {
846
0
  std::lock_guard<simple_spinlock> l(lock_);
847
0
  return tablet_set_.size();
848
0
}
849
850
0
bool DeletedTableInfo::HasTablets() const {
851
0
  std::lock_guard<simple_spinlock> l(lock_);
852
0
  return !tablet_set_.empty();
853
0
}
854
855
0
void DeletedTableInfo::DeleteTablet(const TabletKey& key) {
856
0
  std::lock_guard<simple_spinlock> l(lock_);
857
0
  tablet_set_.erase(key);
858
0
}
859
860
0
void DeletedTableInfo::AddTabletsToMap(DeletedTabletMap* tablet_map) {
861
0
  std::lock_guard<simple_spinlock> l(lock_);
862
0
  for (const TabletKey& key : tablet_set_) {
863
0
    tablet_map->insert(DeletedTabletMap::value_type(key, this));
864
0
  }
865
0
}
866
867
// ================================================================================================
868
// NamespaceInfo
869
// ================================================================================================
870
871
15.5k
NamespaceInfo::NamespaceInfo(NamespaceId ns_id) : namespace_id_(std::move(ns_id)) {}
872
873
1.07M
const NamespaceName& NamespaceInfo::name() const {
874
1.07M
  return LockForRead()->pb.name();
875
1.07M
}
876
877
233k
YQLDatabase NamespaceInfo::database_type() const {
878
233k
  return LockForRead()->pb.database_type();
879
233k
}
880
881
17.7k
bool NamespaceInfo::colocated() const {
882
17.7k
  return LockForRead()->pb.colocated();
883
17.7k
}
884
885
158k
::yb::master::SysNamespaceEntryPB_State NamespaceInfo::state() const {
886
158k
  return LockForRead()->pb.state();
887
158k
}
888
889
31.0k
string NamespaceInfo::ToString() const {
890
31.0k
  return Substitute("$0 [id=$1]", name(), namespace_id_);
891
31.0k
}
892
893
// ================================================================================================
894
// TablegroupInfo
895
// ================================================================================================
896
897
TablegroupInfo::TablegroupInfo(TablegroupId tablegroup_id, NamespaceId namespace_id) :
898
57
                               tablegroup_id_(tablegroup_id), namespace_id_(namespace_id) {}
899
900
92
void TablegroupInfo::AddChildTable(const TableId& table_id, ColocationId colocation_id) {
901
92
  std::lock_guard<simple_spinlock> l(lock_);
902
92
  if (ContainsKey(table_map_.left, table_id)) {
903
0
    LOG(WARNING) << "Tablegroup " << tablegroup_id_ << " already contains a table with ID "
904
0
                 << table_id;
905
92
  } else if (ContainsKey(table_map_.right, colocation_id)) {
906
0
    LOG(WARNING) << "Tablegroup " << tablegroup_id_ << " already contains a table with "
907
0
                 << "colocation ID " << colocation_id;
908
92
  } else {
909
92
    table_map_.insert(TableMap::value_type(table_id, colocation_id));
910
92
  }
911
92
}
912
913
68
void TablegroupInfo::DeleteChildTable(const TableId& table_id) {
914
68
  std::lock_guard<simple_spinlock> l(lock_);
915
68
  auto left_map = table_map_.left;
916
68
  if (ContainsKey(left_map, table_id)) {
917
68
    left_map.erase(table_id);
918
68
  } else {
919
0
    LOG(WARNING) << "Tablegroup " << tablegroup_id_ << " does not contains a table with ID "
920
0
                 << table_id;
921
0
  }
922
68
}
923
924
0
bool TablegroupInfo::HasChildTables() const {
925
0
  std::lock_guard<simple_spinlock> l(lock_);
926
0
  return !table_map_.empty();
927
0
}
928
929
930
107
bool TablegroupInfo::HasChildTable(ColocationId colocation_id) const {
931
107
  std::lock_guard<simple_spinlock> l(lock_);
932
107
  return ContainsKey(table_map_.right, colocation_id);
933
107
}
934
935
936
40
std::size_t TablegroupInfo::NumChildTables() const {
937
40
  std::lock_guard<simple_spinlock> l(lock_);
938
40
  return table_map_.size();
939
40
}
940
941
0
std::unordered_set<TableId> TablegroupInfo::ChildTables() const {
942
0
  std::lock_guard<simple_spinlock> l(lock_);
943
0
  std::unordered_set<TableId> result;
944
0
  for (auto iter = table_map_.left.begin(), iend = table_map_.left.end(); iter != iend; ++iter) {
945
0
    result.insert(iter->first);
946
0
  }
947
0
  return result;
948
0
}
949
950
// ================================================================================================
951
// UDTypeInfo
952
// ================================================================================================
953
954
48
UDTypeInfo::UDTypeInfo(UDTypeId udtype_id) : udtype_id_(std::move(udtype_id)) { }
955
956
469
const UDTypeName& UDTypeInfo::name() const {
957
469
  return LockForRead()->pb.name();
958
469
}
959
960
227
const NamespaceName& UDTypeInfo::namespace_id() const {
961
227
  return LockForRead()->pb.namespace_id();
962
227
}
963
964
699
int UDTypeInfo::field_names_size() const {
965
699
  return LockForRead()->pb.field_names_size();
966
699
}
967
968
472
const string& UDTypeInfo::field_names(int index) const {
969
472
  return LockForRead()->pb.field_names(index);
970
472
}
971
972
699
int UDTypeInfo::field_types_size() const {
973
699
  return LockForRead()->pb.field_types_size();
974
699
}
975
976
472
const QLTypePB& UDTypeInfo::field_types(int index) const {
977
472
  return LockForRead()->pb.field_types(index);
978
472
}
979
980
141
string UDTypeInfo::ToString() const {
981
141
  auto l = LockForRead();
982
141
  return Format("$0 [id=$1] {metadata=$2} ", name(), udtype_id_, l->pb);
983
141
}
984
985
DdlLogEntry::DdlLogEntry(
986
    HybridTime time, const TableId& table_id, const SysTablesEntryPB& table,
987
7.60k
    const std::string& action) {
988
7.60k
  pb_.set_time(time.ToUint64());
989
7.60k
  pb_.set_table_type(table.table_type());
990
7.60k
  pb_.set_namespace_name(table.namespace_name());
991
7.60k
  pb_.set_namespace_id(table.namespace_id());
992
7.60k
  pb_.set_table_name(table.name());
993
7.60k
  pb_.set_table_id(table_id);
994
7.60k
  pb_.set_action(action);
995
7.60k
}
996
997
6.48k
const DdlLogEntryPB& DdlLogEntry::old_pb() const {
998
  // Since DDL log entry are always added, we don't have previous PB for the same entry.
999
6.48k
  static const DdlLogEntryPB kEmpty;
1000
6.48k
  return kEmpty;
1001
6.48k
}
1002
1003
6.48k
const DdlLogEntryPB& DdlLogEntry::new_pb() const {
1004
6.48k
  return pb_;
1005
6.48k
}
1006
1007
6.48k
std::string DdlLogEntry::id() const {
1008
6.48k
  return DocHybridTime(HybridTime(pb_.time()), kMaxWriteId).EncodedInDocDbFormat();
1009
6.48k
}
1010
1011
}  // namespace master
1012
}  // namespace yb