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 bd5926ee50cbde7b86cbd2342b61e8370836fd4a
Author: Will Berkeley <wdberke...@gmail.org>
AuthorDate: Mon Feb 11 12:50:51 2019 -0800

    [tools] Add tablet data dirs to 'kudu remote replica list'
    
    This is useful to find out the data dirs for a tablet on a remote server
    while the server is running. For example, it could be used to
    investigate performance issues related to the devices on which the data
    for the tablet is stored.
    
    Change-Id: I7e509b5c080a76a4110a32ecc073418c28aa0633
    Reviewed-on: http://gerrit.cloudera.org:8080/12449
    Reviewed-by: Adar Dembo <a...@cloudera.com>
    Tested-by: Will Berkeley <wdberke...@gmail.com>
---
 src/kudu/tablet/tablet.proto                 |  1 +
 src/kudu/tablet/tablet_replica.cc            | 15 ++++++++-
 src/kudu/tools/kudu-tool-test.cc             | 47 ++++++++++++++++++++++++++++
 src/kudu/tools/tool_action_remote_replica.cc |  6 ++++
 4 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/src/kudu/tablet/tablet.proto b/src/kudu/tablet/tablet.proto
index 9706c9c..7d347e1 100644
--- a/src/kudu/tablet/tablet.proto
+++ b/src/kudu/tablet/tablet.proto
@@ -101,4 +101,5 @@ message TabletStatusPB {
   optional bytes end_key = 6;
   optional PartitionPB partition = 9;
   optional int64 estimated_on_disk_size = 7;
+  repeated bytes data_dirs = 10;
 }
diff --git a/src/kudu/tablet/tablet_replica.cc 
b/src/kudu/tablet/tablet_replica.cc
index 4175f5b..c7b231b 100644
--- a/src/kudu/tablet/tablet_replica.cc
+++ b/src/kudu/tablet/tablet_replica.cc
@@ -38,6 +38,7 @@
 #include "kudu/consensus/log_anchor_registry.h"
 #include "kudu/consensus/opid.pb.h"
 #include "kudu/consensus/raft_consensus.h"
+#include "kudu/gutil/basictypes.h"
 #include "kudu/gutil/bind.h"
 #include "kudu/gutil/bind_helpers.h"
 #include "kudu/gutil/port.h"
@@ -436,11 +437,23 @@ void TabletReplica::GetTabletStatusPB(TabletStatusPB* 
status_pb_out) const {
     status_pb_out->set_state(state_);
     status_pb_out->set_last_status(last_status_);
   }
-  status_pb_out->set_tablet_id(meta_->tablet_id());
+  const string& tablet_id = meta_->tablet_id();
+  status_pb_out->set_tablet_id(tablet_id);
   status_pb_out->set_table_name(meta_->table_name());
   meta_->partition().ToPB(status_pb_out->mutable_partition());
   status_pb_out->set_tablet_data_state(meta_->tablet_data_state());
   status_pb_out->set_estimated_on_disk_size(OnDiskSize());
+  // There are circumstances where the call to 'FindDataDirsByTabletId' may
+  // fail, like if the tablet is tombstoned or failed. It's alright to return
+  // an empty 'data_dirs' in this case-- the state and last status will inform
+  // the caller.
+  vector<string> data_dirs;
+  ignore_result(
+      meta_->fs_manager()->dd_manager()->FindDataDirsByTabletId(tablet_id,
+                                                                &data_dirs));
+  for (auto& dir : data_dirs) {
+    status_pb_out->add_data_dirs(std::move(dir));
+  }
 }
 
 Status TabletReplica::RunLogGC() {
diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index e0a3a91..f6542c0 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -1893,6 +1893,53 @@ TEST_F(ToolTest, TestRemoteReplicaCopy) {
                                    tablet::RUNNING, kTimeout));
 }
 
+// Test the 'kudu remote_replica list' tool.
+TEST_F(ToolTest, TestRemoteReplicaList) {
+  MonoDelta kTimeout = MonoDelta::FromSeconds(30);
+  const int kNumTservers = 1;
+  const int kNumTablets = 1;
+  ExternalMiniClusterOptions opts;
+  opts.num_data_dirs = 3;
+  opts.num_tablet_servers = kNumTservers;
+  NO_FATALS(StartExternalMiniCluster(std::move(opts)));
+
+  // TestWorkLoad.Setup() internally generates a table.
+  TestWorkload workload(cluster_.get());
+  workload.set_num_tablets(kNumTablets);
+  workload.set_num_replicas(kNumTservers);
+  workload.Setup();
+
+  TServerDetails* ts = ts_map_[cluster_->tablet_server(0)->uuid()];
+  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(
+        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(), ", 
")));
+}
+
 // Test 'kudu local_replica delete' tool with --clean_unsafe flag for
 // deleting the tablet from the tablet server.
 TEST_F(ToolTest, TestLocalReplicaDelete) {
diff --git a/src/kudu/tools/tool_action_remote_replica.cc 
b/src/kudu/tools/tool_action_remote_replica.cc
index 9ffb195..6323f9b 100644
--- a/src/kudu/tools/tool_action_remote_replica.cc
+++ b/src/kudu/tools/tool_action_remote_replica.cc
@@ -43,6 +43,7 @@
 #include "kudu/consensus/metadata.pb.h"
 #include "kudu/gutil/map-util.h"
 #include "kudu/gutil/strings/human_readable.h"
+#include "kudu/gutil/strings/join.h"
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/server/server_base.pb.h"
@@ -305,6 +306,11 @@ Status ListReplicas(const RunnerContext& context) {
       cout << "Estimated on disk size: "
            << HumanReadableNumBytes::ToString(rs.estimated_on_disk_size()) << 
endl;
     }
+    if (rs.data_dirs_size() != 0) {
+      cout << "Data dirs: " << JoinStrings(rs.data_dirs(), ", ") << endl;
+    } else {
+      cout << "Data dirs: <not available>" << endl;
+    }
     cout << "Schema: " << schema.ToString() << endl;
   }
 

Reply via email to