This is an automated email from the ASF dual-hosted git repository.

alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git

commit e70d806d1d410b3f1b623e21465061ebe0f62682
Author: Alexey Serbin <[email protected]>
AuthorDate: Wed May 13 11:30:47 2020 -0700

    [tools] add --ignore_nonexistent for 'local_replica delete'
    
    Added --ignore_nonexistent flag for the 'local_replica delete' tool.
    The motivation for this change is to make the real-world scripting
    scenarios easier if trying to clean up tablet servers of particular
    tablet replicas.
    
    Also added a test to verify the newly introduced functionality.
    
    Change-Id: I3ecd00dea7f19747566b11e3e2a545c97d5f8194
    Reviewed-on: http://gerrit.cloudera.org:8080/15911
    Reviewed-by: Andrew Wong <[email protected]>
    Tested-by: Kudu Jenkins
---
 src/kudu/tools/kudu-tool-test.cc            | 23 +++++++++++++++++++++++
 src/kudu/tools/tool_action_local_replica.cc | 21 ++++++++++++++++-----
 2 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index 5e3e2c5..9dcd278 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -2748,6 +2748,29 @@ TEST_F(ToolTest, TestLocalReplicaDelete) {
                                             Substitute("tablet-meta/$0", 
tablet_id));
   ASSERT_FALSE(env_->FileExists(meta_dir));
 
+  // Try to remove the same tablet replica again.
+  s = RunTool(Substitute(
+      "local_replica delete $0 --clean_unsafe --fs_wal_dir=$1 
--fs_data_dirs=$1",
+      tablet_id, tserver_dir),
+      nullptr, &stderr, nullptr, nullptr);
+  ASSERT_TRUE(s.IsRuntimeError());
+  ASSERT_STR_CONTAINS(stderr, "Not found: Could not load tablet metadata");
+  ASSERT_STR_CONTAINS(stderr, "No such file or directory");
+
+  // Try to remove the same tablet replica again if --ignore_nonexistent
+  // is specified. The tool should report success and output information on the
+  // error ignored.
+  ASSERT_OK(RunActionStderrString(
+      Substitute("local_replica delete $0 --clean_unsafe --fs_wal_dir=$1 "
+                 "--fs_data_dirs=$1 --ignore_nonexistent",
+                 tablet_id, tserver_dir),
+      &stderr));
+  ASSERT_STR_CONTAINS(stderr, Substitute("ignoring error for tablet replica $0 
"
+                                         "because of the --ignore_nonexistent 
flag",
+                                         tablet_id));
+  ASSERT_STR_CONTAINS(stderr, "Not found: Could not load tablet metadata");
+  ASSERT_STR_CONTAINS(stderr, "No such file or directory");
+
   // Verify that the total size of the data on disk after 'delete' action
   // is less than before. Although this doesn't necessarily check
   // for orphan data blocks left behind for the given tablet, it certainly
diff --git a/src/kudu/tools/tool_action_local_replica.cc 
b/src/kudu/tools/tool_action_local_replica.cc
index 8673a2a..2c313ff 100644
--- a/src/kudu/tools/tool_action_local_replica.cc
+++ b/src/kudu/tools/tool_action_local_replica.cc
@@ -104,6 +104,10 @@ DEFINE_bool(clean_unsafe, false,
             "This is not guaranteed to be safe because it also removes the "
             "consensus metadata (including Raft voting record) for the "
             "specified tablet, which violates the Raft vote durability 
requirements.");
+DEFINE_bool(ignore_nonexistent, false,
+            "Whether to ignore non-existent tablet replicas when deleting: if "
+            "set to 'true', the tool does not report an error if the requested 
"
+            "tablet replica to remove is not found");
 
 namespace kudu {
 namespace tools {
@@ -399,11 +403,18 @@ Status DeleteLocalReplica(const string& tablet_id,
     }
   }
 
-  // Force the specified tablet on this node to be in 'state'.
   scoped_refptr<TabletMetadata> meta;
-  RETURN_NOT_OK(TabletMetadata::Load(fs_manager, tablet_id, &meta));
-  return TSTabletManager::DeleteTabletData(
-      meta, cmeta_manager, state, last_logged_opid);
+  const auto s = TabletMetadata::Load(fs_manager, tablet_id, 
&meta).AndThen([&]{
+    return TSTabletManager::DeleteTabletData(
+        meta, cmeta_manager, state, last_logged_opid);
+  });
+  if (FLAGS_ignore_nonexistent && s.IsNotFound()) {
+    LOG(INFO) << Substitute("ignoring error for tablet replica $0 because "
+                            "of the --ignore_nonexistent flag: $1",
+                            tablet_id, s.ToString());
+    return Status::OK();
+  }
+  return s;
 }
 
 Status DeleteLocalReplicas(const RunnerContext& context) {
@@ -430,7 +441,6 @@ Status DeleteLocalReplicas(const RunnerContext& context) {
   for (const auto& tablet_id : tablet_ids) {
     RETURN_NOT_OK(DeleteLocalReplica(tablet_id, &fs_manager, cmeta_manager));
   }
-
   return Status::OK();
 }
 
@@ -931,6 +941,7 @@ unique_ptr<Mode> BuildLocalReplicaMode() {
       .AddOptionalParameter("fs_metadata_dir")
       .AddOptionalParameter("fs_wal_dir")
       .AddOptionalParameter("clean_unsafe")
+      .AddOptionalParameter("ignore_nonexistent")
       .Build();
 
   unique_ptr<Action> data_size =

Reply via email to