YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/master/scoped_leader_shared_lock.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
#include "yb/master/scoped_leader_shared_lock.h"
33
34
#include "yb/consensus/consensus.h"
35
#include "yb/consensus/metadata.pb.h"
36
37
#include "yb/master/catalog_manager.h"
38
#include "yb/master/master.h"
39
#include "yb/master/sys_catalog.h"
40
41
#include "yb/tablet/tablet_peer.h"
42
43
#include "yb/util/debug-util.h"
44
#include "yb/util/shared_lock.h"
45
#include "yb/util/status_format.h"
46
#include "yb/util/tsan_util.h"
47
48
using namespace std::literals;
49
50
constexpr int32_t kMasterLogLockWarningMsDefault =
51
    ::yb::RegularBuildVsSanitizers<int32_t>(1000, 3000);
52
53
DEFINE_int32(master_log_lock_warning_ms, kMasterLogLockWarningMsDefault,
54
             "Print warnings if the master leader shared lock is held for longer than this amount "
55
             "of time. Note that this is a shared lock, so these warnings simply indicate "
56
             "long-running master operations that could delay system catalog loading by a new "
57
             "master leader.");
58
59
constexpr int32_t kMasterLeaderLockStackTraceMsDefault =
60
    ::yb::RegularBuildVsSanitizers<int32_t>(3000, 9000);
61
62
DEFINE_int32(master_leader_lock_stack_trace_ms, kMasterLeaderLockStackTraceMsDefault,
63
             "Dump a stack trace if the master leader shared lock is held for longer than this "
64
             "of time. Also see master_log_lock_warning_ms.");
65
66
using yb::consensus::Consensus;
67
using yb::consensus::ConsensusStatePB;
68
69
using yb::consensus::CONSENSUS_CONFIG_COMMITTED;
70
71
namespace yb {
72
namespace master {
73
74
ScopedLeaderSharedLock::ScopedLeaderSharedLock(
75
    CatalogManager* catalog,
76
    const char* file_name,
77
    int line_number,
78
    const char* function_name)
79
    : catalog_(DCHECK_NOTNULL(catalog)),
80
      leader_shared_lock_(catalog->leader_lock_, std::try_to_lock),
81
      start_(std::chrono::steady_clock::now()),
82
      file_name_(file_name),
83
      line_number_(line_number),
84
40.6M
      function_name_(function_name) {
85
40.6M
  int64_t catalog_leader_ready_term;
86
40.6M
  {
87
    // Check if the catalog manager is running.
88
40.6M
    std::lock_guard<simple_spinlock> l(catalog_->state_lock_);
89
40.6M
    if (PREDICT_FALSE(catalog_->state_ != CatalogManager::kRunning)) {
90
522k
      catalog_status_ = STATUS_SUBSTITUTE(ServiceUnavailable,
91
522k
          "Catalog manager is not initialized. State: $0", catalog_->state_);
92
522k
      return;
93
522k
    }
94
40.1M
    catalog_leader_ready_term = catalog_->leader_ready_term_;
95
40.1M
  }
96
97
0
  string uuid = catalog_->master_->fs_manager()->uuid();
98
40.1M
  if (PREDICT_FALSE(catalog_->master_->IsShellMode())) {
99
    // Consensus and other internal fields should not be checked when in shell mode as they may be
100
    // in transition.
101
317
    leader_status_ = STATUS_SUBSTITUTE(IllegalState,
102
317
        "Catalog manager of $0 is in shell mode, not the leader.", uuid);
103
317
    return;
104
317
  }
105
106
  // Check if the catalog manager is the leader.
107
40.1M
  Consensus* consensus = catalog_->sys_catalog_->tablet_peer()->consensus();
108
40.1M
  ConsensusStatePB cstate = consensus->ConsensusState(CONSENSUS_CONFIG_COMMITTED);
109
40.1M
  if (PREDICT_FALSE(!cstate.has_leader_uuid() || cstate.leader_uuid() != uuid)) {
110
29.8M
    leader_status_ = STATUS_FORMAT(IllegalState,
111
29.8M
                                   "Not the leader. Local UUID: $0, Consensus state: $1",
112
29.8M
                                   uuid, cstate);
113
29.8M
    return;
114
29.8M
  }
115
  // TODO: deduplicate the leadership check above and below (one is committed, one is active).
116
10.2M
  const Status s = consensus->CheckIsActiveLeaderAndHasLease();
117
10.2M
  if (!s.ok()) {
118
4.21k
    leader_status_ = s;
119
4.21k
    return;
120
4.21k
  }
121
10.2M
  if (PREDICT_FALSE(catalog_leader_ready_term != cstate.current_term())) {
122
    // Normally we use LeaderNotReadyToServe to indicate that the leader has not replicated its
123
    // NO_OP entry or the previous leader's lease has not expired yet, and the handling logic is to
124
    // to retry on the same server.
125
598k
    leader_status_ = STATUS_SUBSTITUTE(LeaderNotReadyToServe,
126
598k
        "Leader not yet ready to serve requests: "
127
598k
        "leader_ready_term_ = $0; cstate.current_term = $1",
128
598k
        catalog_leader_ready_term, cstate.current_term());
129
598k
    return;
130
598k
  }
131
9.63M
  if (PREDICT_FALSE(!leader_shared_lock_.owns_lock())) {
132
16
    leader_status_ = STATUS_SUBSTITUTE(ServiceUnavailable,
133
16
        "Couldn't get leader_lock_ in shared mode. Leader still loading catalog tables."
134
16
        "leader_ready_term_ = $0; cstate.current_term = $1",
135
16
        catalog_leader_ready_term, cstate.current_term());
136
16
    return;
137
16
  }
138
9.63M
}
139
140
ScopedLeaderSharedLock::ScopedLeaderSharedLock(
141
    enterprise::CatalogManager* catalog,
142
    const char* file_name,
143
    int line_number,
144
    const char* function_name)
145
    : ScopedLeaderSharedLock(
146
40.4M
          static_cast<CatalogManager*>(catalog), file_name, line_number, function_name) {
147
40.4M
}
Unexecuted instantiation: yb::master::ScopedLeaderSharedLock::ScopedLeaderSharedLock(yb::master::enterprise::CatalogManager*, char const*, int, char const*)
yb::master::ScopedLeaderSharedLock::ScopedLeaderSharedLock(yb::master::enterprise::CatalogManager*, char const*, int, char const*)
Line
Count
Source
146
40.4M
          static_cast<CatalogManager*>(catalog), file_name, line_number, function_name) {
147
40.4M
}
148
149
40.6M
ScopedLeaderSharedLock::~ScopedLeaderSharedLock() {
150
40.6M
  Unlock();
151
40.6M
}
152
153
43.2M
void ScopedLeaderSharedLock::Unlock() {
154
43.2M
  if (leader_shared_lock_.owns_lock()) {
155
40.0M
    {
156
40.0M
      decltype(leader_shared_lock_) lock;
157
40.0M
      lock.swap(leader_shared_lock_);
158
40.0M
    }
159
40.0M
    auto finish = std::chrono::steady_clock::now();
160
161
40.0M
    bool need_stack_trace = finish > start_ + 1ms * FLAGS_master_leader_lock_stack_trace_ms;
162
40.0M
    bool need_warning =
163
40.0M
        
need_stack_trace40.0M
|| (finish > start_ + 1ms * FLAGS_master_log_lock_warning_ms);
164
40.0M
    if (need_warning) {
165
5.29k
      LOG(WARNING)
166
5.29k
          << "Long lock of catalog manager (" << file_name_ << ":" << line_number_ << ", "
167
5.29k
          << function_name_ << "): " << AsString(finish - start_)
168
5.29k
          << (need_stack_trace ? 
"\n" + GetStackTrace()1.07k
:
""4.21k
);
169
5.29k
    }
170
40.0M
  }
171
43.2M
}
172
173
}  // namespace master
174
}  // namespace yb