You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by jd...@apache.org on 2017/04/06 21:46:05 UTC
kudu git commit: KUDU-1607. Unpin tablet flush after failed bootstrap
Repository: kudu
Updated Branches:
refs/heads/branch-1.3.x 54e60d1a1 -> 9eebcdc79
KUDU-1607. Unpin tablet flush after failed bootstrap
We have heard reports that, in certain scenarios, a failed tablet is
unable to be deleted. After some investigation, I determined that this
is because we neglect to unpin the Tablet when tablet bootstrap fails.
When a table is being deleted, we delete each tablet superblock by
calling TabletMetadata::DeleteSuperBlock(). This method double-checks
that no orphaned blocks remain referenced to ensure we don't leak disk
space. That requires TabletMetadata::DeleteTabletData() to be called
first, which invokes Flush() twice to ensure that no orphaned blocks are
referenced on disk upon returning. However, if the tablet is pinned,
Flush() silently becomes a no-op (except for a log message that is
printed) and so DeleteSuperBlock() also fails, resulting in the tablet
not being fully deleted and the following warning message being written
to the log file:
W0317 13:05:19.324373 13242 ts_tablet_manager.cc:634] Invalid argument: Unable to delete on-disk data from tablet d1b857ddaa0743c79c9bcbd9b2fda174: The metadata for tablet d1b857ddaa0743c79c9bcbd9b2fda174 still references orphaned blocks. Call DeleteTabletData() first
This patch makes the following changes:
1. Always unpin the tablet after pinning it.
2. Add a new itest that fails without that change, reproducing the
above warning message.
3. Add a little more test infra to MiniCluster (and the MiniClusterBase
interface) to make it easier to use the helper functions in
cluster_itest_util.h in MiniCluster-based itests.
Change-Id: Id274c6ee1da75bc6f92ab91c0a01edaa009b8962
Reviewed-on: http://gerrit.cloudera.org:8080/6422
Tested-by: Kudu Jenkins
Reviewed-by: David Ribeiro Alves <dr...@apache.org>
(cherry picked from commit 0450f77f69c74cc6dec08ad36bb89ac12c17608f)
Reviewed-on: http://gerrit.cloudera.org:8080/6545
Reviewed-by: Jean-Daniel Cryans <jd...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/9eebcdc7
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/9eebcdc7
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/9eebcdc7
Branch: refs/heads/branch-1.3.x
Commit: 9eebcdc7974bca215b6ecdb32d78a4d10713fc2b
Parents: 54e60d1
Author: Mike Percy <mp...@apache.org>
Authored: Fri Mar 17 15:19:36 2017 -0700
Committer: Jean-Daniel Cryans <jd...@apache.org>
Committed: Thu Apr 6 21:45:00 2017 +0000
----------------------------------------------------------------------
src/kudu/integration-tests/CMakeLists.txt | 1 +
.../integration-tests/delete_tablet-itest.cc | 106 +++++++++++++++++++
.../integration-tests/external_mini_cluster.cc | 6 +-
.../integration-tests/external_mini_cluster.h | 22 +---
src/kudu/integration-tests/mini_cluster.cc | 23 +++-
src/kudu/integration-tests/mini_cluster.h | 6 ++
src/kudu/integration-tests/mini_cluster_base.h | 22 +++-
src/kudu/tablet/tablet_bootstrap.cc | 78 +++++++++-----
src/kudu/tserver/mini_tablet_server.cc | 5 +
src/kudu/tserver/mini_tablet_server.h | 3 +
10 files changed, 224 insertions(+), 48 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/integration-tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/CMakeLists.txt b/src/kudu/integration-tests/CMakeLists.txt
index 7a0d32a..ce72daf 100644
--- a/src/kudu/integration-tests/CMakeLists.txt
+++ b/src/kudu/integration-tests/CMakeLists.txt
@@ -60,6 +60,7 @@ ADD_KUDU_TEST(consistency-itest)
ADD_KUDU_TEST(create-table-itest)
ADD_KUDU_TEST(create-table-stress-test)
ADD_KUDU_TEST(delete_table-test)
+ADD_KUDU_TEST(delete_tablet-itest)
ADD_KUDU_TEST(disk_reservation-itest)
ADD_KUDU_TEST(exactly_once_writes-itest)
ADD_KUDU_TEST(external_mini_cluster-test RESOURCE_LOCK "master-rpc-ports")
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/integration-tests/delete_tablet-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/delete_tablet-itest.cc b/src/kudu/integration-tests/delete_tablet-itest.cc
new file mode 100644
index 0000000..e145701
--- /dev/null
+++ b/src/kudu/integration-tests/delete_tablet-itest.cc
@@ -0,0 +1,106 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include <vector>
+
+#include "kudu/gutil/stl_util.h"
+#include "kudu/gutil/strings/substitute.h"
+#include "kudu/integration-tests/cluster_itest_util.h"
+#include "kudu/integration-tests/mini_cluster-itest-base.h"
+#include "kudu/integration-tests/test_workload.h"
+#include "kudu/master/mini_master.h"
+#include "kudu/tablet/tablet_peer.h"
+#include "kudu/tserver/mini_tablet_server.h"
+#include "kudu/tserver/tablet_server.h"
+#include "kudu/tserver/ts_tablet_manager.h"
+
+DECLARE_int64(fs_wal_dir_reserved_bytes);
+
+using kudu::tablet::TabletPeer;
+using std::vector;
+
+namespace kudu {
+
+class DeleteTabletITest : public MiniClusterITestBase {
+};
+
+// Test deleting a failed replica. Regression test for KUDU-1607.
+TEST_F(DeleteTabletITest, TestDeleteFailedReplica) {
+ NO_FATALS(StartCluster(1)); // 1 TS.
+ TestWorkload workload(cluster_.get());
+ workload.set_num_replicas(1);
+ workload.Setup();
+
+ std::unordered_map<std::string, itest::TServerDetails*> ts_map;
+ ValueDeleter del(&ts_map);
+ ASSERT_OK(itest::CreateTabletServerMap(cluster_->master_proxy().get(),
+ cluster_->messenger(),
+ &ts_map));
+ auto* mts = cluster_->mini_tablet_server(0);
+ auto* ts = ts_map[mts->uuid()];
+
+ scoped_refptr<TabletPeer> tablet_peer;
+ AssertEventually([&] {
+ vector<scoped_refptr<TabletPeer>> tablet_peers;
+ mts->server()->tablet_manager()->GetTabletPeers(&tablet_peers);
+ ASSERT_EQ(1, tablet_peers.size());
+ tablet_peer = tablet_peers[0];
+ });
+ NO_FATALS();
+
+ workload.Start();
+ while (workload.rows_inserted() < 100) {
+ SleepFor(MonoDelta::FromMilliseconds(10));
+ }
+ workload.StopAndJoin();
+
+ // We need blocks on-disk for this regression test, so force an MRS flush.
+ ASSERT_OK(tablet_peer->tablet()->Flush());
+
+ // Shut down the master so it doesn't crash the test process when we make the
+ // disk appear to be full.
+ cluster_->mini_master()->Shutdown();
+
+ // Shut down the TS and restart it after changing flags to ensure no data can
+ // be written during tablet bootstrap.
+ mts->Shutdown();
+ FLAGS_fs_wal_dir_reserved_bytes = INT64_MAX;
+ ASSERT_OK(mts->Restart());
+ Status s = mts->server()->tablet_manager()->WaitForAllBootstrapsToFinish();
+ ASSERT_TRUE(s.IsIOError());
+ ASSERT_STR_CONTAINS(s.ToString(), "Insufficient disk space");
+
+ // Tablet bootstrap failure should result in tablet status == FAILED.
+ {
+ vector<scoped_refptr<TabletPeer>> tablet_peers;
+ mts->server()->tablet_manager()->GetTabletPeers(&tablet_peers);
+ ASSERT_EQ(1, tablet_peers.size());
+ tablet_peer = tablet_peers[0];
+ ASSERT_EQ(tablet::FAILED, tablet_peer->state());
+ }
+
+ // We should still be able to delete the failed tablet.
+ ASSERT_OK(itest::DeleteTablet(ts, tablet_peer->tablet_id(), tablet::TABLET_DATA_DELETED,
+ boost::none, MonoDelta::FromSeconds(30)));
+ AssertEventually([&] {
+ vector<scoped_refptr<TabletPeer>> tablet_peers;
+ mts->server()->tablet_manager()->GetTabletPeers(&tablet_peers);
+ ASSERT_EQ(0, tablet_peers.size());
+ });
+}
+
+} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/integration-tests/external_mini_cluster.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/external_mini_cluster.cc b/src/kudu/integration-tests/external_mini_cluster.cc
index a57f92a..c5eb77f 100644
--- a/src/kudu/integration-tests/external_mini_cluster.cc
+++ b/src/kudu/integration-tests/external_mini_cluster.cc
@@ -537,16 +537,16 @@ vector<ExternalDaemon*> ExternalMiniCluster::daemons() const {
return results;
}
-std::shared_ptr<rpc::Messenger> ExternalMiniCluster::messenger() {
+std::shared_ptr<rpc::Messenger> ExternalMiniCluster::messenger() const {
return messenger_;
}
-std::shared_ptr<MasterServiceProxy> ExternalMiniCluster::master_proxy() {
+std::shared_ptr<MasterServiceProxy> ExternalMiniCluster::master_proxy() const {
CHECK_EQ(masters_.size(), 1);
return master_proxy(0);
}
-std::shared_ptr<MasterServiceProxy> ExternalMiniCluster::master_proxy(int idx) {
+std::shared_ptr<MasterServiceProxy> ExternalMiniCluster::master_proxy(int idx) const {
CHECK_LT(idx, masters_.size());
return std::shared_ptr<MasterServiceProxy>(
new MasterServiceProxy(messenger_, CHECK_NOTNULL(master(idx))->bound_rpc_addr()));
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/integration-tests/external_mini_cluster.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/external_mini_cluster.h b/src/kudu/integration-tests/external_mini_cluster.h
index 57fdba1..a562f8e 100644
--- a/src/kudu/integration-tests/external_mini_cluster.h
+++ b/src/kudu/integration-tests/external_mini_cluster.h
@@ -46,14 +46,6 @@ class NodeInstancePB;
class Sockaddr;
class Subprocess;
-namespace master {
-class MasterServiceProxy;
-} // namespace master
-
-namespace rpc {
-class Messenger;
-} // namespace rpc
-
namespace server {
class ServerStatusPB;
} // namespace server
@@ -235,17 +227,9 @@ class ExternalMiniCluster : public MiniClusterBase {
return masters_.size();
}
- // Return the client messenger used by the ExternalMiniCluster.
- std::shared_ptr<rpc::Messenger> messenger();
-
- // If the cluster is configured for a single non-distributed master,
- // return a proxy to that master. Requires that the single master is
- // running.
- std::shared_ptr<master::MasterServiceProxy> master_proxy();
-
- // Returns an RPC proxy to the master at 'idx'. Requires that the
- // master at 'idx' is running.
- std::shared_ptr<master::MasterServiceProxy> master_proxy(int idx);
+ std::shared_ptr<rpc::Messenger> messenger() const override;
+ std::shared_ptr<master::MasterServiceProxy> master_proxy() const override;
+ std::shared_ptr<master::MasterServiceProxy> master_proxy(int idx) const override;
// Wait until the number of registered tablet servers reaches the given count
// on all of the running masters. Returns Status::TimedOut if the desired
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/integration-tests/mini_cluster.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/mini_cluster.cc b/src/kudu/integration-tests/mini_cluster.cc
index d50c339..c910502 100644
--- a/src/kudu/integration-tests/mini_cluster.cc
+++ b/src/kudu/integration-tests/mini_cluster.cc
@@ -23,6 +23,7 @@
#include "kudu/gutil/strings/substitute.h"
#include "kudu/master/catalog_manager.h"
#include "kudu/master/master.h"
+#include "kudu/master/master.proxy.h"
#include "kudu/master/mini_master.h"
#include "kudu/master/ts_descriptor.h"
#include "kudu/master/ts_manager.h"
@@ -41,8 +42,8 @@ namespace kudu {
using client::KuduClient;
using client::KuduClientBuilder;
using master::CatalogManager;
+using master::MasterServiceProxy;
using master::MiniMaster;
-using master::TabletLocationsPB;
using master::TSDescriptor;
using std::shared_ptr;
using tserver::MiniTabletServer;
@@ -96,6 +97,12 @@ Status MiniCluster::Start() {
RETURN_NOT_OK_PREPEND(WaitForTabletServerCount(num_ts_initial_),
"Waiting for tablet servers to start");
+ RETURN_NOT_OK_PREPEND(rpc::MessengerBuilder("minicluster-messenger")
+ .set_num_reactors(1)
+ .set_max_negotiation_threads(1)
+ .Build(&messenger_),
+ "Failed to start Messenger for minicluster");
+
running_ = true;
return Status::OK();
}
@@ -324,4 +331,18 @@ Status MiniCluster::GetLeaderMasterIndex(int* idx) const {
return Status::OK();
}
+std::shared_ptr<rpc::Messenger> MiniCluster::messenger() const {
+ return messenger_;
+}
+
+std::shared_ptr<MasterServiceProxy> MiniCluster::master_proxy() const {
+ CHECK_EQ(1, mini_masters_.size());
+ return master_proxy(0);
+}
+
+std::shared_ptr<MasterServiceProxy> MiniCluster::master_proxy(int idx) const {
+ return std::shared_ptr<MasterServiceProxy>(
+ new MasterServiceProxy(messenger_, CHECK_NOTNULL(mini_master(idx))->bound_rpc_addr()));
+}
+
} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/integration-tests/mini_cluster.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/mini_cluster.h b/src/kudu/integration-tests/mini_cluster.h
index be5928e..cf49aee 100644
--- a/src/kudu/integration-tests/mini_cluster.h
+++ b/src/kudu/integration-tests/mini_cluster.h
@@ -162,6 +162,10 @@ class MiniCluster : public MiniClusterBase {
// last result may not be valid.
Status GetLeaderMasterIndex(int* idx) const;
+ std::shared_ptr<rpc::Messenger> messenger() const override;
+ std::shared_ptr<master::MasterServiceProxy> master_proxy() const override;
+ std::shared_ptr<master::MasterServiceProxy> master_proxy(int idx) const override;
+
private:
enum {
kRegistrationWaitTimeSeconds = 15,
@@ -180,6 +184,8 @@ class MiniCluster : public MiniClusterBase {
std::vector<std::shared_ptr<master::MiniMaster> > mini_masters_;
std::vector<std::shared_ptr<tserver::MiniTabletServer> > mini_tablet_servers_;
+ std::shared_ptr<rpc::Messenger> messenger_;
+
DISALLOW_COPY_AND_ASSIGN(MiniCluster);
};
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/integration-tests/mini_cluster_base.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/mini_cluster_base.h b/src/kudu/integration-tests/mini_cluster_base.h
index 1fd1985..a71b807 100644
--- a/src/kudu/integration-tests/mini_cluster_base.h
+++ b/src/kudu/integration-tests/mini_cluster_base.h
@@ -24,7 +24,15 @@ class Status;
namespace client {
class KuduClient;
class KuduClientBuilder;
-}
+} // namespace client
+
+namespace master {
+class MasterServiceProxy;
+} // namespace master
+
+namespace rpc {
+class Messenger;
+} // namespace rpc
// Mode to which node types a certain action (like Shutdown()) should apply.
enum class ClusterNodes {
@@ -65,6 +73,18 @@ class MiniClusterBase {
// REQUIRES: the cluster must have already been Start()ed.
virtual Status CreateClient(client::KuduClientBuilder* builder,
client::sp::shared_ptr<client::KuduClient>* client) const = 0;
+
+ // Return a messenger for use by clients.
+ virtual std::shared_ptr<rpc::Messenger> messenger() const = 0;
+
+ // If the cluster is configured for a single non-distributed master,
+ // return a proxy to that master. Requires that the single master is
+ // running.
+ virtual std::shared_ptr<master::MasterServiceProxy> master_proxy() const = 0;
+
+ // Returns an RPC proxy to the master at 'idx'. Requires that the
+ // master at 'idx' is running.
+ virtual std::shared_ptr<master::MasterServiceProxy> master_proxy(int idx) const = 0;
};
} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/tablet/tablet_bootstrap.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_bootstrap.cc b/src/kudu/tablet/tablet_bootstrap.cc
index a7cd658..0749486 100644
--- a/src/kudu/tablet/tablet_bootstrap.cc
+++ b/src/kudu/tablet/tablet_bootstrap.cc
@@ -58,6 +58,7 @@
#include "kudu/util/logging.h"
#include "kudu/util/path_util.h"
#include "kudu/util/pb_util.h"
+#include "kudu/util/scoped_cleanup.h"
#include "kudu/util/stopwatch.h"
DEFINE_bool(skip_remove_old_recovery_dir, false,
@@ -177,10 +178,17 @@ class TabletBootstrap {
// A successful call will yield the rebuilt tablet and the rebuilt log.
Status Bootstrap(shared_ptr<Tablet>* rebuilt_tablet,
scoped_refptr<Log>* rebuilt_log,
- ConsensusBootstrapInfo* results);
+ ConsensusBootstrapInfo* consensus_info);
private:
+ // The method that does the actual work of tablet bootstrap. Bootstrap() is
+ // actually a wrapper method that is responsible for pinning and unpinning
+ // the tablet metadata flush.
+ Status RunBootstrap(shared_ptr<Tablet>* rebuilt_tablet,
+ scoped_refptr<Log>* rebuilt_log,
+ ConsensusBootstrapInfo* consensus_info);
+
// Opens the tablet.
// Sets '*has_blocks' to true if there was any data on disk for this tablet.
Status OpenTablet(bool* has_blocks);
@@ -213,9 +221,9 @@ class TabletBootstrap {
Status OpenNewLog();
// Finishes bootstrap, setting 'rebuilt_log' and 'rebuilt_tablet'.
- Status FinishBootstrap(const string& message,
- scoped_refptr<log::Log>* rebuilt_log,
- shared_ptr<Tablet>* rebuilt_tablet);
+ void FinishBootstrap(const string& message,
+ scoped_refptr<log::Log>* rebuilt_log,
+ shared_ptr<Tablet>* rebuilt_tablet);
// Plays the log segments into the tablet being built.
// The process of playing the segments generates a new log that can be continued
@@ -439,6 +447,43 @@ TabletBootstrap::TabletBootstrap(
Status TabletBootstrap::Bootstrap(shared_ptr<Tablet>* rebuilt_tablet,
scoped_refptr<Log>* rebuilt_log,
ConsensusBootstrapInfo* consensus_info) {
+ // We pin (prevent) metadata flush at the beginning of the bootstrap process
+ // and always unpin it at the end.
+ meta_->PinFlush();
+
+ // Now run the actual bootstrap process.
+ Status bootstrap_status = RunBootstrap(rebuilt_tablet, rebuilt_log, consensus_info);
+
+ // Add a callback to TabletMetadata that makes sure that each time we flush the metadata
+ // we also wait for in-flights to finish and for their wal entry to be fsynced.
+ // This might be a bit conservative in some situations but it will prevent us from
+ // ever flushing the metadata referring to tablet data blocks containing data whose
+ // commit entries are not durable, a pre-requisite for recovery.
+ CHECK((*rebuilt_tablet && *rebuilt_log) || !bootstrap_status.ok())
+ << "Tablet and Log not initialized";
+ if (bootstrap_status.ok()) {
+ meta_->SetPreFlushCallback(
+ Bind(&FlushInflightsToLogCallback::WaitForInflightsAndFlushLog,
+ make_scoped_refptr(new FlushInflightsToLogCallback(
+ rebuilt_tablet->get(), *rebuilt_log))));
+ }
+
+ // This will cause any pending TabletMetadata flush to be executed.
+ Status unpin_status = meta_->UnPinFlush();
+
+ constexpr char kFailedUnpinMsg[] = "Failed to flush after unpinning";
+ if (PREDICT_FALSE(!bootstrap_status.ok() && !unpin_status.ok())) {
+ LOG_WITH_PREFIX(WARNING) << kFailedUnpinMsg << ": " << unpin_status.ToString();
+ return bootstrap_status;
+ }
+ RETURN_NOT_OK(bootstrap_status);
+ RETURN_NOT_OK_PREPEND(unpin_status, Substitute("$0$1", LogPrefix(), kFailedUnpinMsg));
+ return Status::OK();
+}
+
+Status TabletBootstrap::RunBootstrap(shared_ptr<Tablet>* rebuilt_tablet,
+ scoped_refptr<Log>* rebuilt_log,
+ ConsensusBootstrapInfo* consensus_info) {
string tablet_id = meta_->tablet_id();
// Replay requires a valid Consensus metadata file to exist in order to
@@ -458,8 +503,6 @@ Status TabletBootstrap::Bootstrap(shared_ptr<Tablet>* rebuilt_tablet,
TabletDataState_Name(tablet_data_state));
}
- meta_->PinFlush();
-
StatusMessage("Bootstrap starting.");
if (VLOG_IS_ON(1)) {
@@ -483,9 +526,7 @@ Status TabletBootstrap::Bootstrap(shared_ptr<Tablet>* rebuilt_tablet,
if (!has_blocks && !needs_recovery) {
LOG_WITH_PREFIX(INFO) << "No blocks or log segments found. Creating new log.";
RETURN_NOT_OK_PREPEND(OpenNewLog(), "Failed to open new log");
- RETURN_NOT_OK(FinishBootstrap("No bootstrap required, opened a new log",
- rebuilt_log,
- rebuilt_tablet));
+ FinishBootstrap("No bootstrap required, opened a new log", rebuilt_log, rebuilt_tablet);
consensus_info->last_id = MinimumOpId();
consensus_info->last_committed_id = MinimumOpId();
return Status::OK();
@@ -506,29 +547,18 @@ Status TabletBootstrap::Bootstrap(shared_ptr<Tablet>* rebuilt_tablet,
cmeta_->Flush();
RETURN_NOT_OK(RemoveRecoveryDir());
- RETURN_NOT_OK(FinishBootstrap("Bootstrap complete.", rebuilt_log, rebuilt_tablet));
+ FinishBootstrap("Bootstrap complete.", rebuilt_log, rebuilt_tablet);
return Status::OK();
}
-Status TabletBootstrap::FinishBootstrap(const string& message,
- scoped_refptr<log::Log>* rebuilt_log,
- shared_ptr<Tablet>* rebuilt_tablet) {
- // Add a callback to TabletMetadata that makes sure that each time we flush the metadata
- // we also wait for in-flights to finish and for their wal entry to be fsynced.
- // This might be a bit conservative in some situations but it will prevent us from
- // ever flushing the metadata referring to tablet data blocks containing data whose
- // commit entries are not durable, a pre-requisite for recovery.
- meta_->SetPreFlushCallback(
- Bind(&FlushInflightsToLogCallback::WaitForInflightsAndFlushLog,
- make_scoped_refptr(new FlushInflightsToLogCallback(tablet_.get(),
- log_))));
+void TabletBootstrap::FinishBootstrap(const string& message,
+ scoped_refptr<log::Log>* rebuilt_log,
+ shared_ptr<Tablet>* rebuilt_tablet) {
tablet_->MarkFinishedBootstrapping();
- RETURN_NOT_OK(tablet_->metadata()->UnPinFlush());
StatusMessage(message);
rebuilt_tablet->reset(tablet_.release());
rebuilt_log->swap(log_);
- return Status::OK();
}
Status TabletBootstrap::OpenTablet(bool* has_blocks) {
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/tserver/mini_tablet_server.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/mini_tablet_server.cc b/src/kudu/tserver/mini_tablet_server.cc
index f4cb331..aabb9df 100644
--- a/src/kudu/tserver/mini_tablet_server.cc
+++ b/src/kudu/tserver/mini_tablet_server.cc
@@ -135,5 +135,10 @@ const Sockaddr MiniTabletServer::bound_http_addr() const {
return server_->first_http_address();
}
+const string& MiniTabletServer::uuid() const {
+ CHECK(started_);
+ return server_->fs_manager()->uuid();
+}
+
} // namespace tserver
} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/9eebcdc7/src/kudu/tserver/mini_tablet_server.h
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/mini_tablet_server.h b/src/kudu/tserver/mini_tablet_server.h
index 4c205fd..34ed945 100644
--- a/src/kudu/tserver/mini_tablet_server.h
+++ b/src/kudu/tserver/mini_tablet_server.h
@@ -87,6 +87,9 @@ class MiniTabletServer {
const TabletServer* server() const { return server_.get(); }
TabletServer* server() { return server_.get(); }
+ // Return TS uuid.
+ const std::string& uuid() const;
+
bool is_started() const { return started_; }
void FailHeartbeats();