YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/tools/yb-ysck.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
// Command line tool to run Ysck against a cluster. Defaults to running against a local Master
33
// on the default RPC port. It verifies that all the reported Tablet Servers are running and that
34
// the tablets are in a consistent state.
35
36
#include <gflags/gflags.h>
37
#include <glog/logging.h>
38
39
#include "yb/gutil/strings/split.h"
40
#include "yb/gutil/strings/substitute.h"
41
42
#include "yb/master/master_defaults.h"
43
44
#include "yb/tools/ysck_remote.h"
45
46
#include "yb/util/flags.h"
47
#include "yb/util/logging.h"
48
49
0
#define PUSH_PREPEND_NOT_OK(s, statuses, msg) do { \
50
0
  ::yb::Status _s = (s); \
51
0
  if (PREDICT_FALSE(!_s.ok())) { \
52
0
    statuses->push_back(string(msg) + ": " + _s.ToString()); \
53
0
  } \
54
0
} while (0);
55
56
using std::cerr;
57
using std::cout;
58
using std::endl;
59
using std::shared_ptr;
60
using std::vector;
61
using strings::Substitute;
62
63
DEFINE_string(master_address, "",
64
              "Address of master server to run against.");
65
66
DEFINE_bool(checksum_scan, false,
67
            "Perform a checksum scan on data in the cluster.");
68
69
DEFINE_string(tables, "",
70
              "Tables to check (comma-separated list of names). "
71
              "If not specified, checks all tables.");
72
73
DEFINE_string(tablets, "",
74
              "Tablets to check (comma-separated list of IDs) "
75
              "If not specified, checks all tablets.");
76
77
namespace yb {
78
namespace tools {
79
80
0
static string GetYsckUsage(const char* progname) {
81
0
  string msg = Substitute("Usage: $0 --master_address=<addr> <flags>\n\n", progname);
82
0
  msg += "Check the health of a YB cluster.\n\n"
83
0
         "By default, ysck checks that master and tablet server processes are running,\n"
84
0
         "and that table metadata is consistent. Use the 'checksum' flag to check that\n"
85
0
         "tablet data is consistent (also see the 'tables' and 'tablets' flags below).\n"
86
0
         "Use the 'checksum_snapshot' along with 'checksum' if the table or tablets are\n"
87
0
         "actively receiving inserts or updates.";
88
0
  return msg;
89
0
}
90
91
// Run ysck.
92
// Error information is appended to the provided vector.
93
// If the vector is empty upon completion, ysck ran successfully.
94
0
static void RunYsck(vector<string>* error_messages) {
95
0
  std::vector<HostPort> master_addrs;
96
0
  PUSH_PREPEND_NOT_OK(
97
0
      HostPort::ParseStrings(FLAGS_master_address, master::kMasterDefaultPort, &master_addrs),
98
0
      error_messages, "Unable to parse master address");
99
100
0
  shared_ptr<YsckMaster> master;
101
0
  PUSH_PREPEND_NOT_OK(RemoteYsckMaster::Build(master_addrs[0], &master),
102
0
                      error_messages, "Unable to build YsckMaster");
103
0
  if (!error_messages->empty()) return;
104
0
  shared_ptr<YsckCluster> cluster(new YsckCluster(master));
105
0
  shared_ptr<Ysck> ysck(new Ysck(cluster));
106
107
  // This is required for everything below.
108
0
  PUSH_PREPEND_NOT_OK(ysck->CheckMasterRunning(), error_messages,
109
0
                      "Master aliveness check error");
110
0
  if (!error_messages->empty()) return;
111
112
  // This is also required for everything below.
113
0
  PUSH_PREPEND_NOT_OK(ysck->FetchTableAndTabletInfo(), error_messages,
114
0
                      "Error fetching the cluster metadata from the Master server");
115
0
  if (!error_messages->empty()) return;
116
117
0
  PUSH_PREPEND_NOT_OK(ysck->CheckTabletServersRunning(), error_messages,
118
0
                      "Tablet server aliveness check error");
119
120
  // TODO: Add support for tables / tablets filter in the consistency check.
121
0
  PUSH_PREPEND_NOT_OK(ysck->CheckTablesConsistency(), error_messages,
122
0
                      "Table consistency check error");
123
124
0
  if (FLAGS_checksum_scan) {
125
0
    vector<string> tables = strings::Split(FLAGS_tables, ",", strings::SkipEmpty());
126
0
    vector<string> tablets = strings::Split(FLAGS_tablets, ",", strings::SkipEmpty());
127
0
    PUSH_PREPEND_NOT_OK(ysck->ChecksumData(tables, tablets, ChecksumOptions()),
128
0
                        error_messages, "Checksum scan error");
129
0
  }
130
0
}
131
132
} // namespace tools
133
} // namespace yb
134
135
int main(int argc, char** argv) {
136
  google::SetUsageMessage(yb::tools::GetYsckUsage(argv[0]));
137
  if (argc < 2) {
138
    google::ShowUsageWithFlagsRestrict(argv[0], __FILE__);
139
    exit(1);
140
  }
141
  yb::ParseCommandLineFlags(&argc, &argv, true);
142
  FLAGS_logtostderr = true;
143
  yb::InitGoogleLoggingSafe(argv[0]);
144
145
  vector<string> error_messages;
146
  yb::tools::RunYsck(&error_messages);
147
148
  // All good.
149
  if (error_messages.empty()) {
150
    cout << "OK" << endl;
151
    return 0;
152
  }
153
154
  // Something went wrong.
155
  cerr << "==================" << endl;
156
  cerr << "Errors:" << endl;
157
  cerr << "==================" << endl;
158
  for (const string& s : error_messages) {
159
    cerr << s << endl;
160
  }
161
  cerr << endl;
162
  cerr << "FAILED" << endl;
163
  return 1;
164
}