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

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


The following commit(s) were added to refs/heads/master by this push:
     new ea16958  KUDU-2612: persist commit MVCC op timestamp in txn metadata
ea16958 is described below

commit ea1695885067dc5d39ad1f794a91a9d9e0540b1a
Author: Andrew Wong <[email protected]>
AuthorDate: Thu Oct 8 17:01:00 2020 -0700

    KUDU-2612: persist commit MVCC op timestamp in txn metadata
    
    We previously didn't persist the MVCC op timestamp used for the
    BEGIN_COMMIT op. This was problematic, as this timestamp is necessary to
    determine relevancy upon iteration.
    
    This adds the timestamp to the TxnMetadata, and ensures that we anchor
    the BEGIN_COMMIT op until we flush metadata, as we do with other
    persistent participant op state.
    
    Change-Id: Ib2400fbb7e96ddba78544a9549965fc095e32ca3
    Reviewed-on: http://gerrit.cloudera.org:8080/16569
    Tested-by: Kudu Jenkins
    Reviewed-by: Hao Hao <[email protected]>
---
 src/kudu/tablet/metadata.proto          |  16 ++++-
 src/kudu/tablet/ops/participant_op.cc   |   2 +-
 src/kudu/tablet/tablet.cc               |   8 +++
 src/kudu/tablet/tablet.h                |   6 ++
 src/kudu/tablet/tablet_metadata-test.cc |  10 +++
 src/kudu/tablet/tablet_metadata.cc      |  21 ++++++
 src/kudu/tablet/tablet_metadata.h       |   7 ++
 src/kudu/tablet/txn_metadata.h          |   7 +-
 src/kudu/tablet/txn_participant-test.cc | 112 +++++++++++++++++++++++++++++++-
 9 files changed, 180 insertions(+), 9 deletions(-)

diff --git a/src/kudu/tablet/metadata.proto b/src/kudu/tablet/metadata.proto
index e59ee80..5cbfa14 100644
--- a/src/kudu/tablet/metadata.proto
+++ b/src/kudu/tablet/metadata.proto
@@ -87,7 +87,21 @@ message TxnMetadataPB {
   // set.
   optional int64 commit_timestamp = 2;
 
-  // TODO(awong): persist the op timestamp for the commit's MVCC op.
+  // The timestamp used by the MVCC op that tracks the commit of this
+  // transaction. This is sent to the transaction status manager in response to
+  // a BEGIN_COMMIT request to be used to assign a commit timestamp that is
+  // higher than all participants' commit MVCC op timestamps.
+  //
+  // When iterating through mutations at a specific clean snapshot (as in a
+  // READ_AT_SNAPSHOT or diff scan), both this MVCC op timestamp and the commit
+  // timestamp must be applied for the mutation to be considered committed in
+  // that snapshot.
+  //
+  // When iterating through mutations at the latest snapshot (as in READ_LATEST
+  // or during compactions), this MVCC op timestamp must be applied and there
+  // must be a commit timestamp for the mutation to be considered committed --
+  // this avoids reading dirty, uncommitted rows.
+  optional int64 commit_mvcc_op_timestamp = 3;
 
   // TODO(awong): add an owner field to this for uncommitted transactions.
 }
diff --git a/src/kudu/tablet/ops/participant_op.cc 
b/src/kudu/tablet/ops/participant_op.cc
index 2241ad3..fb5295b 100644
--- a/src/kudu/tablet/ops/participant_op.cc
+++ b/src/kudu/tablet/ops/participant_op.cc
@@ -174,7 +174,7 @@ Status ParticipantOpState::PerformOp(const consensus::OpId& 
op_id, Tablet* table
       break;
     }
     case ParticipantOpPB::BEGIN_COMMIT: {
-      txn_->BeginCommit(op_id);
+      tablet->BeginCommit(txn_.get(), begin_commit_mvcc_op_->timestamp(), 
op_id);
       ReleaseMvccOpToTxn();
       break;
     }
diff --git a/src/kudu/tablet/tablet.cc b/src/kudu/tablet/tablet.cc
index badd25b..4badfb0 100644
--- a/src/kudu/tablet/tablet.cc
+++ b/src/kudu/tablet/tablet.cc
@@ -1041,6 +1041,14 @@ void Tablet::BeginTransaction(Txn* txn, const OpId& 
op_id) {
   txn->BeginTransaction();
 }
 
+void Tablet::BeginCommit(Txn* txn, Timestamp mvcc_op_ts, const OpId& op_id) {
+  unique_ptr<MinLogIndexAnchorer> anchor(new 
MinLogIndexAnchorer(log_anchor_registry_.get(),
+        Substitute("BEGIN_COMMIT-$0-$1", txn->txn_id(), txn)));
+  anchor->AnchorIfMinimum(op_id.index());
+  metadata_->BeginCommitTransaction(txn->txn_id(), mvcc_op_ts, 
std::move(anchor));
+  txn->BeginCommit(op_id);
+}
+
 void Tablet::CommitTransaction(Txn* txn, Timestamp commit_ts, const OpId& 
op_id) {
   unique_ptr<MinLogIndexAnchorer> anchor(new 
MinLogIndexAnchorer(log_anchor_registry_.get(),
         Substitute("FINALIZE_COMMIT-$0-$1", txn->txn_id(), txn)));
diff --git a/src/kudu/tablet/tablet.h b/src/kudu/tablet/tablet.h
index 24219bd..ce57bfb 100644
--- a/src/kudu/tablet/tablet.h
+++ b/src/kudu/tablet/tablet.h
@@ -183,6 +183,12 @@ class Tablet {
   // using 'txn' as the anchor owner.
   void BeginTransaction(Txn* txn, const consensus::OpId& op_id);
 
+  // Indicates that the transaction has started to commit, recording the
+  // timestamp used by the MVCC op to demarcate the end of the transaction in
+  // the tablet metadata. Upon calling this, 'op_id' will be anchored until
+  // the metadata is flushed, using 'txn' as the anchor owner.
+  void BeginCommit(Txn* txn, Timestamp mvcc_op_ts, const consensus::OpId& 
op_id);
+
   // Commits the transaction, recording its commit timestamp in the tablet 
metadata.
   // Upon calling this, 'op_id' will be anchored until the metadata is flushed,
   // using 'txn' as the anchor owner.
diff --git a/src/kudu/tablet/tablet_metadata-test.cc 
b/src/kudu/tablet/tablet_metadata-test.cc
index 254b4cb..de6d3e5 100644
--- a/src/kudu/tablet/tablet_metadata-test.cc
+++ b/src/kudu/tablet/tablet_metadata-test.cc
@@ -241,14 +241,18 @@ TEST_F(TestTabletMetadata, TestTxnMetadata) {
   int64_t kAbortedTxnId = 2;
   int64_t kInFlightTxnId = 3;
   meta->AddTxnMetadata(kCommittedTxnId, make_anchor());
+  meta->BeginCommitTransaction(kCommittedTxnId, kDummyTimestamp, 
make_anchor());
   meta->AddCommitTimestamp(kCommittedTxnId, kDummyTimestamp, make_anchor());
   ASSERT_EQ(1, meta->GetTxnMetadata().size());
 
   meta->AddTxnMetadata(kAbortedTxnId, make_anchor());
+  meta->BeginCommitTransaction(kAbortedTxnId, kDummyTimestamp, make_anchor());
   meta->AbortTransaction(kAbortedTxnId, make_anchor());
   ASSERT_EQ(2, meta->GetTxnMetadata().size());
 
   meta->AddTxnMetadata(kInFlightTxnId, make_anchor());
+  meta->BeginCommitTransaction(kInFlightTxnId, kDummyTimestamp, make_anchor());
+  ASSERT_EQ(3, meta->GetTxnMetadata().size());
 
   // Validate the transactions' fields.
   const auto validate_txn_metas = [&] (TabletMetadata* meta) {
@@ -260,16 +264,22 @@ TEST_F(TestTabletMetadata, TestTxnMetadata) {
 
     const auto& committed_txn = FindOrDie(txn_metas, kCommittedTxnId);
     ASSERT_FALSE(committed_txn->aborted());
+    ASSERT_NE(boost::none, committed_txn->commit_mvcc_op_timestamp());
+    ASSERT_EQ(kDummyTimestamp, *committed_txn->commit_mvcc_op_timestamp());
     ASSERT_NE(boost::none, committed_txn->commit_timestamp());
     ASSERT_EQ(kDummyTimestamp, *committed_txn->commit_timestamp());
 
     const auto& aborted_txn = FindOrDie(txn_metas, kAbortedTxnId);
     ASSERT_TRUE(aborted_txn->aborted());
     ASSERT_EQ(boost::none, aborted_txn->commit_timestamp());
+    ASSERT_NE(boost::none, aborted_txn->commit_mvcc_op_timestamp());
+    ASSERT_EQ(kDummyTimestamp, *aborted_txn->commit_mvcc_op_timestamp());
 
     const auto& in_flight_txn = FindOrDie(txn_metas, kInFlightTxnId);
     ASSERT_FALSE(in_flight_txn->aborted());
     ASSERT_EQ(boost::none, in_flight_txn->commit_timestamp());
+    ASSERT_NE(boost::none, in_flight_txn->commit_mvcc_op_timestamp());
+    ASSERT_EQ(kDummyTimestamp, *in_flight_txn->commit_mvcc_op_timestamp());
 
     unordered_set<int64_t> in_flight_txn_ids;
     unordered_set<int64_t> terminal_txn_ids;
diff --git a/src/kudu/tablet/tablet_metadata.cc 
b/src/kudu/tablet/tablet_metadata.cc
index 699d98b..07be998 100644
--- a/src/kudu/tablet/tablet_metadata.cc
+++ b/src/kudu/tablet/tablet_metadata.cc
@@ -505,6 +505,9 @@ Status TabletMetadata::LoadFromSuperBlock(const 
TabletSuperBlockPB& superblock)
       EmplaceOrDie(&txn_metas, txn_id_and_metadata.first,
           new TxnMetadata(
               txn_meta.has_aborted() && txn_meta.aborted(),
+              txn_meta.has_commit_mvcc_op_timestamp() ?
+                  
boost::make_optional(Timestamp(txn_meta.commit_mvcc_op_timestamp())) :
+                  boost::none,
               txn_meta.has_commit_timestamp() ?
                   boost::make_optional(Timestamp(txn_meta.commit_timestamp())) 
:
                   boost::none
@@ -742,6 +745,10 @@ Status 
TabletMetadata::ToSuperBlockUnlocked(TabletSuperBlockPB* super_block,
     if (commit_ts) {
       meta_pb.set_commit_timestamp(commit_ts->value());
     }
+    const auto& commit_mvcc_op_ts = txn_meta->commit_mvcc_op_timestamp();
+    if (commit_mvcc_op_ts) {
+      meta_pb.set_commit_mvcc_op_timestamp(commit_mvcc_op_ts->value());
+    }
     if (txn_meta->aborted()) {
       meta_pb.set_aborted(true);
     }
@@ -802,6 +809,20 @@ void TabletMetadata::AddTxnMetadata(int64_t txn_id, 
unique_ptr<MinLogIndexAnchor
   anchors_needing_flush_.emplace_back(std::move(log_anchor));
 }
 
+void TabletMetadata::BeginCommitTransaction(int64_t txn_id, Timestamp 
mvcc_op_timestamp,
+                                            unique_ptr<MinLogIndexAnchorer> 
log_anchor) {
+  std::lock_guard<LockType> l(data_lock_);
+  auto txn_metadata = FindPtrOrNull(txn_metadata_by_txn_id_, txn_id);
+  CHECK(txn_metadata);
+  // NOTE: we may already have an MVCC op timestamp if we are bootstrapping and
+  // the timestamp was persisted already, in which case, we don't need to
+  // anchor the WAL to ensure the timestamp's persistence in metadata.
+  if (!txn_metadata->commit_mvcc_op_timestamp()) {
+    txn_metadata->set_commit_mvcc_op_timestamp(mvcc_op_timestamp);
+    anchors_needing_flush_.emplace_back(std::move(log_anchor));
+  }
+}
+
 void TabletMetadata::AddCommitTimestamp(int64_t txn_id, Timestamp 
commit_timestamp,
                                         unique_ptr<MinLogIndexAnchorer> 
log_anchor) {
   std::lock_guard<LockType> l(data_lock_);
diff --git a/src/kudu/tablet/tablet_metadata.h 
b/src/kudu/tablet/tablet_metadata.h
index e8fbb3f..6bba726 100644
--- a/src/kudu/tablet/tablet_metadata.h
+++ b/src/kudu/tablet/tablet_metadata.h
@@ -242,6 +242,13 @@ class TabletMetadata : public 
RefCountedThreadSafe<TabletMetadata> {
   // have metadata associated with it.
   void AddTxnMetadata(int64_t txn_id, 
std::unique_ptr<log::MinLogIndexAnchorer> log_anchor);
 
+  // Records the fact that the given transaction has started committing, with
+  // the given timestamp as the end of its open window, adopting the anchor
+  // until the metadata is flushed. The transaction must already have metadata
+  // associated with it.
+  void BeginCommitTransaction(int64_t txn_id, Timestamp mvcc_op_timestamp,
+                              std::unique_ptr<log::MinLogIndexAnchorer> 
log_anchor);
+
   // Records the fact that the transaction was committed at the given
   // timestamp, adopting the anchor until the metadata is flushed. The
   // transaction must already have metadata associated with it.
diff --git a/src/kudu/tablet/txn_metadata.h b/src/kudu/tablet/txn_metadata.h
index ea2708b..177495e 100644
--- a/src/kudu/tablet/txn_metadata.h
+++ b/src/kudu/tablet/txn_metadata.h
@@ -30,12 +30,11 @@ namespace tablet {
 // Encapsulates the persistent state associated with a transaction.
 class TxnMetadata : public RefCountedThreadSafe<TxnMetadata> {
  public:
-  // TODO(awong): add commit_mvcc_op_timestamp to the contructor when reading
-  // from TxnMetadataPB.
   explicit TxnMetadata(bool aborted = false,
+                       boost::optional<Timestamp> commit_mvcc_op_timestamp = 
boost::none,
                        boost::optional<Timestamp> commit_ts = boost::none)
       : aborted_(aborted),
-        commit_mvcc_op_timestamp_(boost::none),
+        commit_mvcc_op_timestamp_(std::move(commit_mvcc_op_timestamp)),
         commit_timestamp_(std::move(commit_ts)) {}
   void set_aborted() {
     std::lock_guard<simple_spinlock> l(lock_);
@@ -45,13 +44,13 @@ class TxnMetadata : public 
RefCountedThreadSafe<TxnMetadata> {
   void set_commit_timestamp(Timestamp commit_ts) {
     std::lock_guard<simple_spinlock> l(lock_);
     CHECK(boost::none == commit_timestamp_);
+    CHECK(boost::none != commit_mvcc_op_timestamp_);
     CHECK(!aborted_);
     commit_timestamp_ = commit_ts;
   }
   void set_commit_mvcc_op_timestamp(Timestamp op_ts) {
     std::lock_guard<simple_spinlock> l(lock_);
     CHECK(boost::none == commit_timestamp_);
-    CHECK(boost::none == commit_mvcc_op_timestamp_);
     commit_mvcc_op_timestamp_ = op_ts;
   }
 
diff --git a/src/kudu/tablet/txn_participant-test.cc 
b/src/kudu/tablet/txn_participant-test.cc
index 02c9287..b1229fb 100644
--- a/src/kudu/tablet/txn_participant-test.cc
+++ b/src/kudu/tablet/txn_participant-test.cc
@@ -24,9 +24,11 @@
 #include <ostream>
 #include <string>
 #include <thread>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
+#include <boost/optional/optional.hpp>
 #include <gflags/gflags_declare.h>
 #include <glog/logging.h>
 #include <gtest/gtest.h>
@@ -52,6 +54,7 @@
 #include "kudu/tablet/tablet_metadata.h"
 #include "kudu/tablet/tablet_replica-test-base.h"
 #include "kudu/tablet/tablet_replica.h"
+#include "kudu/tablet/txn_metadata.h"
 #include "kudu/tablet/txn_participant-test-util.h"
 #include "kudu/tserver/tserver.pb.h"
 #include "kudu/tserver/tserver_admin.pb.h"
@@ -464,9 +467,13 @@ TEST_F(TxnParticipantTest, TestTxnMetadataSurvivesRestart) 
{
   ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId, 
ParticipantOpPB::BEGIN_COMMIT,
                               kDummyCommitTimestamp, &resp));
   ASSERT_FALSE(resp.has_error());
-  ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
   ASSERT_OK(tablet_replica_->log()->WaitUntilAllFlushed());
   ASSERT_OK(tablet_replica_->log()->AllocateSegmentAndRollOverForTests());
+  // There should be two anchors for this op: one that is in place until the
+  // FINALIZE_COMMIT op, another until we flush.
+  ASSERT_EQ(2, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+  ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
+  ASSERT_EQ(1, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
   ASSERT_OK(tablet_replica_->GetGCableDataSize(&gcable_size));
   ASSERT_GT(gcable_size, 0);
   ASSERT_OK(tablet_replica_->RunLogGC());
@@ -513,6 +520,104 @@ TEST_F(TxnParticipantTest, 
TestTxnMetadataSurvivesRestart) {
   }), txn_participant()->GetTxnsForTests());
 }
 
+// Test that we can replay BEGIN_COMMIT ops, given it anchors WALs until
+// metadata flush _and_ until the transaction is finalized or aborted.
+TEST_F(TxnParticipantTest, TestBeginCommitAnchorsOnFlush) {
+  const int64_t kTxnId = 1;
+  ParticipantResponsePB resp;
+  // Start a transaction and begin committing.
+  ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId, 
ParticipantOpPB::BEGIN_TXN,
+                              kDummyCommitTimestamp, &resp));
+  ASSERT_FALSE(resp.has_error());
+  ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
+  auto txn_meta = 
FindOrDie(tablet_replica_->tablet_metadata()->GetTxnMetadata(), kTxnId);
+  ASSERT_EQ(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId, 
ParticipantOpPB::BEGIN_COMMIT,
+                              kDummyCommitTimestamp, &resp));
+  ASSERT_FALSE(resp.has_error());
+  // We should have two anchors: one that lasts until we flush, another that
+  // lasts until we finalize the commit.
+  ASSERT_EQ(2, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+
+  // We should have an MVCC op timestamp in the metadata, even after
+  // restarting.
+  ASSERT_NE(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  const auto orig_mvcc_op_timestamp = *txn_meta->commit_mvcc_op_timestamp();
+  txn_meta.reset();
+  RestartReplica(/*reset_tablet*/true);
+  txn_meta = FindOrDie(tablet_replica_->tablet_metadata()->GetTxnMetadata(), 
kTxnId);
+  ASSERT_NE(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  ASSERT_EQ(orig_mvcc_op_timestamp, *txn_meta->commit_mvcc_op_timestamp());
+
+  // Once we flush, we should drop down to one anchor.
+  ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
+  ASSERT_EQ(1, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+  ASSERT_OK(RestartReplica(/*reset_tablet*/true));
+  ASSERT_EQ(1, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+  ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId, 
ParticipantOpPB::FINALIZE_COMMIT,
+                              kDummyCommitTimestamp, &resp));
+  ASSERT_FALSE(resp.has_error());
+
+  // The anchor from the BEGIN_COMMIT op should be gone, but we should have
+  // another anchor for the FINALIZE_COMMIT op until we flush the metadata.
+  ASSERT_EQ(1, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+  ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
+  ASSERT_EQ(0, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+
+  // As another sanity check, we should still have metadata for the MVCC op
+  // after restarting.
+  ASSERT_NE(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  txn_meta.reset();
+  RestartReplica(/*reset_tablet*/true);
+  txn_meta = FindOrDie(tablet_replica_->tablet_metadata()->GetTxnMetadata(), 
kTxnId);
+  ASSERT_NE(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  ASSERT_EQ(orig_mvcc_op_timestamp, *txn_meta->commit_mvcc_op_timestamp());
+}
+
+// Like the above test but finalizing the commit before flushing the metadata.
+TEST_F(TxnParticipantTest, TestBeginCommitAnchorsOnFinalize) {
+  const int64_t kTxnId = 1;
+  ParticipantResponsePB resp;
+  ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId, 
ParticipantOpPB::BEGIN_TXN,
+                              kDummyCommitTimestamp, &resp));
+  ASSERT_FALSE(resp.has_error());
+  auto txn_meta = 
FindOrDie(tablet_replica_->tablet_metadata()->GetTxnMetadata(), kTxnId);
+  ASSERT_EQ(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
+  ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId, 
ParticipantOpPB::BEGIN_COMMIT,
+                              kDummyCommitTimestamp, &resp));
+  ASSERT_FALSE(resp.has_error());
+  ASSERT_NE(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  const auto orig_mvcc_op_timestamp = *txn_meta->commit_mvcc_op_timestamp();
+
+  // Restarting shouldn't affect our metadata.
+  txn_meta.reset();
+  RestartReplica(/*reset_tablet*/true);
+  txn_meta = FindOrDie(tablet_replica_->tablet_metadata()->GetTxnMetadata(), 
kTxnId);
+  ASSERT_NE(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  ASSERT_EQ(orig_mvcc_op_timestamp, *txn_meta->commit_mvcc_op_timestamp());
+
+  // We should have two anchors, one that lasts until we flush, another that
+  // lasts until we finalize.
+  ASSERT_EQ(2, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+  ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId,
+                              ParticipantOpPB::FINALIZE_COMMIT, 
kDummyCommitTimestamp, &resp));
+  ASSERT_FALSE(resp.has_error());
+
+  // Finalizing the commit shouldn't affect our metadata.
+  txn_meta.reset();
+  RestartReplica(/*reset_tablet*/true);
+  txn_meta = FindOrDie(tablet_replica_->tablet_metadata()->GetTxnMetadata(), 
kTxnId);
+  ASSERT_NE(boost::none, txn_meta->commit_mvcc_op_timestamp());
+  ASSERT_EQ(orig_mvcc_op_timestamp, *txn_meta->commit_mvcc_op_timestamp());
+
+  // One anchor should be gone and another should be registered in its place
+  // that lasts until we flush the finalized metadata.
+  ASSERT_EQ(2, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+  ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
+  ASSERT_EQ(0, 
tablet_replica_->log_anchor_registry()->GetAnchorCountForTests());
+}
+
 class MetadataFlushTxnParticipantTest : public TxnParticipantTest,
                                         public 
::testing::WithParamInterface<bool> {};
 
@@ -535,8 +640,9 @@ TEST_P(MetadataFlushTxnParticipantTest, 
TestRebuildTxnMetadata) {
   ASSERT_OK(CallParticipantOp(tablet_replica_.get(), kTxnId, 
ParticipantOpPB::BEGIN_COMMIT,
                               kDummyCommitTimestamp, &resp));
   ASSERT_FALSE(resp.has_error());
-  // NOTE: BEGIN_COMMIT ops don't anchor on metadata flush, so don't bother
-  // flushing.
+  if (should_flush) {
+    ASSERT_OK(tablet_replica_->tablet_metadata()->Flush());
+  }
 
   ASSERT_OK(RestartReplica(/*reset_tablet*/true));
   ASSERT_EQ(vector<TxnParticipant::TxnEntry>({

Reply via email to