YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/master/master_tablet_service.cc
Line
Count
Source (jump to first uncovered line)
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 "yb/master/master_tablet_service.h"
15
16
#include "yb/common/common_flags.h"
17
#include "yb/common/entity_ids.h"
18
#include "yb/common/wire_protocol.h"
19
20
#include "yb/master/catalog_manager_if.h"
21
#include "yb/master/master.h"
22
#include "yb/master/scoped_leader_shared_lock.h"
23
#include "yb/master/scoped_leader_shared_lock-internal.h"
24
25
#include "yb/rpc/rpc_context.h"
26
27
#include "yb/util/flag_tags.h"
28
#include "yb/util/logging.h"
29
#include "yb/util/result.h"
30
#include "yb/util/status_format.h"
31
32
DEFINE_test_flag(int32, ysql_catalog_write_rejection_percentage, 0,
33
                 "Reject specified percentage of writes to the YSQL catalog tables.");
34
TAG_FLAG(TEST_ysql_catalog_write_rejection_percentage, runtime);
35
36
using namespace std::chrono_literals;
37
38
namespace yb {
39
namespace master {
40
41
// Only SysTablet 0 is bootstrapped on all master peers, and only the master leader
42
// reads other sys tablets. We check only for tablet 0 so as to have same readiness
43
// level across all masters.
44
// Note: If this value changes, then IsTabletServerReady has to be revisited.
45
constexpr int NUM_TABLETS_SYS_CATALOG = 1;
46
47
MasterTabletServiceImpl::MasterTabletServiceImpl(MasterTabletServer* server, Master* master)
48
5.42k
    : TabletServiceImpl(server), master_(master) {
49
5.42k
}
50
51
Result<std::shared_ptr<tablet::AbstractTablet>> MasterTabletServiceImpl::GetTabletForRead(
52
  const TabletId& tablet_id, tablet::TabletPeerPtr tablet_peer,
53
640k
  YBConsistencyLevel consistency_level, tserver::AllowSplitTablet allow_split_tablet) {
54
  // Ignore looked_up_tablet_peer.
55
56
640k
  SCOPED_LEADER_SHARED_LOCK(l, master_->catalog_manager_impl());
57
640k
  RETURN_NOT_OK(l.first_failed_status());
58
59
640k
  return master_->catalog_manager()->GetSystemTablet(tablet_id);
60
640k
}
61
62
void MasterTabletServiceImpl::Write(const tserver::WriteRequestPB* req,
63
                                    tserver::WriteResponsePB* resp,
64
44.1k
                                    rpc::RpcContext context) {
65
44.1k
  SCOPED_LEADER_SHARED_LOCK(l, master_->catalog_manager_impl());
66
44.1k
  if (!l.CheckIsInitializedAndIsLeaderOrRespondTServer(resp, &context)) {
67
0
    return;
68
0
  }
69
70
44.1k
  if (PREDICT_FALSE(FLAGS_TEST_ysql_catalog_write_rejection_percentage > 0) &&
71
202
      req->pgsql_write_batch_size() > 0 &&
72
202
      RandomUniformInt(1, 99) <= FLAGS_TEST_ysql_catalog_write_rejection_percentage) {
73
11
    context.RespondRpcFailure(rpc::ErrorStatusPB::ERROR_APPLICATION,
74
11
        STATUS(InternalError, "Injected random failure for testing."));
75
11
      return;
76
11
  }
77
78
44.1k
  bool log_versions = false;
79
216k
  for (const auto& pg_req : req->pgsql_write_batch()) {
80
216k
    if (pg_req.is_ysql_catalog_change()) {
81
0
      const auto &res = master_->catalog_manager()->IncrementYsqlCatalogVersion();
82
0
      if (!res.ok()) {
83
0
        context.RespondRpcFailure(rpc::ErrorStatusPB::ERROR_APPLICATION,
84
0
            STATUS(InternalError, "Failed to increment YSQL catalog version"));
85
0
      }
86
216k
    } else if (FLAGS_log_ysql_catalog_versions && pg_req.table_id() == kPgYbCatalogVersionTableId) {
87
0
      log_versions = true;
88
0
    }
89
216k
  }
90
91
44.1k
  tserver::TabletServiceImpl::Write(req, resp, std::move(context));
92
93
44.1k
  if (log_versions) {
94
0
    uint64_t catalog_version;
95
0
    uint64_t last_breaking_version;
96
    // The above Write is async, so delay a bit to hopefully read the newly written values.  If the
97
    // delay was not sufficient, it's not a big deal since this is just for logging.
98
0
    SleepFor(100ms);
99
0
    if (!master_->catalog_manager()->GetYsqlCatalogVersion(&catalog_version,
100
0
                                                           &last_breaking_version).ok()) {
101
0
      LOG_WITH_FUNC(ERROR) << "failed to get catalog version, ignoring";
102
0
    } else {
103
0
      LOG_WITH_FUNC(INFO) << "catalog version: " << catalog_version << ", breaking version: "
104
0
                          << last_breaking_version;
105
0
    }
106
0
  }
107
44.1k
}
108
109
void MasterTabletServiceImpl::IsTabletServerReady(
110
    const tserver::IsTabletServerReadyRequestPB* req,
111
    tserver::IsTabletServerReadyResponsePB* resp,
112
9
    rpc::RpcContext context) {
113
9
  SCOPED_LEADER_SHARED_LOCK(l, master_->catalog_manager_impl());
114
9
  int total_tablets = NUM_TABLETS_SYS_CATALOG;
115
9
  resp->set_total_tablets(total_tablets);
116
9
  resp->set_num_tablets_not_running(total_tablets);
117
118
  // Tablet 0 being ready corresponds to state_ = kRunning in catalog manager.
119
  // If catalog_status_ in not OK, then catalog manager state_ is not kRunning.
120
9
  if (!l.CheckIsInitializedOrRespondTServer(resp, &context, false /* set_error */)) {
121
0
    LOG(INFO) << "Zero tablets not running out of " << total_tablets;
122
9
  } else {
123
9
    LOG(INFO) << "All " << total_tablets << " tablets running.";
124
9
    resp->set_num_tablets_not_running(0);
125
9
    context.RespondSuccess();
126
9
  }
127
9
}
128
129
namespace {
130
131
0
void HandleUnsupportedMethod(const char* method_name, rpc::RpcContext* context) {
132
0
  context->RespondRpcFailure(rpc::ErrorStatusPB::ERROR_APPLICATION,
133
0
                             STATUS_FORMAT(NotSupported, "$0 Not Supported!", method_name));
134
0
}
135
136
} // namespace
137
138
void MasterTabletServiceImpl::ListTablets(const tserver::ListTabletsRequestPB* req,
139
                                          tserver::ListTabletsResponsePB* resp,
140
0
                                          rpc::RpcContext context)  {
141
0
  HandleUnsupportedMethod("ListTablets", &context);
142
0
}
143
144
void MasterTabletServiceImpl::ListTabletsForTabletServer(
145
    const tserver::ListTabletsForTabletServerRequestPB* req,
146
    tserver::ListTabletsForTabletServerResponsePB* resp,
147
0
    rpc::RpcContext context)  {
148
0
  HandleUnsupportedMethod("ListTabletsForTabletServer", &context);
149
0
}
150
151
void MasterTabletServiceImpl::GetLogLocation(const tserver::GetLogLocationRequestPB* req,
152
                                             tserver::GetLogLocationResponsePB* resp,
153
0
                                             rpc::RpcContext context)  {
154
0
  HandleUnsupportedMethod("GetLogLocation", &context);
155
0
}
156
157
void MasterTabletServiceImpl::Checksum(const tserver::ChecksumRequestPB* req,
158
                                       tserver::ChecksumResponsePB* resp,
159
0
                                       rpc::RpcContext context)  {
160
0
  HandleUnsupportedMethod("Checksum", &context);
161
0
}
162
163
} // namespace master
164
} // namespace yb