You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by wd...@apache.org on 2019/02/15 23:37:52 UTC
[kudu] 02/02: [tools] Add useful flags to 'kudu remote_replica list'
This is an automated email from the ASF dual-hosted git repository.
wdberkeley pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit df105295b3da8515992815c6cddabb031fc7b089
Author: Will Berkeley <wd...@gmail.org>
AuthorDate: Mon Feb 11 14:28:40 2019 -0800
[tools] Add useful flags to 'kudu remote_replica list'
1. --include_schema: The ability to exclude schema.
2. --table_name and --tablets: The ability to filter on tablet id, table name.
Change-Id: I462515f1bc3e8487185aebb6cb99d1c5c00cea40
Reviewed-on: http://gerrit.cloudera.org:8080/12450
Reviewed-by: Adar Dembo <ad...@cloudera.com>
Reviewed-by: Alexey Serbin <as...@cloudera.com>
Tested-by: Kudu Jenkins
---
src/kudu/tools/kudu-tool-test.cc | 102 +++++++++++++++++++++------
src/kudu/tools/tool_action_remote_replica.cc | 30 +++++++-
2 files changed, 108 insertions(+), 24 deletions(-)
diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index f6542c0..6e3909e 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -1913,31 +1913,87 @@ TEST_F(ToolTest, TestRemoteReplicaList) {
vector<ListTabletsResponsePB::StatusAndSchemaPB> tablets;
ASSERT_OK(WaitForNumTabletsOnTS(ts, kNumTablets, kTimeout, &tablets));
const string& ts_addr = cluster_->tablet_server(0)->bound_rpc_addr().ToString();
- string stdout;
- NO_FATALS(RunActionStdoutString(
- Substitute("remote_replica list $0", ts_addr), &stdout));
- const auto& tablet_status = tablets[0].tablet_status();
- // Some fields like state or estimated on disk size may vary. Just check a
- // few whose values we should know exactly.
- ASSERT_STR_CONTAINS(stdout,
- Substitute("Tablet id: $0", tablet_status.tablet_id()));
- ASSERT_STR_CONTAINS(stdout,
- Substitute("Table name: $0", workload.table_name()));
- ASSERT_STR_CONTAINS(stdout,
- Substitute("Data dirs: $0", JoinStrings(tablet_status.data_dirs(), ", ")));
-
- // Tombstone the replica and try again.
- ASSERT_OK(DeleteTablet(ts, tablet_status.tablet_id(),
- TabletDataState::TABLET_DATA_TOMBSTONED, kTimeout));
- NO_FATALS(RunActionStdoutString(
+ const auto& tablet_status = tablets[0].tablet_status();
+ {
+ // Test the basic case.
+ string stdout;
+ NO_FATALS(RunActionStdoutString(
Substitute("remote_replica list $0", ts_addr), &stdout));
- ASSERT_STR_CONTAINS(stdout,
- Substitute("Tablet id: $0", tablet_status.tablet_id()));
- ASSERT_STR_CONTAINS(stdout,
- Substitute("Table name: $0", workload.table_name()));
- ASSERT_STR_CONTAINS(stdout,
- Substitute("Data dirs: $0", JoinStrings(tablet_status.data_dirs(), ", ")));
+
+ // Some fields like state or estimated on disk size may vary. Just check a
+ // few whose values we should know exactly.
+ ASSERT_STR_CONTAINS(stdout,
+ Substitute("Tablet id: $0", tablet_status.tablet_id()));
+ ASSERT_STR_CONTAINS(stdout,
+ Substitute("Table name: $0", workload.table_name()));
+ ASSERT_STR_CONTAINS(stdout, "key INT32 NOT NULL");
+ ASSERT_STR_CONTAINS(stdout,
+ Substitute("Data dirs: $0", JoinStrings(tablet_status.data_dirs(), ", ")));
+ }
+
+ {
+ // Test we lose the schema with --include_schema=false.
+ string stdout;
+ NO_FATALS(RunActionStdoutString(
+ Substitute("remote_replica list $0 --include_schema=false", ts_addr),
+ &stdout));
+ ASSERT_STR_NOT_CONTAINS(stdout, "key INT32 NOT NULL");
+ }
+
+ {
+ // Test we see the tablet when matching on wrong tablet id or wrong table
+ // name.
+ string stdout;
+ NO_FATALS(RunActionStdoutString(
+ Substitute("remote_replica list $0 --table_name=$1",
+ ts_addr, workload.table_name()),
+ &stdout));
+ ASSERT_STR_CONTAINS(stdout,
+ Substitute("Tablet id: $0",
+ tablet_status.tablet_id()));
+ stdout.clear();
+ NO_FATALS(RunActionStdoutString(
+ Substitute("remote_replica list $0 --tablets=$1",
+ ts_addr, tablet_status.tablet_id()),
+ &stdout));
+ ASSERT_STR_CONTAINS(stdout,
+ Substitute("Tablet id: $0",
+ tablet_status.tablet_id()));
+ }
+
+ {
+ // Test we lose the tablet when matching on the wrong tablet id or the wrong
+ // table name.
+ string stdout;
+ NO_FATALS(RunActionStdoutString(
+ Substitute("remote_replica list $0 --table_name=foo", ts_addr),
+ &stdout));
+ ASSERT_STR_NOT_CONTAINS(stdout,
+ Substitute("Tablet id: $0",
+ tablet_status.tablet_id()));
+ stdout.clear();
+ NO_FATALS(RunActionStdoutString(
+ Substitute("remote_replica list $0 --tablets=foo", ts_addr),
+ &stdout));
+ ASSERT_STR_NOT_CONTAINS(stdout,
+ Substitute("Tablet id: $0",
+ tablet_status.tablet_id()));
+ }
+
+ {
+ // Finally, tombstone the replica and try again.
+ string stdout;
+ ASSERT_OK(DeleteTablet(ts, tablet_status.tablet_id(),
+ TabletDataState::TABLET_DATA_TOMBSTONED, kTimeout));
+ NO_FATALS(RunActionStdoutString(
+ Substitute("remote_replica list $0", ts_addr), &stdout));
+ ASSERT_STR_CONTAINS(stdout,
+ Substitute("Tablet id: $0", tablet_status.tablet_id()));
+ ASSERT_STR_CONTAINS(stdout,
+ Substitute("Table name: $0", workload.table_name()));
+ ASSERT_STR_CONTAINS(stdout, "Data dirs: <not available>");
+ }
}
// Test 'kudu local_replica delete' tool with --clean_unsafe flag for
diff --git a/src/kudu/tools/tool_action_remote_replica.cc b/src/kudu/tools/tool_action_remote_replica.cc
index 6323f9b..e3b12b1 100644
--- a/src/kudu/tools/tool_action_remote_replica.cc
+++ b/src/kudu/tools/tool_action_remote_replica.cc
@@ -21,6 +21,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
@@ -44,6 +45,7 @@
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/strings/human_readable.h"
#include "kudu/gutil/strings/join.h"
+#include "kudu/gutil/strings/split.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/rpc/rpc_controller.h"
#include "kudu/server/server_base.pb.h"
@@ -62,6 +64,10 @@
DEFINE_bool(force_copy, false,
"Force the copy when the destination tablet server has this replica");
+DEFINE_bool(include_schema, true,
+ "Whether to include the schema of each replica");
+DECLARE_string(table_name);
+DECLARE_string(tablets);
DECLARE_int64(timeout_ms); // defined in ksck
namespace kudu {
@@ -82,6 +88,7 @@ using std::cout;
using std::endl;
using std::string;
using std::unique_ptr;
+using std::unordered_set;
using std::vector;
using tablet::TabletStatusPB;
using tserver::DeleteTabletRequestPB;
@@ -178,6 +185,10 @@ Status GetReplicas(TabletServerServiceProxy* proxy,
RpcController rpc;
rpc.set_timeout(MonoDelta::FromMilliseconds(FLAGS_timeout_ms));
+ // Even with FLAGS_include_schema=false, don't set need_schema_info=false
+ // in the request. The reason is that the schema is still needed to decode
+ // the partition of each replica, and the partition information is pretty
+ // much always nice to have.
RETURN_NOT_OK(proxy->ListTablets(req, &resp, &rpc));
if (resp.has_error()) {
return StatusFromPB(resp.error().status());
@@ -281,7 +292,16 @@ Status ListReplicas(const RunnerContext& context) {
vector<ListTabletsResponsePB::StatusAndSchemaPB> replicas;
RETURN_NOT_OK(GetReplicas(proxy.get(), &replicas));
+ unordered_set<string> tablet_ids = strings::Split(FLAGS_tablets, ",");
for (const auto& r : replicas) {
+ if (!FLAGS_table_name.empty() &&
+ r.tablet_status().table_name() != FLAGS_table_name) {
+ continue;
+ }
+ if (!FLAGS_tablets.empty() &&
+ !ContainsKey(tablet_ids, r.tablet_status().tablet_id())) {
+ continue;
+ }
Schema schema;
RETURN_NOT_OK_PREPEND(
SchemaFromPB(r.schema(), &schema),
@@ -311,7 +331,9 @@ Status ListReplicas(const RunnerContext& context) {
} else {
cout << "Data dirs: <not available>" << endl;
}
- cout << "Schema: " << schema.ToString() << endl;
+ if (FLAGS_include_schema) {
+ cout << "Schema: " << schema.ToString() << endl;
+ }
}
return Status::OK();
@@ -437,6 +459,12 @@ unique_ptr<Mode> BuildRemoteReplicaMode() {
ActionBuilder("list", &ListReplicas)
.Description("List all tablet replicas on a Kudu Tablet Server")
.AddRequiredParameter({ kTServerAddressArg, kTServerAddressDesc })
+ .AddOptionalParameter("include_schema")
+ .AddOptionalParameter("table_name")
+ .AddOptionalParameter("tablets",
+ string(""),
+ string("Comma-separated list of tablet IDs used to "
+ "filter the list of replicas"))
.Build();
unique_ptr<Action> unsafe_change_config =