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 =
