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

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


The following commit(s) were added to refs/heads/branch-1.15.x by this push:
     new 116e529  [txns] add fields for create and update times
116e529 is described below

commit 116e529c8ea5595c24ac93ff006764f24abb4684
Author: Andrew Wong <aw...@cloudera.com>
AuthorDate: Sun May 16 17:16:12 2021 -0700

    [txns] add fields for create and update times
    
    This patch adds fields to the transaction status entry for the start
    time and the last update time. This is reported in both the `txn list`
    and `txn show` tools.
    
    $ ./bin/kudu txn list 0.0.0.0:8764  --included_states="*"
     txn_id | user  |   state   |        commit_datetime        |        
start_datetime         |   last_transition_datetime
    
--------+-------+-----------+-------------------------------+-------------------------------+-------------------------------
     0      | awong | COMMITTED | Thu, 29 Apr 2021 18:54:56 GMT | <none>        
                | <none>
     1      | awong | COMMITTED | Thu, 29 Apr 2021 22:12:53 GMT | <none>        
                | <none>
     2      | awong | ABORTED   | <none>                        | <none>        
                | <none>
     3      | awong | ABORTED   | <none>                        | <none>        
                | <none>
     4      | awong | COMMITTED | Tue, 18 May 2021 07:41:34 GMT | Tue, 18 May 
2021 07:41:34 GMT | Tue, 18 May 2021 07:41:34 GMT
     5      | awong | ABORTED   | <none>                        | Tue, 18 May 
2021 07:42:22 GMT | Tue, 18 May 2021 07:42:56 GMT
     6      | awong | COMMITTED | Tue, 18 May 2021 07:42:33 GMT | Tue, 18 May 
2021 07:42:32 GMT | Tue, 18 May 2021 07:42:33 GMT
     7      | awong | ABORTED   | <none>                        | Tue, 18 May 
2021 07:47:16 GMT | Tue, 18 May 2021 07:47:46 GMT
    
    Change-Id: I4d4f77b4c9b7fcc3f7f749b7f79a18a24be3ce4d
    Reviewed-on: http://gerrit.cloudera.org:8080/17475
    Reviewed-by: Alexey Serbin <aser...@cloudera.com>
    Tested-by: Kudu Jenkins
    (cherry picked from commit 1a8e8c39a7bb378da6d10e88aae80bf4eeb2a057)
    Reviewed-on: http://gerrit.cloudera.org:8080/17476
    Reviewed-by: Bankim Bhavsar <ban...@cloudera.com>
---
 src/kudu/tools/kudu-txn-cli-test.cc             | 47 +++++++++++++++----------
 src/kudu/tools/tool_action_txn.cc               | 30 ++++++++++++----
 src/kudu/transactions/transactions.proto        |  8 +++++
 src/kudu/transactions/txn_status_manager.cc     | 11 +++++-
 src/kudu/transactions/txn_status_tablet-test.cc | 19 ++++++----
 src/kudu/transactions/txn_status_tablet.cc      |  6 ++--
 src/kudu/transactions/txn_status_tablet.h       |  2 +-
 7 files changed, 87 insertions(+), 36 deletions(-)

diff --git a/src/kudu/tools/kudu-txn-cli-test.cc 
b/src/kudu/tools/kudu-txn-cli-test.cc
index 502565b..e4ea01f 100644
--- a/src/kudu/tools/kudu-txn-cli-test.cc
+++ b/src/kudu/tools/kudu-txn-cli-test.cc
@@ -87,27 +87,31 @@ TEST_F(KuduTxnsCliTest, TestBasicTxnsList) {
   string out;
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString(),
                           "--included_states=*" }, &out));
-  ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\|   state   \| *commit_datetime
---------\+-*\+-----------\+-*
- 0      \| *[a-z]* *\| COMMITTED \| .* GMT
- 1      \| *[a-z]* *\| ABORTED   \| <none>
- 2      \| *[a-z]* *\| OPEN      \| <none>)");
+  ASSERT_STR_MATCHES(out,
+R"(txn_id \| *user *\| *state *\| *commit_datetime *\| *start_datetime *\| 
*last_transition_datetime
+--------\+-*\+-----------\+-*\+-*\+-*
+ 0      \| *[a-z]* *\| COMMITTED \| .* GMT *\| .* GMT *\| .* GMT
+ 1      \| *[a-z]* *\| ABORTED   \| <none> *\| .* GMT *\| .* GMT
+ 2      \| *[a-z]* *\| OPEN      \| <none> *\| .* GMT *\| .* GMT)");
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString(),
                           "--included_states=aborted,open" }, &out));
-  ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\|  state  \| *commit_datetime
---------\+-*\+---------\+-*
- 1      \| *[a-z]* *\| ABORTED \| <none>
- 2      \| *[a-z]* *\| OPEN    \| <none>)");
+  ASSERT_STR_MATCHES(out,
+R"(txn_id \| *user *\| *state *\| *commit_datetime *\| *start_datetime *\| 
*last_transition_datetime
+--------\+-*\+---------\+-*\+-*\+-*
+ 1      \| *[a-z]* *\| ABORTED \| <none> *\| .* GMT *\| .* GMT
+ 2      \| *[a-z]* *\| OPEN    \| <none> *\| .* GMT *\| .* GMT)");
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString(),
                           "--included_states=open,committed" }, &out));
-  ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\|   state   \| *commit_datetime
---------\+-*\+-----------\+-*
- 0      \| *[a-z]* *\| COMMITTED \| .* GMT
- 2      \| *[a-z]* *\| OPEN      \| <none>)");
+  ASSERT_STR_MATCHES(out,
+R"(txn_id \| *user *\| *state *\| *commit_datetime *\| *start_datetime *\| 
*last_transition_datetime
+--------\+-*\+-----------\+-*\+-*\+-*
+ 0      \| *[a-z]* *\| COMMITTED \| .* GMT *\| .* GMT *\| .* GMT
+ 2      \| *[a-z]* *\| OPEN      \| <none> *\| .* GMT *\| .* GMT)");
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString() }, &out));
-  ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\| state \| *commit_datetime
---------\+-*\+-------\+-*
- 2      \| *[a-z]* *\| OPEN  \| <none>)");
+  ASSERT_STR_MATCHES(out,
+R"(txn_id \| *user *\| *state *\| *commit_datetime *\| *start_datetime *\| 
*last_transition_datetime
+--------\+-*\+-------\+-*\+-*\+-*
+ 2      \| *[a-z]* *\| OPEN  \| <none> *\| .* GMT *\| .* GMT)");
 }
 
 TEST_F(KuduTxnsCliTest, TestTxnsListMinMaxFilter) {
@@ -125,6 +129,7 @@ TEST_F(KuduTxnsCliTest, TestTxnsListMinMaxFilter) {
   }
   string out;
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString(),
+                          "--columns=txn_id,user,state,commit_datetime",
                           "--min_txn_id=7", "--included_states=*" }, &out));
   ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\|   state   \| *commit_datetime
 --------\+-*\+-----------\+-*
@@ -132,6 +137,7 @@ TEST_F(KuduTxnsCliTest, TestTxnsListMinMaxFilter) {
  8      \| *[a-z]* *\| COMMITTED \| .* GMT
  9      \| *[a-z]* *\| COMMITTED \| .* GMT)");
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString(),
+                          "--columns=txn_id,user,state,commit_datetime",
                           "--max_txn_id=2", "--included_states=*" }, &out));
   ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\|   state   \| *commit_datetime
 --------\+-*\+-----------\+-*
@@ -139,6 +145,7 @@ TEST_F(KuduTxnsCliTest, TestTxnsListMinMaxFilter) {
  1      \| *[a-z]* *\| COMMITTED \| .* GMT
  2      \| *[a-z]* *\| COMMITTED \| .* GMT)");
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString(),
+                          "--columns=txn_id,user,state,commit_datetime",
                           "--min_txn_id=5", "--max_txn_id=7", 
"--included_states=*" }, &out));
   ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\|   state   \| *commit_datetime
 --------\+-*\+-----------\+-*
@@ -146,6 +153,7 @@ TEST_F(KuduTxnsCliTest, TestTxnsListMinMaxFilter) {
  6      \| *[a-z]* *\| COMMITTED \| .* GMT
  7      \| *[a-z]* *\| COMMITTED \| .* GMT)");
   ASSERT_OK(RunKuduTool({ "txn", "list", 
cluster_->master_rpc_addrs()[0].ToString(),
+                          "--columns=txn_id,user,state,commit_datetime",
                           "--min_txn_id=10", "--max_txn_id=0", 
"--included_states=*" }, &out));
   ASSERT_EQ(
       " txn_id | user | state | commit_datetime\n"
@@ -189,9 +197,10 @@ TEST_F(KuduTxnsCliTest, TestBasicShowTxn) {
   // Check the output of the tool with no arguments.
   string out;
   ASSERT_OK(RunKuduTool({ "txn", "show", 
cluster_->master_rpc_addrs()[0].ToString(), "0" }, &out));
-  ASSERT_STR_MATCHES(out, R"( txn_id \| *user *\|   state   \| *commit_datetime
---------\+-*\+-----------\+-*
- 0      \| *[a-z]* *\| COMMITTED \| .* GMT
+  ASSERT_STR_MATCHES(out,
+R"(txn_id \| *user *\| *state *\| *commit_datetime *\| *start_datetime *\| 
*last_transition_datetime
+--------\+-*\+-----------\+-*\+-*\+-*
+ 0      \| *[a-z]* *\| COMMITTED \| .* GMT \| .* GMT \| .* GMT
 
             tablet_id             \| *begin_commit_datetime *\| 
*commit_datetime
 ----------------------------------\+-*\+-*
diff --git a/src/kudu/tools/tool_action_txn.cc 
b/src/kudu/tools/tool_action_txn.cc
index ab9d201..a1cf35a 100644
--- a/src/kudu/tools/tool_action_txn.cc
+++ b/src/kudu/tools/tool_action_txn.cc
@@ -104,6 +104,8 @@ enum class ListTxnsField : int {
   kState,
   kCommitDateTime,
   kCommitHybridTime,
+  kStartDatetime,
+  kLastTransitionDatetime,
 };
 
 const unordered_map<string, ListTxnsField> kStrToTxnField {
@@ -112,6 +114,8 @@ const unordered_map<string, ListTxnsField> kStrToTxnField {
   { "state", ListTxnsField::kState },
   { "commit_datetime", ListTxnsField::kCommitDateTime },
   { "commit_hybridtime", ListTxnsField::kCommitHybridTime },
+  { "start_datetime", ListTxnsField::kStartDatetime },
+  { "last_transition_datetime", ListTxnsField::kLastTransitionDatetime },
 };
 
 enum class ParticipantField : int {
@@ -210,7 +214,7 @@ Status GetFields(vector<string>* txn_field_names, 
vector<ListTxnsField>* txn_fie
 }
 
 void AddTxnStatusRow(const vector<ListTxnsField>& fields, int64_t txn_id,
-                       const TxnStatusEntryPB& txn_entry_pb, DataTable* 
data_table) {
+                     const TxnStatusEntryPB& txn_entry_pb, DataTable* 
data_table) {
   string commit_ts_ht_str = "<none>";
   string commit_ts_date_str = "<none>";
   vector<string> col_vals;
@@ -233,6 +237,18 @@ void AddTxnStatusRow(const vector<ListTxnsField>& fields, 
int64_t txn_id,
         col_vals.emplace_back(txn_entry_pb.has_commit_timestamp() ?
             
HybridClock::StringifyTimestamp(Timestamp(txn_entry_pb.commit_timestamp())) : 
"<none>");
         break;
+      case ListTxnsField::kStartDatetime: {
+        char buf[kFastToBufferSize];
+        col_vals.emplace_back(txn_entry_pb.has_start_timestamp() ?
+            FastTimeToBuffer(txn_entry_pb.start_timestamp(), buf) : "<none>");
+        break;
+      }
+      case ListTxnsField::kLastTransitionDatetime: {
+        char buf[kFastToBufferSize];
+        col_vals.emplace_back(txn_entry_pb.has_last_transition_timestamp() ?
+            FastTimeToBuffer(txn_entry_pb.last_transition_timestamp(), buf) : 
"<none>");
+        break;
+      }
     }
   }
   data_table->AddRow(std::move(col_vals));
@@ -425,10 +441,10 @@ unique_ptr<Mode> BuildTxnMode() {
       .Description("Show details of multi-row transactions in the cluster")
       .AddOptionalParameter(
           "columns",
-          string("txn_id,user,state,commit_datetime"),
+          
string("txn_id,user,state,commit_datetime,start_datetime,last_transition_datetime"),
           string("Comma-separated list of transaction-related info fields to 
include "
                  "in the output.\nPossible values: txn_id, user, state, 
commit_datetime, "
-                 "commit_hybridtime"))
+                 "commit_hybridtime, start_datetime, 
last_transition_datetime"))
       .AddOptionalParameter("max_txn_id")
       .AddOptionalParameter("min_txn_id")
       .AddOptionalParameter("included_states")
@@ -441,11 +457,13 @@ unique_ptr<Mode> BuildTxnMode() {
       .AddRequiredParameter({ kTxnIdArg, "Transaction ID on which to operate" 
})
       .AddOptionalParameter(
           "columns",
-          string("txn_id,user,state,commit_datetime,participant_tablet_id,"
-                 
"participant_begin_commit_datetime,participant_commit_datetime"),
+          
string("txn_id,user,state,commit_datetime,start_datetime,last_transition_datetime,"
+                 "participant_tablet_id,participant_begin_commit_datetime,"
+                 "participant_commit_datetime"),
           string("Comma-separated list of transaction-related info fields to 
include "
                  "in the output.\nPossible values: txn_id, user, state, 
commit_datetime, "
-                 "commit_hybridtime, participant_tablet_id, 
participant_is_aborted, "
+                 "commit_hybridtime, start_datetime, last_transition_datetime, 
"
+                 "participant_tablet_id, participant_is_aborted, "
                  "participant_flushed_committed_mrs, 
participant_begin_commit_datetime, "
                  "participant_begin_commit_hybridtime, 
participant_commit_datetime, "
                  "participant_commit_hybridtime"))
diff --git a/src/kudu/transactions/transactions.proto 
b/src/kudu/transactions/transactions.proto
index a58d8bd..f00eb83 100644
--- a/src/kudu/transactions/transactions.proto
+++ b/src/kudu/transactions/transactions.proto
@@ -68,6 +68,14 @@ message TxnStatusEntryPB {
 
   // Commit timestamp associated with this transaction.
   optional fixed64 commit_timestamp = 3;
+
+  // The timestamp in seconds since the epoch that this transaction was
+  // started.
+  optional int64 start_timestamp = 4;
+
+  // The timestamp in seconds since the epoch that this transaction had a state
+  // change.
+  optional int64 last_transition_timestamp = 5;
 }
 
 // Metadata encapsulating the existence of a transaction participant.
diff --git a/src/kudu/transactions/txn_status_manager.cc 
b/src/kudu/transactions/txn_status_manager.cc
index 26245dc..d3889dd 100644
--- a/src/kudu/transactions/txn_status_manager.cc
+++ b/src/kudu/transactions/txn_status_manager.cc
@@ -18,6 +18,7 @@
 #include "kudu/transactions/txn_status_manager.h"
 
 #include <algorithm>
+#include <ctime>
 #include <functional>
 #include <iterator>
 #include <mutex>
@@ -987,7 +988,8 @@ Status TxnStatusManager::BeginTransaction(int64_t txn_id,
     }
   });
   // Write an entry to the status tablet for this transaction.
-  RETURN_NOT_OK(status_tablet_.AddNewTransaction(txn_id, user, ts_error));
+  const auto start_timestamp = time(nullptr);
+  RETURN_NOT_OK(status_tablet_.AddNewTransaction(txn_id, user, 
start_timestamp, ts_error));
 
   // Now that we've successfully persisted the new transaction ID, initialize
   // the in-memory state and make it visible to clients.
@@ -996,6 +998,8 @@ Status TxnStatusManager::BeginTransaction(int64_t txn_id,
     TransactionEntryLock txn_lock(txn.get(), LockMode::WRITE);
     txn_lock.mutable_data()->pb.set_state(TxnStatePB::OPEN);
     txn_lock.mutable_data()->pb.set_user(user);
+    txn_lock.mutable_data()->pb.set_start_timestamp(start_timestamp);
+    txn_lock.mutable_data()->pb.set_last_transition_timestamp(start_timestamp);
     txn_lock.Commit();
   }
   std::lock_guard<simple_spinlock> l(lock_);
@@ -1056,6 +1060,7 @@ Status TxnStatusManager::BeginCommitTransaction(int64_t 
txn_id, const string& us
                                  ts_error);
   }
   auto* mutable_data = txn_lock.mutable_data();
+  mutable_data->pb.set_last_transition_timestamp(time(nullptr));
   mutable_data->pb.set_state(TxnStatePB::COMMIT_IN_PROGRESS);
   RETURN_NOT_OK(status_tablet_.UpdateTransaction(txn_id, mutable_data->pb, 
ts_error));
 
@@ -1097,6 +1102,7 @@ Status TxnStatusManager::FinalizeCommitTransaction(
         ts_error);
   }
   auto* mutable_data = txn_lock.mutable_data();
+  mutable_data->pb.set_last_transition_timestamp(time(nullptr));
   mutable_data->pb.set_state(TxnStatePB::FINALIZE_IN_PROGRESS);
   mutable_data->pb.set_commit_timestamp(commit_timestamp.value());
   RETURN_NOT_OK(status_tablet_.UpdateTransaction(
@@ -1133,6 +1139,7 @@ Status 
TxnStatusManager::CompleteCommitTransaction(int64_t txn_id) {
         &ts_error);
   }
   auto* mutable_data = txn_lock.mutable_data();
+  mutable_data->pb.set_last_transition_timestamp(time(nullptr));
   mutable_data->pb.set_state(TxnStatePB::COMMITTED);
   RETURN_NOT_OK(status_tablet_.UpdateTransaction(
       txn_id, mutable_data->pb, &ts_error));
@@ -1165,6 +1172,7 @@ Status TxnStatusManager::FinalizeAbortTransaction(int64_t 
txn_id) {
         &ts_error);
   }
   auto* mutable_data = txn_lock.mutable_data();
+  mutable_data->pb.set_last_transition_timestamp(time(nullptr));
   mutable_data->pb.set_state(TxnStatePB::ABORTED);
   RETURN_NOT_OK(status_tablet_.UpdateTransaction(txn_id, mutable_data->pb, 
&ts_error));
   txn_lock.Commit();
@@ -1216,6 +1224,7 @@ Status TxnStatusManager::BeginAbortTransaction(int64_t 
txn_id,
         ts_error);
   }
   auto* mutable_data = txn_lock.mutable_data();
+  mutable_data->pb.set_last_transition_timestamp(time(nullptr));
   mutable_data->pb.set_state(TxnStatePB::ABORT_IN_PROGRESS);
   RETURN_NOT_OK(status_tablet_.UpdateTransaction(txn_id, mutable_data->pb, 
ts_error));
 
diff --git a/src/kudu/transactions/txn_status_tablet-test.cc 
b/src/kudu/transactions/txn_status_tablet-test.cc
index 79498ac..964f3eb 100644
--- a/src/kudu/transactions/txn_status_tablet-test.cc
+++ b/src/kudu/transactions/txn_status_tablet-test.cc
@@ -62,6 +62,7 @@ const char kParticipant[] = "peanutbutter";
 string ParticipantId(int i) {
   return Substitute("$0$1", kParticipant, i);
 }
+constexpr const int64_t kFakeTime = 43110;
 
 // Simple representation of an entry in the transaction status tablet.
 struct SimpleEntry {
@@ -73,6 +74,8 @@ struct SimpleEntry {
   static SimpleEntry Create(int64_t txn_id, const string& user, TxnStatePB 
txn_state_pb,
                             vector<std::pair<string, TxnStatePB>> 
participants) {
     TxnStatusEntryPB txn_pb;
+    txn_pb.set_start_timestamp(kFakeTime);
+    txn_pb.set_last_transition_timestamp(kFakeTime);
     txn_pb.set_state(txn_state_pb);
     txn_pb.set_user(user);
     vector<ParticipantIdAndPB> prt_pbs;
@@ -140,16 +143,18 @@ TEST_F(TxnStatusTabletTest, TestWriteTransactions) {
   TabletServerErrorPB ts_error;
   // We can make multiple calls to add a single transaction. This will only
   // insert a single row to the table.
-  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, &ts_error));
-  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, &ts_error));
+  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, kFakeTime, 
&ts_error));
+  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, kFakeTime, 
&ts_error));
 
   // The storage abstraction doesn't prevent us from writing a new transaction
   // entry for a lower transaction ID.
-  ASSERT_OK(status_tablet_->AddNewTransaction(5, kOwner, &ts_error));
-  ASSERT_OK(status_tablet_->AddNewTransaction(2, kOwner, &ts_error));
+  ASSERT_OK(status_tablet_->AddNewTransaction(5, kOwner, kFakeTime, 
&ts_error));
+  ASSERT_OK(status_tablet_->AddNewTransaction(2, kOwner, kFakeTime, 
&ts_error));
 
   // Also try updating the status of one of our transaction entries.
   TxnStatusEntryPB status_entry_pb;
+  status_entry_pb.set_start_timestamp(kFakeTime);
+  status_entry_pb.set_last_transition_timestamp(kFakeTime);
   status_entry_pb.set_user(kOwner);
   status_entry_pb.set_state(TxnStatePB::ABORTED);
   ASSERT_OK(status_tablet_->UpdateTransaction(2, status_entry_pb, &ts_error));
@@ -173,7 +178,7 @@ TEST_F(TxnStatusTabletTest, TestWriteTransactions) {
 
 TEST_F(TxnStatusTabletTest, TestWriteParticipants) {
   TabletServerErrorPB ts_error;
-  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, &ts_error));
+  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, kFakeTime, 
&ts_error));
 
   // Participants will be de-duplicated.
   ASSERT_OK(status_tablet_->AddNewParticipant(1, ParticipantId(1), &ts_error));
@@ -214,7 +219,7 @@ TEST_F(TxnStatusTabletTest, TestFailedVisitor) {
   ASSERT_STR_CONTAINS(s.ToString(), "missing transaction status entry");
 
   // Now try again but with the transaction ID written.
-  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, &ts_error));
+  ASSERT_OK(status_tablet_->AddNewTransaction(1, kOwner, kFakeTime, 
&ts_error));
   ASSERT_OK(status_tablet_->VisitTransactions(&visitor));
 
   // And again with a new transaction ID.
@@ -244,7 +249,7 @@ TEST_F(TxnStatusTabletTest, TestMultithreadedAccess) {
   for (int i = 0; i < kNumThreads; i++) {
     threads.emplace_back([&, i] {
       TabletServerErrorPB ts_error;
-      RET_IF_NOT_OK(status_tablet_->AddNewTransaction(i, kOwner, &ts_error));
+      RET_IF_NOT_OK(status_tablet_->AddNewTransaction(i, kOwner, kFakeTime, 
&ts_error));
       for (int p = 0; p < kNumParticipantsPerTransaction; p++) {
         RET_IF_NOT_OK(status_tablet_->AddNewParticipant(i, 
Substitute("prt-$0", p), &ts_error));
       }
diff --git a/src/kudu/transactions/txn_status_tablet.cc 
b/src/kudu/transactions/txn_status_tablet.cc
index feb2698..a04e1c9 100644
--- a/src/kudu/transactions/txn_status_tablet.cc
+++ b/src/kudu/transactions/txn_status_tablet.cc
@@ -31,13 +31,13 @@
 #include "kudu/common/iterator.h"
 #include "kudu/common/partial_row.h"
 #include "kudu/common/row_operations.h"
+#include "kudu/common/row_operations.pb.h"
 #include "kudu/common/rowblock.h"
 #include "kudu/common/rowblock_memory.h"
 #include "kudu/common/scan_spec.h"
 #include "kudu/common/schema.h"
 #include "kudu/common/types.h"
 #include "kudu/common/wire_protocol.h"
-#include "kudu/common/wire_protocol.pb.h"
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/tablet/ops/op.h"
@@ -297,12 +297,14 @@ Status 
TxnStatusTablet::VisitTransactions(TransactionsVisitor* visitor) {
 }
 
 Status TxnStatusTablet::AddNewTransaction(int64_t txn_id, const string& user,
-                                          TabletServerErrorPB* ts_error) {
+                                          int64_t start_timestamp, 
TabletServerErrorPB* ts_error) {
   WriteRequestPB req = BuildWriteReqPB(tablet_replica_->tablet_id());
 
   TxnStatusEntryPB entry;
   entry.set_state(OPEN);
   entry.set_user(user);
+  entry.set_start_timestamp(start_timestamp);
+  entry.set_last_transition_timestamp(start_timestamp);
   faststring metadata_buf;
   pb_util::SerializeToString(entry, &metadata_buf);
 
diff --git a/src/kudu/transactions/txn_status_tablet.h 
b/src/kudu/transactions/txn_status_tablet.h
index 024244c..880c270 100644
--- a/src/kudu/transactions/txn_status_tablet.h
+++ b/src/kudu/transactions/txn_status_tablet.h
@@ -107,7 +107,7 @@ class TxnStatusTablet {
   // error. If there was otherwise a logical error with the request (e.g. row
   // already exists), returns an error without populating 'ts_error'.
   Status AddNewTransaction(int64_t txn_id, const std::string& user,
-                           tserver::TabletServerErrorPB* ts_error);
+                           int64_t start_timestamp, 
tserver::TabletServerErrorPB* ts_error);
   Status UpdateTransaction(int64_t txn_id, const TxnStatusEntryPB& pb,
                            tserver::TabletServerErrorPB* ts_error);
   Status AddNewParticipant(int64_t txn_id, const std::string& tablet_id,

Reply via email to