This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push:
new 6131a8b61 [Tool] Show the information of a tablet
6131a8b61 is described below
commit 6131a8b61411f787a47aef953d6b6f4e6a2d0713
Author: xinghuayu007 <[email protected]>
AuthorDate: Wed Feb 15 10:30:57 2023 +0800
[Tool] Show the information of a tablet
This tool is used to show the table name and all replicas on
different tablet servers according to the tablet id.
Sometimes, the log prints the tablet id when a query failed or
the system got something wrong. But it is difficult to find
useful information according to the tablet id.
This tool will be helpful for debuging. The following is an
example:
Command: kudu tablet info $master_address $tablet_id
The result is:
ID | Table Name | Tablet Server UUID | Host | Port | Is Leader
-----+------------+--------------------+------+-------+----
abc | test_table | xxxxx | host1| 43689 | V
abd | test_table | xxxx1 | host2| 43035 | L
dbe | test_table | xxxx2 | host3| 35209 | V
Change-Id: Ib5ae5f61f50a44c4787843df76adaa61700ae9fe
Reviewed-on: http://gerrit.cloudera.org:8080/19501
Tested-by: Kudu Jenkins
Reviewed-by: Yingchun Lai <[email protected]>
---
src/kudu/client/client.h | 6 ++++
src/kudu/tools/kudu-tool-test.cc | 64 ++++++++++++++++++++++++++++++++++
src/kudu/tools/tool_action_tablet.cc | 66 +++++++++++++++++++++++++++++++++++-
3 files changed, 135 insertions(+), 1 deletion(-)
diff --git a/src/kudu/client/client.h b/src/kudu/client/client.h
index a1702ab13..8de0dc8da 100644
--- a/src/kudu/client/client.h
+++ b/src/kudu/client/client.h
@@ -85,6 +85,8 @@ class LeaderMasterProxy;
class RemoteKsckCluster;
class TableAlter;
class TableLister;
+Status ShowTabletInfo(const std::vector<std::string>& master_addresses,
+ const std::vector<std::string>& tablet_id);
} // namespace tools
namespace client {
@@ -1086,6 +1088,8 @@ class KUDU_EXPORT KuduClient : public
sp::enable_shared_from_this<KuduClient> {
friend class tools::RemoteKsckCluster;
friend class tools::TableLister;
friend class ScanTokenTest;
+ friend Status tools::ShowTabletInfo(const std::vector<std::string>&
master_addresses,
+ const std::vector<std::string>&
tablet_id);
FRIEND_TEST(kudu::ClientStressTest, TestUniqueClientIds);
FRIEND_TEST(kudu::MetaCacheLookupStressTest, PerfSynthetic);
@@ -1152,6 +1156,8 @@ class KUDU_EXPORT KuduTabletServer {
friend class KuduClient;
friend class KuduScanner;
friend class KuduScanTokenBuilder;
+ friend Status tools::ShowTabletInfo(const std::vector<std::string>&
master_addresses,
+ const std::vector<std::string>&
tablet_id);
KuduTabletServer();
diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index 00c0183d0..9bcbd91ab 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -1603,11 +1603,13 @@ TEST_F(ToolTest, TestModeHelp) {
"change_config.*Change.*Raft configuration",
"leader_step_down.*Change.*tablet's leader",
"unsafe_replace_tablet.*Replace a tablet with an empty one",
+ "info.*Show information of the table which the tablets"
};
NO_FATALS(RunTestHelp(kCmd, kTabletModeRegexes));
NO_FATALS(RunTestHelpRpcFlags(kCmd,
{ "leader_step_down",
"unsafe_replace_tablet",
+ "info"
}));
}
{
@@ -4222,6 +4224,68 @@ TEST_F(ToolTest, TestPerfTabletScan) {
}
}
+TEST_F(ToolTest, TestTabletInfo) {
+ ExternalMiniClusterOptions opts;
+ const int kNumTabletServers = 3;
+ const int kNumReplicas = 3;
+ const int kNumTablets = 3;
+ opts.num_tablet_servers = kNumTabletServers;
+ const string& kTableName = "test_table";
+ MonoDelta kTimeout = MonoDelta::FromSeconds(30);
+ NO_FATALS(StartExternalMiniCluster(std::move(opts)));
+
+ TestWorkload workload(cluster_.get());
+ workload.set_num_tablets(kNumTablets);
+ workload.set_num_replicas(kNumReplicas);
+ workload.set_table_name(kTableName);
+ workload.Setup();
+
+ vector<ListTabletsResponsePB::StatusAndSchemaPB> tablets;
+ TServerDetails* ts = ts_map_[cluster_->tablet_server(0)->uuid()];
+ ASSERT_OK(WaitForNumTabletsOnTS(ts, kNumTablets, kTimeout, &tablets));
+
+ vector<string> master_addrs;
+ for (const auto& hp : cluster_->master_rpc_addrs()) {
+ master_addrs.emplace_back(hp.ToString());
+ }
+ const string& master_addrs_str = JoinStrings(master_addrs, ",");
+ string stdout;
+ // 'tablet_ids_str' contains 3 tablets, one of them does not existed.
+ string tablet_ids_str = Substitute("$0,test_tablet_id,$1",
+ tablets[0].tablet_status().tablet_id(),
+ tablets[1].tablet_status().tablet_id());
+ NO_FATALS(RunActionStdoutString(Substitute("tablet info $0 $1",
+ master_addrs_str,
tablet_ids_str), &stdout));
+ for (int i = 0; i < kNumTabletServers; i++) {
+ for (int j = 0; j < 2; j++) {
+ string replica_info = Substitute("$0 | $1 | $2 | $3 | $4 |",
+ tablets[j].tablet_status().tablet_id(),
+ kTableName,
+ cluster_->tablet_server(i)->uuid(),
+ cluster_->tablet_server(i)->bound_rpc_hostport().host(),
+ cluster_->tablet_server(i)->bound_rpc_hostport().port());
+ ASSERT_STR_CONTAINS(stdout, replica_info);
+ }
+ }
+
+ // Print the result in json format.
+ stdout.clear();
+ NO_FATALS(RunActionStdoutString(Substitute("tablet info $0 $1 --format=json",
+ master_addrs_str, tablet_ids_str), &stdout));
+ for (int i = 0; i < kNumTabletServers; i++) {
+ for (int j = 0; j < 2; j++) {
+ string replica_info = Substitute(
+ R"("ID":"$0","Table Name":"$1","Tablet Server
UUID":"$2","Host":"$3","Port":"$4")",
+ tablets[j].tablet_status().tablet_id(),
+ kTableName,
+ cluster_->tablet_server(i)->uuid(),
+ cluster_->tablet_server(i)->bound_rpc_hostport().host(),
+ cluster_->tablet_server(i)->bound_rpc_hostport().port());
+ ASSERT_STR_CONTAINS(stdout, replica_info);
+ }
+ }
+}
+
// Test 'kudu remote_replica copy' tool when the destination tablet server is
online.
// 1. Test the copy tool when the destination replica is healthy
// 2. Test the copy tool when the destination replica is tombstoned
diff --git a/src/kudu/tools/tool_action_tablet.cc
b/src/kudu/tools/tool_action_tablet.cc
index 60d48f772..6cc53c262 100644
--- a/src/kudu/tools/tool_action_tablet.cc
+++ b/src/kudu/tools/tool_action_tablet.cc
@@ -15,6 +15,7 @@
// specific language governing permissions and limitations
// under the License.
+#include <algorithm>
#include <fstream> // IWYU pragma: keep
#include <functional>
#include <iostream>
@@ -23,17 +24,19 @@
#include <string>
#include <type_traits>
#include <unordered_map>
-#include <utility>
#include <vector>
#include <gflags/gflags.h>
+#include "kudu/client/client-internal.h"
#include "kudu/client/client.h" // IWYU pragma: keep
+#include "kudu/client/replica_controller-internal.h"
#include "kudu/client/shared_ptr.h" // IWYU pragma: keep
#include "kudu/common/wire_protocol.h"
#include "kudu/consensus/consensus.pb.h"
#include "kudu/consensus/metadata.pb.h"
#include "kudu/gutil/map-util.h"
+#include "kudu/gutil/stl_util.h"
#include "kudu/gutil/strings/split.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/master/master.pb.h"
@@ -67,6 +70,10 @@ DEFINE_int64(move_leader_timeout_sec, 30,
"Number of seconds to wait for a leader when relocating a leader
tablet");
using kudu::client::KuduClient;
+using kudu::client::KuduScanToken;
+using kudu::client::KuduScanTokenBuilder;
+using kudu::client::KuduTable;
+using kudu::client::internal::ReplicaController;
using kudu::consensus::ADD_PEER;
using kudu::consensus::ChangeConfigType;
using kudu::consensus::LeaderStepDownMode;
@@ -81,6 +88,7 @@ using std::endl;
using std::make_optional;
using std::nullopt;
using std::optional;
+using std::ostream;
using std::string;
using std::unique_ptr;
using std::vector;
@@ -90,6 +98,45 @@ using strings::Substitute;
namespace kudu {
namespace tools {
+Status ShowTabletInfo(const vector<string>& master_addresses,
+ const vector<string>& tablet_ids) {
+ client::sp::shared_ptr<KuduClient> client;
+ RETURN_NOT_OK(CreateKuduClient(master_addresses, &client, true));
+ vector<client::KuduClient::Data::TableInfo> tables_info;
+ RETURN_NOT_OK(client->data_->ListTablesWithInfo(client.get(), &tables_info,
""));
+ DataTable cmatrix({"ID", "Table Name", "Tablet Server UUID", "Host", "Port",
"Is Leader"});
+
+ for (const auto& tinfo : tables_info) {
+ const auto& tname = tinfo.table_name;
+ client::sp::shared_ptr<KuduTable> client_table;
+ RETURN_NOT_OK(client->OpenTable(tname, &client_table));
+ vector<KuduScanToken*> tokens;
+ ElementDeleter deleter(&tokens);
+ KuduScanTokenBuilder builder(client_table.get());
+ RETURN_NOT_OK(builder.Build(&tokens));
+
+ for (const auto* token : tokens) {
+ if (std::find(tablet_ids.begin(), tablet_ids.end(),
token->tablet().id()) ==
+ tablet_ids.end()) {
+ continue;
+ }
+ for (const auto* replica : token->tablet().replicas()) {
+ const bool is_voter = ReplicaController::is_voter(*replica);
+ const bool is_leader = replica->is_leader();
+ vector<string> row;
+ row.push_back(token->tablet().id());
+ row.push_back(tname);
+ row.push_back(replica->ts().uuid());
+ row.push_back(replica->ts().hostname());
+ row.push_back(std::to_string(replica->ts().port()));
+ row.push_back(is_leader ? "L" : (is_voter ? "V" : "N"));
+ cmatrix.AddRow(row);
+ }
+ }
+ }
+ return cmatrix.PrintTo(cout);
+}
+
namespace {
const char* const kReplicaTypeArg = "replica_type";
@@ -276,6 +323,14 @@ Status ReplaceTablet(const RunnerContext& context) {
return Status::OK();
}
+Status Info(const RunnerContext& context) {
+ vector<string> master_addresses;
+ RETURN_NOT_OK(ParseMasterAddresses(context, &master_addresses));
+ const string& tablet_ids_str = FindOrDie(context.required_args,
kTabletIdsCsvArg);
+ vector<string> tablet_ids = strings::Split(tablet_ids_str, ",",
strings::SkipEmpty());
+ return ShowTabletInfo(master_addresses, tablet_ids);
+}
+
} // anonymous namespace
unique_ptr<Mode> BuildTabletMode() {
@@ -359,11 +414,20 @@ unique_ptr<Mode> BuildTabletMode() {
.AddRequiredParameter({ kTabletIdArg, kTabletIdArgDesc })
.Build();
+ unique_ptr<Action> info =
+ ClusterActionBuilder("info", &Info)
+ .Description("Show information of the table which the tablets blongs to "
+ "and where the tablets replicas are located.")
+ .AddRequiredParameter({ kTabletIdsCsvArg, kTabletIdsCsvArgDesc })
+ .AddOptionalParameter("format")
+ .Build();
+
return ModeBuilder("tablet")
.Description("Operate on remote Kudu tablets")
.AddMode(std::move(change_config))
.AddAction(std::move(leader_step_down))
.AddAction(std::move(replace_tablet))
+ .AddAction(std::move(info))
.Build();
}