From 39ba88b7336ee0ff33470ba14ed2564b939ee1f0 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 5 Dec 2018 12:23:07 -0500 Subject: [PATCH] kv,storage,sql: purge snapshot isolation Snapshot isolation was disabled in v2.1, so it is safe to remove all code paths that handle snapshot isolation in v2.2. Note that the change to the MVCCMetadata checksum in pkg/storage/below_raft_protos_test.go is safe, because the actual encoding of the protobuf is not affected by this change. What is affected is NewPopulatedMVCCMetadata, which no longer returns a TxnMeta with a non-zero IsolationType, since the IsolationType field has been removed. This is a necessary precursor to #32487. Release note: None --- c-deps/libroach/protos/roachpb/data.pb.cc | 29 - c-deps/libroach/protos/roachpb/data.pb.h | 21 - .../storage/engine/enginepb/mvcc3.pb.cc | 50 +- .../protos/storage/engine/enginepb/mvcc3.pb.h | 41 - pkg/internal/client/client_test.go | 42 +- pkg/internal/client/sender.go | 10 - pkg/internal/client/txn.go | 25 - pkg/kv/dist_sender_server_test.go | 3 +- pkg/kv/dist_sender_test.go | 5 +- pkg/kv/txn_coord_sender.go | 29 +- pkg/kv/txn_coord_sender_test.go | 22 +- pkg/kv/txn_correctness_test.go | 195 ++-- pkg/kv/txn_interceptor_pipeliner_test.go | 2 +- pkg/kv/txn_interceptor_span_refresher.go | 44 +- pkg/kv/txn_test.go | 205 +---- pkg/roachpb/batch_test.go | 3 +- pkg/roachpb/data.go | 30 +- pkg/roachpb/data.pb.go | 293 +++--- pkg/roachpb/data.proto | 16 +- pkg/roachpb/data_test.go | 7 +- pkg/roachpb/errors.pb.go | 354 ++++---- pkg/roachpb/errors.proto | 4 +- pkg/roachpb/errors_test.go | 3 +- pkg/roachpb/string_test.go | 6 +- pkg/server/server_test.go | 2 +- pkg/sql/conn_executor.go | 25 +- pkg/sql/conn_executor_exec.go | 15 +- pkg/sql/conn_fsm.go | 7 +- pkg/sql/distsqlrun/cluster_test.go | 4 - pkg/sql/exec_util.go | 5 - pkg/sql/lease.go | 7 - pkg/sql/sem/tree/timeconv_test.go | 2 - pkg/sql/sem/tree/txn.go | 1 - pkg/sql/sessiondata/session_data.go | 4 - pkg/sql/set_default_isolation.go | 6 +- pkg/sql/txn_state.go | 20 - pkg/sql/txn_state_test.go | 16 +- pkg/sql/vars.go | 14 +- pkg/storage/batcheval/cmd_add_sstable_test.go | 1 - pkg/storage/batcheval/cmd_delete_range.go | 8 - pkg/storage/batcheval/cmd_end_transaction.go | 16 +- pkg/storage/batcheval/cmd_push_txn.go | 6 - pkg/storage/batcheval/cmd_query_intent.go | 20 +- pkg/storage/below_raft_protos_test.go | 2 +- pkg/storage/client_metrics_test.go | 3 +- pkg/storage/client_replica_test.go | 5 +- pkg/storage/client_split_test.go | 7 +- pkg/storage/closed_timestamp_test.go | 3 +- pkg/storage/engine/enginepb/mvcc3.go | 18 +- pkg/storage/engine/enginepb/mvcc3.pb.go | 190 ++-- pkg/storage/engine/enginepb/mvcc3.proto | 13 +- pkg/storage/gc_queue_test.go | 12 +- pkg/storage/intent_resolver_test.go | 9 +- pkg/storage/replica.go | 72 +- pkg/storage/replica_test.go | 855 ++++++++---------- pkg/storage/store_test.go | 155 +--- pkg/storage/txn_wait_queue_test.go | 27 +- 57 files changed, 1028 insertions(+), 1961 deletions(-) diff --git a/c-deps/libroach/protos/roachpb/data.pb.cc b/c-deps/libroach/protos/roachpb/data.pb.cc index 63a5359cbb7f..234641c31326 100644 --- a/c-deps/libroach/protos/roachpb/data.pb.cc +++ b/c-deps/libroach/protos/roachpb/data.pb.cc @@ -3057,7 +3057,6 @@ const int Transaction::kRefreshedTimestampFieldNumber; const int Transaction::kObservedTimestampsFieldNumber; const int Transaction::kWritingFieldNumber; const int Transaction::kWriteTooOldFieldNumber; -const int Transaction::kRetryOnPushFieldNumber; const int Transaction::kIntentsFieldNumber; const int Transaction::kEpochZeroTimestampFieldNumber; const int Transaction::kOrigTimestampWasObservedFieldNumber; @@ -3327,20 +3326,6 @@ bool Transaction::MergePartialFromCodedStream( break; } - // bool retry_on_push = 13; - case 13: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(104u /* 104 & 0xFF */)) { - - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &retry_on_push_))); - } else { - goto handle_unusual; - } - break; - } - case 14: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(114u /* 114 & 0xFF */)) { @@ -3465,11 +3450,6 @@ void Transaction::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteBool(12, this->write_too_old(), output); } - // bool retry_on_push = 13; - if (this->retry_on_push() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteBool(13, this->retry_on_push(), output); - } - if (this->has_epoch_zero_timestamp()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 14, this->_internal_epoch_zero_timestamp(), output); @@ -3575,11 +3555,6 @@ size_t Transaction::ByteSizeLong() const { total_size += 1 + 1; } - // bool retry_on_push = 13; - if (this->retry_on_push() != 0) { - total_size += 1 + 1; - } - // bool orig_timestamp_was_observed = 16; if (this->orig_timestamp_was_observed() != 0) { total_size += 2 + 1; @@ -3635,9 +3610,6 @@ void Transaction::MergeFrom(const Transaction& from) { if (from.write_too_old() != 0) { set_write_too_old(from.write_too_old()); } - if (from.retry_on_push() != 0) { - set_retry_on_push(from.retry_on_push()); - } if (from.orig_timestamp_was_observed() != 0) { set_orig_timestamp_was_observed(from.orig_timestamp_was_observed()); } @@ -3673,7 +3645,6 @@ void Transaction::InternalSwap(Transaction* other) { swap(status_, other->status_); swap(writing_, other->writing_); swap(write_too_old_, other->write_too_old_); - swap(retry_on_push_, other->retry_on_push_); swap(orig_timestamp_was_observed_, other->orig_timestamp_was_observed_); _internal_metadata_.Swap(&other->_internal_metadata_); } diff --git a/c-deps/libroach/protos/roachpb/data.pb.h b/c-deps/libroach/protos/roachpb/data.pb.h index f04d218de594..41ab6e5a812d 100644 --- a/c-deps/libroach/protos/roachpb/data.pb.h +++ b/c-deps/libroach/protos/roachpb/data.pb.h @@ -1620,12 +1620,6 @@ class Transaction : public ::google::protobuf::MessageLite /* @@protoc_insertion bool write_too_old() const; void set_write_too_old(bool value); - // bool retry_on_push = 13; - void clear_retry_on_push(); - static const int kRetryOnPushFieldNumber = 13; - bool retry_on_push() const; - void set_retry_on_push(bool value); - // bool orig_timestamp_was_observed = 16; void clear_orig_timestamp_was_observed(); static const int kOrigTimestampWasObservedFieldNumber = 16; @@ -1648,7 +1642,6 @@ class Transaction : public ::google::protobuf::MessageLite /* @@protoc_insertion int status_; bool writing_; bool write_too_old_; - bool retry_on_push_; bool orig_timestamp_was_observed_; mutable ::google::protobuf::internal::CachedSize _cached_size_; friend struct ::protobuf_roachpb_2fdata_2eproto::TableStruct; @@ -3885,20 +3878,6 @@ inline void Transaction::set_write_too_old(bool value) { // @@protoc_insertion_point(field_set:cockroach.roachpb.Transaction.write_too_old) } -// bool retry_on_push = 13; -inline void Transaction::clear_retry_on_push() { - retry_on_push_ = false; -} -inline bool Transaction::retry_on_push() const { - // @@protoc_insertion_point(field_get:cockroach.roachpb.Transaction.retry_on_push) - return retry_on_push_; -} -inline void Transaction::set_retry_on_push(bool value) { - - retry_on_push_ = value; - // @@protoc_insertion_point(field_set:cockroach.roachpb.Transaction.retry_on_push) -} - inline int Transaction::intents_size() const { return intents_.size(); } diff --git a/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.cc b/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.cc index d85c53f63e5d..633dfcdf6102 100644 --- a/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.cc +++ b/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.cc @@ -255,16 +255,6 @@ namespace cockroach { namespace storage { namespace engine { namespace enginepb { -bool IsolationType_IsValid(int value) { - switch (value) { - case 0: - case 1: - return true; - default: - return false; - } -} - // =================================================================== @@ -280,7 +270,6 @@ void TxnMeta::clear_timestamp() { } #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int TxnMeta::kIdFieldNumber; -const int TxnMeta::kIsolationFieldNumber; const int TxnMeta::kKeyFieldNumber; const int TxnMeta::kEpochFieldNumber; const int TxnMeta::kTimestampFieldNumber; @@ -313,9 +302,9 @@ TxnMeta::TxnMeta(const TxnMeta& from) } else { timestamp_ = NULL; } - ::memcpy(&isolation_, &from.isolation_, + ::memcpy(&epoch_, &from.epoch_, static_cast(reinterpret_cast(&deprecated_batch_index_) - - reinterpret_cast(&isolation_)) + sizeof(deprecated_batch_index_)); + reinterpret_cast(&epoch_)) + sizeof(deprecated_batch_index_)); // @@protoc_insertion_point(copy_constructor:cockroach.storage.engine.enginepb.TxnMeta) } @@ -359,9 +348,9 @@ void TxnMeta::Clear() { delete timestamp_; } timestamp_ = NULL; - ::memset(&isolation_, 0, static_cast( + ::memset(&epoch_, 0, static_cast( reinterpret_cast(&deprecated_batch_index_) - - reinterpret_cast(&isolation_)) + sizeof(deprecated_batch_index_)); + reinterpret_cast(&epoch_)) + sizeof(deprecated_batch_index_)); _internal_metadata_.Clear(); } @@ -392,21 +381,6 @@ bool TxnMeta::MergePartialFromCodedStream( break; } - // .cockroach.storage.engine.enginepb.IsolationType isolation = 2; - case 2: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { - int value; - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - set_isolation(static_cast< ::cockroach::storage::engine::enginepb::IsolationType >(value)); - } else { - goto handle_unusual; - } - break; - } - // bytes key = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == @@ -517,12 +491,6 @@ void TxnMeta::SerializeWithCachedSizes( 1, this->id(), output); } - // .cockroach.storage.engine.enginepb.IsolationType isolation = 2; - if (this->isolation() != 0) { - ::google::protobuf::internal::WireFormatLite::WriteEnum( - 2, this->isolation(), output); - } - // bytes key = 3; if (this->key().size() > 0) { ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( @@ -584,12 +552,6 @@ size_t TxnMeta::ByteSizeLong() const { *timestamp_); } - // .cockroach.storage.engine.enginepb.IsolationType isolation = 2; - if (this->isolation() != 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->isolation()); - } - // uint32 epoch = 4; if (this->epoch() != 0) { total_size += 1 + @@ -646,9 +608,6 @@ void TxnMeta::MergeFrom(const TxnMeta& from) { if (from.has_timestamp()) { mutable_timestamp()->::cockroach::util::hlc::Timestamp::MergeFrom(from.timestamp()); } - if (from.isolation() != 0) { - set_isolation(from.isolation()); - } if (from.epoch() != 0) { set_epoch(from.epoch()); } @@ -685,7 +644,6 @@ void TxnMeta::InternalSwap(TxnMeta* other) { key_.Swap(&other->key_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); swap(timestamp_, other->timestamp_); - swap(isolation_, other->isolation_); swap(epoch_, other->epoch_); swap(priority_, other->priority_); swap(sequence_, other->sequence_); diff --git a/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.h b/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.h index 0e9a42feef49..7c383cd9e8cb 100644 --- a/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.h +++ b/c-deps/libroach/protos/storage/engine/enginepb/mvcc3.pb.h @@ -29,7 +29,6 @@ #include #include // IWYU pragma: export #include // IWYU pragma: export -#include #include "util/hlc/timestamp.pb.h" // @@protoc_insertion_point(includes) #define PROTOBUF_INTERNAL_EXPORT_protobuf_storage_2fengine_2fenginepb_2fmvcc3_2eproto @@ -102,17 +101,6 @@ namespace storage { namespace engine { namespace enginepb { -enum IsolationType { - SERIALIZABLE = 0, - SNAPSHOT = 1, - IsolationType_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, - IsolationType_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max -}; -bool IsolationType_IsValid(int value); -const IsolationType IsolationType_MIN = SERIALIZABLE; -const IsolationType IsolationType_MAX = SNAPSHOT; -const int IsolationType_ARRAYSIZE = IsolationType_MAX + 1; - // =================================================================== class TxnMeta : public ::google::protobuf::MessageLite /* @@protoc_insertion_point(class_definition:cockroach.storage.engine.enginepb.TxnMeta) */ { @@ -238,12 +226,6 @@ class TxnMeta : public ::google::protobuf::MessageLite /* @@protoc_insertion_poi ::cockroach::util::hlc::Timestamp* mutable_timestamp(); void set_allocated_timestamp(::cockroach::util::hlc::Timestamp* timestamp); - // .cockroach.storage.engine.enginepb.IsolationType isolation = 2; - void clear_isolation(); - static const int kIsolationFieldNumber = 2; - ::cockroach::storage::engine::enginepb::IsolationType isolation() const; - void set_isolation(::cockroach::storage::engine::enginepb::IsolationType value); - // uint32 epoch = 4; void clear_epoch(); static const int kEpochFieldNumber = 4; @@ -275,7 +257,6 @@ class TxnMeta : public ::google::protobuf::MessageLite /* @@protoc_insertion_poi ::google::protobuf::internal::ArenaStringPtr id_; ::google::protobuf::internal::ArenaStringPtr key_; ::cockroach::util::hlc::Timestamp* timestamp_; - int isolation_; ::google::protobuf::uint32 epoch_; ::google::protobuf::int32 priority_; ::google::protobuf::int32 sequence_; @@ -1656,20 +1637,6 @@ inline void TxnMeta::set_allocated_id(::std::string* id) { // @@protoc_insertion_point(field_set_allocated:cockroach.storage.engine.enginepb.TxnMeta.id) } -// .cockroach.storage.engine.enginepb.IsolationType isolation = 2; -inline void TxnMeta::clear_isolation() { - isolation_ = 0; -} -inline ::cockroach::storage::engine::enginepb::IsolationType TxnMeta::isolation() const { - // @@protoc_insertion_point(field_get:cockroach.storage.engine.enginepb.TxnMeta.isolation) - return static_cast< ::cockroach::storage::engine::enginepb::IsolationType >(isolation_); -} -inline void TxnMeta::set_isolation(::cockroach::storage::engine::enginepb::IsolationType value) { - - isolation_ = value; - // @@protoc_insertion_point(field_set:cockroach.storage.engine.enginepb.TxnMeta.isolation) -} - // bytes key = 3; inline void TxnMeta::clear_key() { key_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -3293,14 +3260,6 @@ inline void MVCCLogicalOp::set_allocated_abort_intent(::cockroach::storage::engi } // namespace storage } // namespace cockroach -namespace google { -namespace protobuf { - -template <> struct is_proto_enum< ::cockroach::storage::engine::enginepb::IsolationType> : ::std::true_type {}; - -} // namespace protobuf -} // namespace google - // @@protoc_insertion_point(global_scope) #endif // PROTOBUF_INCLUDED_storage_2fengine_2fenginepb_2fmvcc3_2eproto diff --git a/pkg/internal/client/client_test.go b/pkg/internal/client/client_test.go index c568fb3f9465..bf127303d0e8 100644 --- a/pkg/internal/client/client_test.go +++ b/pkg/internal/client/client_test.go @@ -32,7 +32,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/server" "github.com/cockroachdb/cockroach/pkg/storage" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/storage/storagebase" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" @@ -127,20 +126,15 @@ func TestClientRetryNonTxn(t *testing.T) { testCases := []struct { args roachpb.Request - isolation enginepb.IsolationType canPush bool expAttempts int }{ // Write/write conflicts. - {&roachpb.PutRequest{}, enginepb.SNAPSHOT, true, 2}, - {&roachpb.PutRequest{}, enginepb.SERIALIZABLE, true, 2}, - {&roachpb.PutRequest{}, enginepb.SNAPSHOT, false, 1}, - {&roachpb.PutRequest{}, enginepb.SERIALIZABLE, false, 1}, + {&roachpb.PutRequest{}, true, 2}, + {&roachpb.PutRequest{}, false, 1}, // Read/write conflicts. - {&roachpb.GetRequest{}, enginepb.SNAPSHOT, true, 1}, - {&roachpb.GetRequest{}, enginepb.SERIALIZABLE, true, 1}, - {&roachpb.GetRequest{}, enginepb.SNAPSHOT, false, 1}, - {&roachpb.GetRequest{}, enginepb.SERIALIZABLE, false, 1}, + {&roachpb.GetRequest{}, true, 1}, + {&roachpb.GetRequest{}, false, 1}, } // Lay down a write intent using a txn and attempt to access the same // key from our test client, with priorities set up so that the Push @@ -158,12 +152,6 @@ func TestClientRetryNonTxn(t *testing.T) { t.Fatal(err) } } - if test.isolation == enginepb.SNAPSHOT { - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - } - count++ // Lay down the intent. if err := txn.Put(ctx, key, "txn-value"); err != nil { @@ -256,18 +244,15 @@ func TestClientRunTransaction(t *testing.T) { value := []byte("value") key := []byte(fmt.Sprintf("%s/key-%t", testUser, commit)) - // Use snapshot isolation so non-transactional read can always push. err := db.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - // Put transactional value. if err := txn.Put(ctx, key, value); err != nil { return err } - // Attempt to read outside of txn. - if gr, err := db.Get(ctx, key); err != nil { + // Attempt to read in another txn. + conflictTxn := client.NewTxn(ctx, db, 0 /* gatewayNodeID */, client.RootTxn) + conflictTxn.InternalSetPriority(roachpb.MaxTxnPriority) + if gr, err := conflictTxn.Get(ctx, key); err != nil { return err } else if gr.Value != nil { return errors.Errorf("expected nil value; got %+v", gr.Value) @@ -320,12 +305,7 @@ func TestClientRunConcurrentTransaction(t *testing.T) { keys[j] = []byte(fmt.Sprintf("%s/key-%t/%s", testUser, commit, string(s))) } - // Use snapshot isolation so non-transactional read can always push. err := db.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - // We can't use errgroup here because we need to return any TxnAborted // errors if we see them. var wg sync.WaitGroup @@ -339,9 +319,11 @@ func TestClientRunConcurrentTransaction(t *testing.T) { concErrs[i] = err return } - // Attempt to read outside of txn. We need to guarantee that the + // Attempt to read in another txn. We need to guarantee that the // BeginTxnRequest has finished or we risk aborting the transaction. - if gr, err := db.Get(ctx, key); err != nil { + conflictTxn := client.NewTxn(ctx, db, 0 /* gatewayNodeID */, client.RootTxn) + conflictTxn.InternalSetPriority(roachpb.MaxTxnPriority) + if gr, err := conflictTxn.Get(ctx, key); err != nil { concErrs[i] = err return } else if gr.Value != nil { diff --git a/pkg/internal/client/sender.go b/pkg/internal/client/sender.go index 83bdecc2856a..1c9ba4cb2d7c 100644 --- a/pkg/internal/client/sender.go +++ b/pkg/internal/client/sender.go @@ -18,7 +18,6 @@ import ( "context" "github.com/cockroachdb/cockroach/pkg/roachpb" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/hlc" ) @@ -136,9 +135,6 @@ type TxnSender interface { // SetDebugName sets the txn's debug name. SetDebugName(name string) - // SetIsolation sets the transaction's isolation level. - SetIsolation(isolation enginepb.IsolationType) error - // TxnStatus exports the txn's status. TxnStatus() roachpb.TransactionStatus @@ -314,12 +310,6 @@ func (m *MockTransactionalSender) SetDebugName(name string) { m.txn.Name = name } -// SetIsolation is part of the TxnSender interface. -func (m *MockTransactionalSender) SetIsolation(isolation enginepb.IsolationType) error { - m.txn.Isolation = isolation - return nil -} - // OrigTimestamp is part of the TxnSender interface. func (m *MockTransactionalSender) OrigTimestamp() hlc.Timestamp { return m.txn.OrigTimestamp diff --git a/pkg/internal/client/txn.go b/pkg/internal/client/txn.go index 3a0caef92086..f42a229f4c7e 100644 --- a/pkg/internal/client/txn.go +++ b/pkg/internal/client/txn.go @@ -19,7 +19,6 @@ import ( "fmt" "github.com/cockroachdb/cockroach/pkg/roachpb" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/protoutil" @@ -57,7 +56,6 @@ type Txn struct { syncutil.Mutex ID uuid.UUID debugName string - isolation enginepb.IsolationType // userPriority is the transaction's priority. If not set, // NormalUserPriority will be used. @@ -103,7 +101,6 @@ func NewTxn(ctx context.Context, db *DB, gatewayNodeID roachpb.NodeID, typ TxnTy "unnamed", nil, // baseKey roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, now, db.clock.MaxOffset().Nanoseconds(), ) @@ -241,27 +238,6 @@ func (txn *Txn) debugNameLocked() string { return fmt.Sprintf("%s (id: %s)", txn.mu.debugName, txn.mu.ID) } -// SetIsolation sets the transaction's isolation type. Transactions default to -// serializable isolation. The isolation must be set before any operations are -// performed on the transaction. -func (txn *Txn) SetIsolation(isolation enginepb.IsolationType) error { - txn.mu.Lock() - defer txn.mu.Unlock() - - if err := txn.mu.sender.SetIsolation(isolation); err != nil { - return err - } - txn.mu.isolation = isolation - return nil -} - -// Isolation returns the transaction's isolation type. -func (txn *Txn) Isolation() enginepb.IsolationType { - txn.mu.Lock() - defer txn.mu.Unlock() - return txn.mu.isolation -} - // OrigTimestamp returns the transaction's starting timestamp. // Note a transaction can be internally pushed forward in time before // committing so this is not guaranteed to be the commit timestamp. @@ -972,7 +948,6 @@ func (txn *Txn) GenerateForcedRetryableError(ctx context.Context, msg string) er txn.debugNameLocked(), nil, // baseKey txn.mu.userPriority, - txn.mu.isolation, now, txn.db.clock.MaxOffset().Nanoseconds(), )) diff --git a/pkg/kv/dist_sender_server_test.go b/pkg/kv/dist_sender_server_test.go index c295d375a9fa..6cdaa19b8c97 100644 --- a/pkg/kv/dist_sender_server_test.go +++ b/pkg/kv/dist_sender_server_test.go @@ -34,7 +34,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/server" "github.com/cockroachdb/cockroach/pkg/storage" "github.com/cockroachdb/cockroach/pkg/storage/engine" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/storage/storagebase" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" @@ -74,7 +73,7 @@ func TestRangeLookupWithOpenTransaction(t *testing.T) { // engine. key := testutils.MakeKey(keys.Meta1Prefix, roachpb.KeyMax) now := s.Clock().Now() - txn := roachpb.MakeTransaction("txn", roachpb.Key("foobar"), 0, enginepb.SERIALIZABLE, now, 0) + txn := roachpb.MakeTransaction("txn", roachpb.Key("foobar"), 0, now, 0) if err := engine.MVCCPutProto( context.Background(), s.(*server.TestServer).Engines()[0], nil, key, now, &txn, &roachpb.RangeDescriptor{}); err != nil { diff --git a/pkg/kv/dist_sender_test.go b/pkg/kv/dist_sender_test.go index df578fd436ed..5766219aa542 100644 --- a/pkg/kv/dist_sender_test.go +++ b/pkg/kv/dist_sender_test.go @@ -34,7 +34,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/rpc" "github.com/cockroachdb/cockroach/pkg/rpc/nodedialer" "github.com/cockroachdb/cockroach/pkg/settings/cluster" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/cockroach/pkg/util/hlc" @@ -500,7 +499,7 @@ func TestImmutableBatchArgs(t *testing.T) { txn := roachpb.MakeTransaction( "test", nil /* baseKey */, roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, clock.Now(), clock.MaxOffset().Nanoseconds(), + clock.Now(), clock.MaxOffset().Nanoseconds(), ) origTxnTs := txn.Timestamp @@ -1469,7 +1468,7 @@ func TestMultiRangeGapReverse(t *testing.T) { ds := NewDistSender(cfg, g) - txn := roachpb.MakeTransaction("foo", nil, 1.0, enginepb.SERIALIZABLE, clock.Now(), 0) + txn := roachpb.MakeTransaction("foo", nil, 1.0, clock.Now(), 0) var ba roachpb.BatchRequest ba.Txn = &txn diff --git a/pkg/kv/txn_coord_sender.go b/pkg/kv/txn_coord_sender.go index 501db76cbb0d..f26bba1771b9 100644 --- a/pkg/kv/txn_coord_sender.go +++ b/pkg/kv/txn_coord_sender.go @@ -24,7 +24,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/keys" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/settings/cluster" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/duration" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/log" @@ -246,7 +245,6 @@ type TxnMetrics struct { // Counts of restart types. RestartsWriteTooOld *metric.Counter - RestartsDeleteRange *metric.Counter RestartsSerializable *metric.Counter RestartsPossibleReplay *metric.Counter RestartsAsyncWriteFailure *metric.Counter @@ -298,12 +296,6 @@ var ( Measurement: "Restarted Transactions", Unit: metric.Unit_COUNT, } - metaRestartsDeleteRange = metric.Metadata{ - Name: "txn.restarts.deleterange", - Help: "Number of restarts due to a forwarded commit timestamp and a DeleteRange command", - Measurement: "Restarted Transactions", - Unit: metric.Unit_COUNT, - } metaRestartsSerializable = metric.Metadata{ Name: "txn.restarts.serializable", Help: "Number of restarts due to a forwarded commit timestamp and isolation=SERIALIZABLE", @@ -335,7 +327,6 @@ func MakeTxnMetrics(histogramWindow time.Duration) TxnMetrics { Durations: metric.NewLatency(metaDurationsHistograms, histogramWindow), Restarts: metric.NewHistogram(metaRestartsHistogram, histogramWindow, 100, 3), RestartsWriteTooOld: metric.NewCounter(metaRestartsWriteTooOld), - RestartsDeleteRange: metric.NewCounter(metaRestartsDeleteRange), RestartsSerializable: metric.NewCounter(metaRestartsSerializable), RestartsPossibleReplay: metric.NewCounter(metaRestartsPossibleReplay), RestartsAsyncWriteFailure: metric.NewCounter(metaRestartsAsyncWriteFailure), @@ -824,8 +815,6 @@ func (tc *TxnCoordSender) handleRetryableErrLocked( switch tErr.Reason { case roachpb.RETRY_WRITE_TOO_OLD: tc.metrics.RestartsWriteTooOld.Inc(1) - case roachpb.RETRY_DELETE_RANGE: - tc.metrics.RestartsDeleteRange.Inc(1) case roachpb.RETRY_SERIALIZABLE: tc.metrics.RestartsSerializable.Inc(1) case roachpb.RETRY_POSSIBLE_REPLAY: @@ -985,21 +974,6 @@ func (tc *TxnCoordSender) SetDebugName(name string) { tc.mu.txn.Name = name } -// SetIsolation is part of the client.TxnSender interface. -func (tc *TxnCoordSender) SetIsolation(isolation enginepb.IsolationType) error { - tc.mu.Lock() - defer tc.mu.Unlock() - - if tc.mu.txn.Isolation == isolation { - return nil - } - if tc.mu.active { - return errors.Errorf("cannot change the isolation level of a running transaction") - } - tc.mu.txn.Isolation = isolation - return nil -} - // OrigTimestamp is part of the client.TxnSender interface. func (tc *TxnCoordSender) OrigTimestamp() hlc.Timestamp { tc.mu.Lock() @@ -1069,8 +1043,7 @@ func (tc *TxnCoordSender) IsSerializablePushAndRefreshNotPossible() bool { tc.mu.txn.OrigTimestampWasObserved // We check OrigTimestampWasObserved here because, if that's set, refreshing // of reads is not performed. - return tc.mu.txn.Isolation == enginepb.SERIALIZABLE && - isTxnPushed && refreshAttemptNotPossible + return isTxnPushed && refreshAttemptNotPossible } // Epoch is part of the client.TxnSender interface. diff --git a/pkg/kv/txn_coord_sender_test.go b/pkg/kv/txn_coord_sender_test.go index 4ebe2491ac1e..f4c868a79a64 100644 --- a/pkg/kv/txn_coord_sender_test.go +++ b/pkg/kv/txn_coord_sender_test.go @@ -106,9 +106,6 @@ func TestTxnCoordSenderBeginTransaction(t *testing.T) { key := roachpb.Key("key") txn.InternalSetPriority(10) txn.SetDebugName("test txn") - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - t.Fatal(err) - } if err := txn.Put(ctx, key, []byte("value")); err != nil { t.Fatal(err) } @@ -122,9 +119,6 @@ func TestTxnCoordSenderBeginTransaction(t *testing.T) { if !bytes.Equal(proto.Key, key) { t.Errorf("expected txn Key to match %q != %q", key, proto.Key) } - if proto.Isolation != enginepb.SNAPSHOT { - t.Errorf("expected txn isolation to be SNAPSHOT; got %s", proto.Isolation) - } } // TestTxnCoordSenderKeyRanges verifies that multiple requests to same or @@ -453,16 +447,13 @@ func TestTxnCoordSenderEndTxn(t *testing.T) { for i := 0; i < 4; i++ { key := roachpb.Key("key: " + strconv.Itoa(i)) txn := client.NewTxn(ctx, s.DB, 0 /* gatewayNodeID */, client.RootTxn) - // Set to SNAPSHOT so that it can be pushed without restarting. - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - t.Fatal(err) - } // Initialize the transaction. if pErr := txn.Put(ctx, key, []byte("value")); pErr != nil { t.Fatal(pErr) } // Conflicting transaction that pushes the above transaction. conflictTxn := client.NewTxn(ctx, s.DB, 0 /* gatewayNodeID */, client.RootTxn) + conflictTxn.InternalSetPriority(roachpb.MaxTxnPriority) if _, pErr := conflictTxn.Get(ctx, key); pErr != nil { t.Fatal(pErr) } @@ -806,7 +797,6 @@ func TestTxnCoordSenderTxnUpdatedOnError(t *testing.T) { "test txn", key, roachpb.UserPriority(0), - enginepb.SERIALIZABLE, clock.Now(), clock.MaxOffset().Nanoseconds(), ) @@ -949,7 +939,7 @@ func TestTxnCoordSenderErrorWithIntent(t *testing.T) { key := roachpb.Key("test") ba.Add(&roachpb.PutRequest{RequestHeader: roachpb.RequestHeader{Key: key}}) ba.Add(&roachpb.EndTransactionRequest{}) - txn := roachpb.MakeTransaction("test", key, 0, 0, clock.Now(), 0) + txn := roachpb.MakeTransaction("test", key, 0, clock.Now(), 0) meta := roachpb.MakeTxnCoordMeta(txn) tc := factory.TransactionalSender(client.RootTxn, meta) ba.Txn = &txn @@ -1171,10 +1161,6 @@ func TestTxnAbortCount(t *testing.T) { if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { key := []byte("key-abort") - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - if err := txn.Put(ctx, key, value); err != nil { t.Fatal(err) } @@ -1254,9 +1240,6 @@ func TestTxnDurations(t *testing.T) { for i := 0; i < puts; i++ { key := roachpb.Key(fmt.Sprintf("key-txn-durations-%d", i)) if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } if err := txn.Put(ctx, key, []byte("val")); err != nil { return err } @@ -1603,7 +1586,6 @@ func TestIntentTrackingBeforeBeginTransaction(t *testing.T) { "test txn", key, roachpb.UserPriority(0), - enginepb.SERIALIZABLE, clock.Now(), clock.MaxOffset().Nanoseconds(), ) diff --git a/pkg/kv/txn_correctness_test.go b/pkg/kv/txn_correctness_test.go index 67f39efe2cd5..a135448da669 100644 --- a/pkg/kv/txn_correctness_test.go +++ b/pkg/kv/txn_correctness_test.go @@ -29,7 +29,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/internal/client" "github.com/cockroachdb/cockroach/pkg/roachpb" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/localtestcluster" "github.com/cockroachdb/cockroach/pkg/util/leaktest" @@ -316,62 +315,6 @@ func parseHistories(histories []string, t *testing.T) [][]*cmd { return results } -// Easily accessible slices of transaction isolation variations. -var ( - bothIsolations = []enginepb.IsolationType{enginepb.SERIALIZABLE, enginepb.SNAPSHOT} - onlySerializable = []enginepb.IsolationType{enginepb.SERIALIZABLE} - onlySnapshot = []enginepb.IsolationType{enginepb.SNAPSHOT} -) - -// enumerateIsolations returns a slice enumerating all combinations of -// isolation types across the transactions. The inner slice describes -// the isolation type for each transaction. The outer slice contains -// each possible combination of such transaction isolations. -func enumerateIsolations( - numTxns int, isolations []enginepb.IsolationType, -) [][]enginepb.IsolationType { - // Use a count from 0 to pow(# isolations, numTxns)-1 and examine - // n-ary digits to get all possible combinations of txn isolations. - n := len(isolations) - result := [][]enginepb.IsolationType{} - for i := 0; i < int(math.Pow(float64(n), float64(numTxns))); i++ { - desc := make([]enginepb.IsolationType, numTxns) - val := i - for j := 0; j < numTxns; j++ { - desc[j] = isolations[val%n] - val /= n - } - result = append(result, desc) - } - return result -} - -func TestEnumerateIsolations(t *testing.T) { - defer leaktest.AfterTest(t)() - SSI := enginepb.SERIALIZABLE - SI := enginepb.SNAPSHOT - expIsolations := [][]enginepb.IsolationType{ - {SSI, SSI, SSI}, - {SI, SSI, SSI}, - {SSI, SI, SSI}, - {SI, SI, SSI}, - {SSI, SSI, SI}, - {SI, SSI, SI}, - {SSI, SI, SI}, - {SI, SI, SI}, - } - if enum := enumerateIsolations(3, bothIsolations); !reflect.DeepEqual(enum, expIsolations) { - t.Errorf("expected enumeration to match %s; got %s", expIsolations, enum) - } - - expDegenerate := [][]enginepb.IsolationType{ - {SSI, SSI, SSI}, - } - if enum := enumerateIsolations(3, onlySerializable); !reflect.DeepEqual(enum, expDegenerate) { - t.Errorf("expected enumeration to match %s; got %s", expDegenerate, enum) - } -} - // enumeratePriorities returns a slice enumerating all combinations of // priorities across the transactions. The inner slice describes the // priority for each transaction. The outer slice contains each possible @@ -639,20 +582,17 @@ func newHistoryVerifier( } } -func (hv *historyVerifier) run(isolations []enginepb.IsolationType, db *client.DB, t *testing.T) { +func (hv *historyVerifier) run(db *client.DB, t *testing.T) { log.Infof(context.Background(), "verifying all possible histories for the %q anomaly", hv.name) enumPri := enumeratePriorities(len(hv.txns), []int32{1, roachpb.MaxTxnPriority}) - enumIso := enumerateIsolations(len(hv.txns), isolations) enumHis := enumerateHistories(hv.txns, hv.equal) for _, p := range enumPri { - for _, i := range enumIso { - for _, h := range enumHis { - hv.retriedTxns = map[int]struct{}{} // always reset the retried txns set - if err := hv.runHistoryWithRetry(p, i, h, db, t); err != nil { - t.Errorf("expected success, experienced %s", err) - return - } + for _, h := range enumHis { + hv.retriedTxns = map[int]struct{}{} // always reset the retried txns set + if err := hv.runHistoryWithRetry(p, h, db, t); err != nil { + t.Errorf("expected success, experienced %s", err) + return } } } @@ -666,9 +606,9 @@ func (hv *historyVerifier) run(isolations []enginepb.IsolationType, db *client.D // // This process continues recursively if there are further retries. func (hv *historyVerifier) runHistoryWithRetry( - priorities []int32, isolations []enginepb.IsolationType, cmds []*cmd, db *client.DB, t *testing.T, + priorities []int32, cmds []*cmd, db *client.DB, t *testing.T, ) error { - if err := hv.runHistory(priorities, isolations, cmds, db, t); err != nil { + if err := hv.runHistory(priorities, cmds, db, t); err != nil { if log.V(1) { log.Infof(context.Background(), "got an error running history %s: %s", historyString(cmds), err) } @@ -691,7 +631,7 @@ func (hv *historyVerifier) runHistoryWithRetry( if log.V(1) { log.Infof(context.Background(), "after retry, running alternate history %d of %d", i, len(enumHis)) } - if err := hv.runHistoryWithRetry(priorities, isolations, h, db, t); err != nil { + if err := hv.runHistoryWithRetry(priorities, h, db, t); err != nil { return err } } @@ -700,7 +640,7 @@ func (hv *historyVerifier) runHistoryWithRetry( } func (hv *historyVerifier) runHistory( - priorities []int32, isolations []enginepb.IsolationType, cmds []*cmd, db *client.DB, t *testing.T, + priorities []int32, cmds []*cmd, db *client.DB, t *testing.T, ) error { hv.idx++ if t.Failed() { @@ -716,7 +656,7 @@ func (hv *historyVerifier) runHistory( plannedStr := historyString(cmds) if log.V(1) { - log.Infof(context.Background(), "iso=%d pri=%d history=%s", isolations, priorities, plannedStr) + log.Infof(context.Background(), "pri=%d history=%s", priorities, plannedStr) } hv.mu.actual = []string{} @@ -736,7 +676,7 @@ func (hv *historyVerifier) runHistory( for i, txnCmds := range txnMap { go func(i int, txnCmds []*cmd) { - if err := hv.runTxn(i, priorities[i], isolations[i], txnCmds, db, t); err != nil { + if err := hv.runTxn(i, priorities[i], txnCmds, db, t); err != nil { if re, ok := err.(*retryError); !ok { reportErr := errors.Wrapf(err, "(%s): unexpected failure", cmds) select { @@ -778,12 +718,12 @@ func (hv *historyVerifier) runHistory( err = hv.verify.checkFn(verifyEnv) if err == nil { if log.V(1) { - log.Infof(context.Background(), "PASSED: iso=%d, pri=%d, history=%q", isolations, priorities, actualStr) + log.Infof(context.Background(), "PASSED: pri=%d, history=%q", priorities, actualStr) } } if err != nil { - t.Errorf("%d: iso=%d, pri=%d, history=%q: actual=%q, verify=%q: %s", - hv.idx, isolations, priorities, plannedStr, actualStr, verifyStr, err) + t.Errorf("%d: pri=%d, history=%q: actual=%q, verify=%q: %s", + hv.idx, priorities, plannedStr, actualStr, verifyStr, err) } return err } @@ -810,12 +750,7 @@ func (hv *historyVerifier) runCmds( } func (hv *historyVerifier) runTxn( - txnIdx int, - priority int32, - isolation enginepb.IsolationType, - cmds []*cmd, - db *client.DB, - t *testing.T, + txnIdx int, priority int32, cmds []*cmd, db *client.DB, t *testing.T, ) error { var retry int txnName := fmt.Sprintf("txn %d", txnIdx+1) @@ -843,11 +778,6 @@ func (hv *historyVerifier) runTxn( } txn.SetDebugName(txnName) - if isolation == enginepb.SNAPSHOT { - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - } txn.InternalSetPriority(priority) env := map[string]int64{} @@ -885,16 +815,14 @@ func (hv *historyVerifier) runCmd( // checkConcurrency creates a history verifier, starts a new database // and runs the verifier. -func checkConcurrency( - name string, isolations []enginepb.IsolationType, txns []string, verify *verifier, t *testing.T, -) { +func checkConcurrency(name string, txns []string, verify *verifier, t *testing.T) { verifier := newHistoryVerifier(name, txns, verify, t) s := &localtestcluster.LocalTestCluster{ DontRetryPushTxnFailures: true, } s.Start(t, testutils.NewNodeTestBaseContext(), InitFactoryForLocalTestCluster) defer s.Stop() - verifier.run(isolations, s.DB, t) + verifier.run(s.DB, t) } // The following tests for concurrency anomalies include documentation @@ -920,8 +848,8 @@ func checkConcurrency( // In.m(x) - increment from txn "n" ("m"th retry) of key "x" // Cn.m - commit of txn "n" ("m"th retry) -// TestTxnDBReadSkewAnomaly verifies that neither SI nor SSI isolation -// are subject to the read skew anomaly, an example of a database +// TestTxnDBReadSkewAnomaly verifies that transactions are not +// subject to the read skew anomaly, an example of a database // constraint violation known as inconsistent analysis (see // http://research.microsoft.com/pubs/69541/tr-95-51.pdf). This anomaly // is prevented by REPEATABLE_READ. @@ -950,11 +878,11 @@ func TestTxnDBReadSkewAnomaly(t *testing.T) { return nil }, } - checkConcurrency("read skew", bothIsolations, []string{txn1, txn2}, verify, t) + checkConcurrency("read skew", []string{txn1, txn2}, verify, t) } -// TestTxnDBLostUpdateAnomaly verifies that neither SI nor SSI isolation -// are subject to the lost update anomaly. This anomaly is prevented +// TestTxnDBLostUpdateAnomaly verifies that transactions are not +// subject to the lost update anomaly. This anomaly is prevented // in most cases by using the READ_COMMITTED ANSI isolation level. // However, only REPEATABLE_READ fully protects against it. // @@ -981,11 +909,11 @@ func TestTxnDBLostUpdateAnomaly(t *testing.T) { return nil }, } - checkConcurrency("lost update", bothIsolations, []string{txn, txn}, verify, t) + checkConcurrency("lost update", []string{txn, txn}, verify, t) } -// TestTxnDBLostDeleteAnomaly verifies that neither SI nor SSI -// isolation are subject to the lost delete anomaly. See #6240. +// TestTxnDBLostDeleteAnomaly verifies that transactions are not +// subject to the lost delete anomaly. See #6240. // // With lost delete, the two deletions from txn2 are interleaved // with a read and write from txn1, allowing txn1 to read a pre- @@ -1013,11 +941,11 @@ func TestTxnDBLostDeleteAnomaly(t *testing.T) { return nil }, } - checkConcurrency("lost update (delete)", onlySnapshot, []string{txn1, txn2}, verify, t) + checkConcurrency("lost update (delete)", []string{txn1, txn2}, verify, t) } -// TestTxnDBLostDeleteRangeAnomaly verifies that neither SI nor SSI -// isolation are subject to the lost delete range anomaly. See #6240. +// TestTxnDBLostDeleteRangeAnomaly verifies that transactions are not +// subject to the lost delete range anomaly. See #6240. // // With lost delete range, the delete range for keys B-C leave no // deletion tombstones (as there are an infinite number of keys in the @@ -1027,8 +955,8 @@ func TestTxnDBLostDeleteAnomaly(t *testing.T) { // delete range request therefore committed but failed to delete the // value written to key B. // -// This anomaly is prevented by making snapshot transactions which -// involve a range deletion restart when they are pushed. +// Note that the snapshot isolation level is no longer supported. This +// test is retained for good measure. // // Lost delete range would typically fail with a history such as: // D2(A) DR2(B-C) R1(A) C2 W1(B,A) C1 @@ -1048,11 +976,11 @@ func TestTxnDBLostDeleteRangeAnomaly(t *testing.T) { return nil }, } - checkConcurrency("lost update (range delete)", onlySnapshot, []string{txn1, txn2}, verify, t) + checkConcurrency("lost update (range delete)", []string{txn1, txn2}, verify, t) } -// TestTxnDBPhantomReadAnomaly verifies that neither SI nor SSI isolation -// are subject to the phantom reads anomaly. This anomaly is prevented by +// TestTxnDBPhantomReadAnomaly verifies that transactions are not subject +// to the phantom reads anomaly. This anomaly is prevented by // the SQL ANSI SERIALIZABLE isolation level, though it's also prevented // by snapshot isolation (i.e. Oracle's traditional "serializable"). // @@ -1076,11 +1004,11 @@ func TestTxnDBPhantomReadAnomaly(t *testing.T) { return nil }, } - checkConcurrency("phantom read", bothIsolations, []string{txn1, txn2}, verify, t) + checkConcurrency("phantom read", []string{txn1, txn2}, verify, t) } -// TestTxnDBPhantomDeleteAnomaly verifies that neither SI nor SSI -// isolation are subject to the phantom deletion anomaly; this is +// TestTxnDBPhantomDeleteAnomaly verifies that transactions are not +// subject to the phantom deletion anomaly; this is // similar to phantom reads, but verifies the delete range // functionality causes read/write conflicts. // @@ -1099,41 +1027,18 @@ func TestTxnDBPhantomDeleteAnomaly(t *testing.T) { return nil }, } - checkConcurrency("phantom delete", bothIsolations, []string{txn1, txn2}, verify, t) + checkConcurrency("phantom delete", []string{txn1, txn2}, verify, t) } -func runWriteSkewTest(t *testing.T, iso enginepb.IsolationType) { - checks := make(map[enginepb.IsolationType]func(map[string]int64) error) - checks[enginepb.SERIALIZABLE] = func(env map[string]int64) error { - if !((env["A"] == 1 && env["B"] == 2) || (env["A"] == 2 && env["B"] == 1)) { - return errors.Errorf("expected either A=1, B=2 -or- A=2, B=1, but have A=%d, B=%d", env["A"], env["B"]) - } - return nil - } - checks[enginepb.SNAPSHOT] = func(env map[string]int64) error { - if env["A"] == 1 && env["B"] == 1 { - return nil - } - return checks[enginepb.SERIALIZABLE](env) - } - - txn1 := "SC(A-C) W(A,A+B+1) C" - txn2 := "SC(A-C) W(B,A+B+1) C" - verify := &verifier{ - history: "R(A) R(B)", - checkFn: checks[iso], - } - checkConcurrency("write skew", []enginepb.IsolationType{iso}, []string{txn1, txn2}, verify, t) -} - -// TestTxnDBWriteSkewAnomaly verifies that SI suffers from the write -// skew anomaly but not SSI. The write skew anomaly is a condition which -// illustrates that snapshot isolation is not serializable in practice. +// TestTxnDBWriteSkewAnomaly verifies that transactions are not +// subject to the write skew anomaly. Write skew is only possible +// at the weaker, snapshot isolation level, which is no longer +// supported. // // With write skew, two transactions both read values from A and B // respectively, but each writes to either A or B only. Thus there are // no write/write conflicts but a cycle of dependencies which result in -// "skew". Only serializable isolation prevents this anomaly. +// "skew". // // Write skew would typically fail with a history such as: // SC1(A-C) SC2(A-C) W1(A,A+B+1) C1 W2(B,A+B+1) C2 @@ -1147,6 +1052,16 @@ func runWriteSkewTest(t *testing.T, iso enginepb.IsolationType) { // history above) and may set A=1, B=1. func TestTxnDBWriteSkewAnomaly(t *testing.T) { defer leaktest.AfterTest(t)() - runWriteSkewTest(t, enginepb.SERIALIZABLE) - runWriteSkewTest(t, enginepb.SNAPSHOT) + txn1 := "SC(A-C) W(A,A+B+1) C" + txn2 := "SC(A-C) W(B,A+B+1) C" + verify := &verifier{ + history: "R(A) R(B)", + checkFn: func(env map[string]int64) error { + if !((env["A"] == 1 && env["B"] == 2) || (env["A"] == 2 && env["B"] == 1)) { + return errors.Errorf("expected either A=1, B=2 -or- A=2, B=1, but have A=%d, B=%d", env["A"], env["B"]) + } + return nil + }, + } + checkConcurrency("write skew", []string{txn1, txn2}, verify, t) } diff --git a/pkg/kv/txn_interceptor_pipeliner_test.go b/pkg/kv/txn_interceptor_pipeliner_test.go index 18a515a20f2b..55644c477879 100644 --- a/pkg/kv/txn_interceptor_pipeliner_test.go +++ b/pkg/kv/txn_interceptor_pipeliner_test.go @@ -55,7 +55,7 @@ func makeMockTxnPipeliner() (txnPipeliner, *mockLockedSender) { } func makeTxnProto() roachpb.Transaction { - return roachpb.MakeTransaction("test", []byte("key"), 0, 0, hlc.Timestamp{}, 0) + return roachpb.MakeTransaction("test", []byte("key"), 0, hlc.Timestamp{}, 0) } // TestTxnPipeliner1PCTransaction tests that 1PC transactions pass through the diff --git a/pkg/kv/txn_interceptor_span_refresher.go b/pkg/kv/txn_interceptor_span_refresher.go index 928b122bc6b2..c9a75d7cd2fd 100644 --- a/pkg/kv/txn_interceptor_span_refresher.go +++ b/pkg/kv/txn_interceptor_span_refresher.go @@ -83,10 +83,7 @@ func (sr *txnSpanRefresher) SendLocked( ) (*roachpb.BatchResponse, *roachpb.Error) { if rArgs, hasET := ba.GetArg(roachpb.EndTransaction); hasET { et := rArgs.(*roachpb.EndTransactionRequest) - if ba.Txn.IsSerializable() && - !sr.refreshInvalid && - len(sr.refreshReads) == 0 && - len(sr.refreshWrites) == 0 { + if !sr.refreshInvalid && len(sr.refreshReads) == 0 && len(sr.refreshWrites) == 0 { et.NoRefreshSpans = true } } @@ -113,29 +110,26 @@ func (sr *txnSpanRefresher) SendLocked( } // Iterate over and aggregate refresh spans in the requests, - // qualified by possible resume spans in the responses, if the txn - // has serializable isolation and we haven't yet exceeded the max - // read key bytes. - if ba.Txn.IsSerializable() { - if !sr.refreshInvalid { - ba.Txn.RefreshedTimestamp.Forward(largestRefreshTS) - if !sr.appendRefreshSpans(ctx, ba, br) { - // The refresh spans are out of date, return a generic client-side retry error. - return nil, roachpb.NewErrorWithTxn( - roachpb.NewTransactionRetryError(roachpb.RETRY_SERIALIZABLE), br.Txn, - ) - } - } - // Verify and enforce the size in bytes of all read-only spans - // doesn't exceed the max threshold. - if sr.refreshSpansBytes > MaxTxnRefreshSpansBytes.Get(&sr.st.SV) { - log.VEventf(ctx, 2, "refresh spans max size exceeded; clearing") - sr.refreshReads = nil - sr.refreshWrites = nil - sr.refreshInvalid = true - sr.refreshSpansBytes = 0 + // qualified by possible resume spans in the responses, if we + // haven't yet exceeded the max read key bytes. + if !sr.refreshInvalid { + ba.Txn.RefreshedTimestamp.Forward(largestRefreshTS) + if !sr.appendRefreshSpans(ctx, ba, br) { + // The refresh spans are out of date, return a generic client-side retry error. + return nil, roachpb.NewErrorWithTxn( + roachpb.NewTransactionRetryError(roachpb.RETRY_SERIALIZABLE), br.Txn, + ) } } + // Verify and enforce the size in bytes of all read-only spans + // doesn't exceed the max threshold. + if sr.refreshSpansBytes > MaxTxnRefreshSpansBytes.Get(&sr.st.SV) { + log.VEventf(ctx, 2, "refresh spans max size exceeded; clearing") + sr.refreshReads = nil + sr.refreshWrites = nil + sr.refreshInvalid = true + sr.refreshSpansBytes = 0 + } // If the transaction will retry and the refresh spans are // exhausted, return a non-retryable error indicating that the // transaction is too large and should potentially be split. diff --git a/pkg/kv/txn_test.go b/pkg/kv/txn_test.go index abeed7abcc13..b13840c410e5 100644 --- a/pkg/kv/txn_test.go +++ b/pkg/kv/txn_test.go @@ -25,7 +25,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/keys" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/storage/tscache" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/localtestcluster" @@ -48,18 +47,15 @@ func TestTxnDBBasics(t *testing.T) { key := []byte(fmt.Sprintf("key-%t", commit)) err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - // Use snapshot isolation so non-transactional read can always push. - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - // Put transactional value. if err := txn.Put(ctx, key, value); err != nil { return err } - // Attempt to read outside of txn. - if gr, err := s.DB.Get(ctx, key); err != nil { + // Attempt to read in another txn. + conflictTxn := client.NewTxn(ctx, s.DB, 0 /* gatewayNodeID */, client.RootTxn) + conflictTxn.InternalSetPriority(roachpb.MaxTxnPriority) + if gr, err := conflictTxn.Get(ctx, key); err != nil { return err } else if gr.Exists() { return errors.Errorf("expected nil value; got %v", gr.Value) @@ -124,93 +120,14 @@ func BenchmarkSingleRoundtripWithLatency(b *testing.B) { } } -// TestSnapshotIsolationIncrement verifies that Increment with snapshot -// isolation yields an increment based on the original timestamp of -// the transaction, not the forwarded timestamp. -func TestSnapshotIsolationIncrement(t *testing.T) { - defer leaktest.AfterTest(t)() - s := createTestDB(t) - defer s.Stop() - - var key = roachpb.Key("a") - var key2 = roachpb.Key("b") - - done := make(chan error) - start := make(chan struct{}) - - go func() { - <-start - done <- s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - if _, err := txn.Inc(ctx, key, 1); err != nil { - return err - } - if _, err := txn.Get(ctx, key2); err != nil { - return err - } - return nil - }) - }() - - if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - t.Fatal(err) - } - - // Issue a read to get initial value. - if _, err := txn.Get(ctx, key); err != nil { - t.Fatal(err) - } - - if txn.Epoch() == 0 { - close(start) // let someone write into our future - // When they're done writing, increment. - if err := <-done; err != nil { - t.Fatal(err) - } - } else if txn.Epoch() > 1 { - t.Fatal("should experience just one restart") - } - - // Start by writing key2, which will move our txn timestamp forward. - if err := txn.Put(ctx, key2, "foo"); err != nil { - t.Fatal(err) - } - // Now, increment with txn.Timestamp equal to key2's timestamp - // cache entry + 1. We want to be sure that we still see a value - // of 0 on our first increment (as txn.OrigTimestamp was set - // before anything else happened in the concurrent writer - // goroutine). The second iteration of the txn should read the - // correct value and commit. - proto := txn.Serialize() - if txn.Epoch() == 0 && !proto.OrigTimestamp.Less(proto.Timestamp) { - t.Fatalf("expected orig timestamp less than timestamp: %s", proto) - } - ir, err := txn.Inc(ctx, key, 1) - if err != nil { - t.Fatal(err) - } - proto = txn.Serialize() - if vi := ir.ValueInt(); vi != int64(proto.Epoch+1) { - t.Errorf("expected %d; got %d", proto.Epoch+1, vi) - } - // Verify that the WriteTooOld boolean is set on the txn. - if (txn.Epoch() == 0) != proto.WriteTooOld { - t.Fatalf("expected write too old=%t; got %t", (proto.Epoch == 0), proto.WriteTooOld) - } - return nil - }); err != nil { - t.Fatal(err) - } -} - -// TestSnapshotIsolationLostUpdate verifies that snapshot isolation -// transactions are not susceptible to the lost update anomaly. +// TestLostUpdate verifies that transactions are not susceptible to the +// lost update anomaly. // // The transaction history looks as follows ("2" refers to the // independent goroutine's actions) // // R1(A) W2(A,"hi") W1(A,"oops!") C1 [serializable restart] R1(A) W1(A,"correct") C1 -func TestSnapshotIsolationLostUpdate(t *testing.T) { +func TestLostUpdate(t *testing.T) { defer leaktest.AfterTest(t)() s := createTestDB(t) defer s.Stop() @@ -226,10 +143,6 @@ func TestSnapshotIsolationLostUpdate(t *testing.T) { }() if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - t.Fatal(err) - } - // Issue a read to get initial value. gr, err := txn.Get(ctx, key) if err != nil { @@ -307,54 +220,48 @@ func TestPriorityRatchetOnAbortOrPush(t *testing.T) { } } - // Try all combinations of read/write and snapshot/serializable isolation. + // Try both read and write. for _, read := range []bool{true, false} { - for _, iso := range []enginepb.IsolationType{enginepb.SNAPSHOT, enginepb.SERIALIZABLE} { - var iteration int - if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - defer func() { iteration++ }() - key := roachpb.Key(fmt.Sprintf("read=%t, iso=%s", read, iso)) - - if err := txn.SetIsolation(iso); err != nil { - t.Fatal(err) - } + var iteration int + if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { + defer func() { iteration++ }() + key := roachpb.Key(fmt.Sprintf("read=%t", read)) - // Write to lay down an intent (this will send the begin - // transaction which gets the updated priority). - if err := txn.Put(ctx, key, "bar"); err != nil { - return err - } + // Write to lay down an intent (this will send the begin + // transaction which gets the updated priority). + if err := txn.Put(ctx, key, "bar"); err != nil { + return err + } - if iteration == 1 { - // Verify our priority has ratcheted to one less than the pusher's priority - expPri := int32(roachpb.MaxTxnPriority - 1) - if pri := txn.Serialize().Priority; pri != expPri { - t.Fatalf("%s: expected priority on retry to ratchet to %d; got %d", key, expPri, pri) - } - return nil + if iteration == 1 { + // Verify our priority has ratcheted to one less than the pusher's priority + expPri := int32(roachpb.MaxTxnPriority - 1) + if pri := txn.Serialize().Priority; pri != expPri { + t.Fatalf("%s: expected priority on retry to ratchet to %d; got %d", key, expPri, pri) } + return nil + } - // Now simulate a concurrent reader or writer. Our txn will - // either be pushed or aborted. Then issue a read and verify - // that if we've been pushed, no error is returned and if we - // have been aborted, we get an aborted error. - var err error - if read { - pushByReading(key) - _, err = txn.Get(ctx, key) - if err != nil { - t.Fatalf("%s: expected no error; got %s", key, err) - } - } else { - abortByWriting(key) - _, err = txn.Get(ctx, key) - assertTransactionAbortedError(t, err) + // Now simulate a concurrent reader or writer. Our txn will + // either be pushed or aborted. Then issue a read and verify + // that if we've been pushed, no error is returned and if we + // have been aborted, we get an aborted error. + var err error + if read { + pushByReading(key) + _, err = txn.Get(ctx, key) + if err != nil { + t.Fatalf("%s: expected no error; got %s", key, err) } - - return err - }); err != nil { - t.Fatal(err) + } else { + abortByWriting(key) + _, err = txn.Get(ctx, key) + assertTransactionAbortedError(t, err) } + + return err + }); err != nil { + t.Fatal(err) } } } @@ -371,17 +278,15 @@ func TestTxnTimestampRegression(t *testing.T) { keyA := "a" keyB := "b" err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - // Use snapshot isolation so non-transactional read can always push. - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } // Put transactional value. if err := txn.Put(ctx, keyA, "value1"); err != nil { return err } - // Attempt to read outside of txn (this will push timestamp of transaction). - if _, err := s.DB.Get(context.TODO(), keyA); err != nil { + // Attempt to read in another txn (this will push timestamp of transaction). + conflictTxn := client.NewTxn(ctx, s.DB, 0 /* gatewayNodeID */, client.RootTxn) + conflictTxn.InternalSetPriority(roachpb.MaxTxnPriority) + if _, err := conflictTxn.Get(context.TODO(), keyA); err != nil { return err } @@ -413,10 +318,6 @@ func TestTxnLongDelayBetweenWritesWithConcurrentRead(t *testing.T) { errChan := make(chan error) go func() { errChan <- s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - // Use snapshot isolation. - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } // Put transactional value. if err := txn.Put(ctx, keyA, "value1"); err != nil { return err @@ -435,11 +336,6 @@ func TestTxnLongDelayBetweenWritesWithConcurrentRead(t *testing.T) { // Delay for longer than the cache window. s.Manual.Increment((tscache.MinRetentionWindow + time.Second).Nanoseconds()) if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - // Use snapshot isolation. - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - // Attempt to get first keyB. gr1, err := txn.Get(ctx, keyB) if err != nil { @@ -487,10 +383,6 @@ func TestTxnRepeatGetWithRangeSplit(t *testing.T) { errChan := make(chan error) go func() { errChan <- s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - // Use snapshot isolation. - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } // Put transactional value. if err := txn.Put(ctx, keyA, "value1"); err != nil { return err @@ -508,11 +400,6 @@ func TestTxnRepeatGetWithRangeSplit(t *testing.T) { <-ch if err := s.DB.Txn(context.TODO(), func(ctx context.Context, txn *client.Txn) error { - // Use snapshot isolation. - if err := txn.SetIsolation(enginepb.SNAPSHOT); err != nil { - return err - } - // First get keyC, value will be nil. gr1, err := txn.Get(ctx, keyC) if err != nil { diff --git a/pkg/roachpb/batch_test.go b/pkg/roachpb/batch_test.go index 6617402a3abf..ce4841e9268c 100644 --- a/pkg/roachpb/batch_test.go +++ b/pkg/roachpb/batch_test.go @@ -18,7 +18,6 @@ import ( "reflect" "testing" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/kr/pretty" ) @@ -311,7 +310,7 @@ func TestBatchResponseCombine(t *testing.T) { { txn := MakeTransaction( "test", nil /* baseKey */, NormalUserPriority, - enginepb.SERIALIZABLE, hlc.Timestamp{WallTime: 123}, 0, /* maxOffsetNs */ + hlc.Timestamp{WallTime: 123}, 0, /* maxOffsetNs */ ) brTxn := &BatchResponse{ BatchResponse_Header: BatchResponse_Header{ diff --git a/pkg/roachpb/data.go b/pkg/roachpb/data.go index 3f4a4ea54e56..0438573270ad 100644 --- a/pkg/roachpb/data.go +++ b/pkg/roachpb/data.go @@ -735,12 +735,7 @@ const ( // baseKey can be nil, in which case it will be set when sending the first // write. func MakeTransaction( - name string, - baseKey Key, - userPriority UserPriority, - isolation enginepb.IsolationType, - now hlc.Timestamp, - maxOffsetNs int64, + name string, baseKey Key, userPriority UserPriority, now hlc.Timestamp, maxOffsetNs int64, ) Transaction { u := uuid.FastMakeV4() var maxTS hlc.Timestamp @@ -757,7 +752,6 @@ func MakeTransaction( TxnMeta: enginepb.TxnMeta{ Key: baseKey, ID: u, - Isolation: isolation, Timestamp: now, Priority: MakePriority(userPriority), Sequence: 0, // 1-indexed, incremented before each Request @@ -931,7 +925,6 @@ func (t *Transaction) Restart( t.UpgradePriority(MakePriority(userPriority)) t.UpgradePriority(upgradePriority) t.WriteTooOld = false - t.RetryOnPush = false t.Sequence = 0 // Reset Writing. Since we're using a new epoch, we don't care about the abort // cache. @@ -982,14 +975,12 @@ func (t *Transaction) Update(o *Transaction) { } // If the epoch or refreshed timestamp move forward, overwrite - // WriteTooOld and RetryOnPush, otherwise the flags are cumulative. + // WriteTooOld, otherwise the flags are cumulative. if t.Epoch < o.Epoch || t.RefreshedTimestamp.Less(o.RefreshedTimestamp) { t.WriteTooOld = o.WriteTooOld - t.RetryOnPush = o.RetryOnPush t.OrigTimestampWasObserved = o.OrigTimestampWasObserved } else { t.WriteTooOld = t.WriteTooOld || o.WriteTooOld - t.RetryOnPush = t.RetryOnPush || o.RetryOnPush t.OrigTimestampWasObserved = t.OrigTimestampWasObserved || o.OrigTimestampWasObserved } @@ -1037,12 +1028,6 @@ func (t *Transaction) UpgradePriority(minPriority int32) { } } -// IsSerializable returns whether this transaction uses serializable -// isolation. -func (t *Transaction) IsSerializable() bool { - return t != nil && t.Isolation == enginepb.SERIALIZABLE -} - // String formats transaction into human readable string. func (t Transaction) String() string { var buf bytes.Buffer @@ -1051,10 +1036,10 @@ func (t Transaction) String() string { if len(t.Name) > 0 { fmt.Fprintf(&buf, "%q ", t.Name) } - fmt.Fprintf(&buf, "id=%s key=%s rw=%t pri=%.8f iso=%s stat=%s epo=%d "+ - "ts=%s orig=%s max=%s wto=%t rop=%t seq=%d", - t.Short(), Key(t.Key), t.Writing, floatPri, t.Isolation, t.Status, t.Epoch, t.Timestamp, - t.OrigTimestamp, t.MaxTimestamp, t.WriteTooOld, t.RetryOnPush, t.Sequence) + fmt.Fprintf(&buf, "id=%s key=%s rw=%t pri=%.8f stat=%s epo=%d "+ + "ts=%s orig=%s max=%s wto=%t seq=%d", + t.Short(), Key(t.Key), t.Writing, floatPri, t.Status, t.Epoch, t.Timestamp, + t.OrigTimestamp, t.MaxTimestamp, t.WriteTooOld, t.Sequence) if ni := len(t.Intents); t.Status != PENDING && ni > 0 { fmt.Fprintf(&buf, " int=%d", ni) } @@ -1143,7 +1128,6 @@ func PrepareTransactionForRetry( // We have errTxnPri, but this wants a UserPriority. So we're going to // overwrite the priority below. NormalUserPriority, - txn.Isolation, newTxnTimestamp, clock.MaxOffset().Nanoseconds(), ) @@ -1181,7 +1165,7 @@ func CanTransactionRetryAtRefreshedTimestamp( ctx context.Context, pErr *Error, ) (bool, *Transaction) { txn := pErr.GetTxn() - if !txn.IsSerializable() || txn.OrigTimestampWasObserved { + if txn == nil || txn.OrigTimestampWasObserved { return false, nil } timestamp := txn.Timestamp diff --git a/pkg/roachpb/data.pb.go b/pkg/roachpb/data.pb.go index 797daf8f530c..74a802676fe1 100644 --- a/pkg/roachpb/data.pb.go +++ b/pkg/roachpb/data.pb.go @@ -333,11 +333,10 @@ func (*ObservedTimestamp) ProtoMessage() {} func (*ObservedTimestamp) Descriptor() ([]byte, []int) { return fileDescriptorData, []int{9} } // A Transaction is a unit of work performed on the database. -// Cockroach transactions support two isolation levels: snapshot -// isolation and serializable snapshot isolation. Each Cockroach -// transaction is assigned a random priority. This priority will be -// used to decide whether a transaction will be aborted during -// contention. +// Cockroach transactions always operate at the serializable isolation +// level. Each Cockroach transaction is assigned a random priority. +// This priority will be used to decide whether a transaction will be +// aborted during contention. // // If you add fields to Transaction you'll need to update // Transaction.Clone. Failure to do so will result in test failures. @@ -465,13 +464,7 @@ type Transaction struct { // This bool is set instead of immediately returning a txn retry // error so that intents can continue to be laid down, minimizing // work required on txn restart. - WriteTooOld bool `protobuf:"varint,12,opt,name=write_too_old,json=writeTooOld,proto3" json:"write_too_old,omitempty"` - // If retry_on_push is true, the transaction must retry in the event - // that the commit timestamp is pushed forward. This flag is set if - // the transaction contains any calls to DeleteRange, in order to - // prevent the LostDeleteRange anomaly. This flag is relevant only - // for SNAPSHOT transactions. - RetryOnPush bool `protobuf:"varint,13,opt,name=retry_on_push,json=retryOnPush,proto3" json:"retry_on_push,omitempty"` + WriteTooOld bool `protobuf:"varint,12,opt,name=write_too_old,json=writeTooOld,proto3" json:"write_too_old,omitempty"` Intents []Span `protobuf:"bytes,11,rep,name=intents" json:"intents"` // Epoch zero timestamp is used to keep track of the earliest timestamp // that any epoch of the transaction used. This is set only if the @@ -944,9 +937,6 @@ func (this *Transaction) Equal(that interface{}) bool { if this.WriteTooOld != that1.WriteTooOld { return false } - if this.RetryOnPush != that1.RetryOnPush { - return false - } if len(this.Intents) != len(that1.Intents) { return false } @@ -1514,16 +1504,6 @@ func (m *Transaction) MarshalTo(dAtA []byte) (int, error) { } i++ } - if m.RetryOnPush { - dAtA[i] = 0x68 - i++ - if m.RetryOnPush { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - } dAtA[i] = 0x72 i++ i = encodeVarintData(dAtA, i, uint64(m.EpochZeroTimestamp.Size())) @@ -1902,7 +1882,6 @@ func NewPopulatedTransaction(r randyData, easy bool) *Transaction { } } this.WriteTooOld = bool(bool(r.Intn(2) == 0)) - this.RetryOnPush = bool(bool(r.Intn(2) == 0)) v12 := cockroach_util_hlc.NewPopulatedTimestamp(r, easy) this.EpochZeroTimestamp = *v12 v13 := cockroach_util_hlc.NewPopulatedTimestamp(r, easy) @@ -2209,9 +2188,6 @@ func (m *Transaction) Size() (n int) { if m.WriteTooOld { n += 2 } - if m.RetryOnPush { - n += 2 - } l = m.EpochZeroTimestamp.Size() n += 1 + l + sovData(uint64(l)) l = m.RefreshedTimestamp.Size() @@ -3909,26 +3885,6 @@ func (m *Transaction) Unmarshal(dAtA []byte) error { } } m.WriteTooOld = bool(v != 0) - case 13: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RetryOnPush", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowData - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.RetryOnPush = bool(v != 0) case 14: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field EpochZeroTimestamp", wireType) @@ -5007,124 +4963,123 @@ var ( func init() { proto.RegisterFile("roachpb/data.proto", fileDescriptorData) } var fileDescriptorData = []byte{ - // 1903 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4d, 0x6f, 0xdb, 0xc8, - 0xf9, 0x37, 0xf5, 0x62, 0x51, 0x8f, 0x5e, 0x4c, 0x8f, 0xe3, 0x44, 0x7f, 0x2f, 0xfe, 0x52, 0x56, - 0x5b, 0xb4, 0x41, 0xb0, 0x2b, 0xa3, 0x49, 0x5f, 0x8d, 0xb6, 0x80, 0xde, 0x92, 0x30, 0xb1, 0x64, - 0x83, 0xa2, 0x1d, 0x6c, 0x16, 0x0b, 0x96, 0x22, 0xc7, 0x12, 0x11, 0x89, 0x64, 0x87, 0x23, 0xc7, - 0xda, 0x4f, 0xb0, 0xb7, 0xee, 0xa1, 0x87, 0x1e, 0x03, 0xf4, 0xd6, 0x2f, 0xd0, 0x7e, 0x83, 0xe6, - 0x52, 0x60, 0x6f, 0x2d, 0x7a, 0x10, 0x5a, 0xf5, 0xd2, 0xa2, 0xb7, 0x1e, 0x03, 0x2c, 0x50, 0xcc, - 0x0c, 0x29, 0xd1, 0xb5, 0x62, 0xc8, 0xdd, 0x1e, 0x7a, 0xb1, 0x67, 0x9e, 0x79, 0x9e, 0xdf, 0x3c, - 0xf3, 0xbc, 0xfc, 0x66, 0x28, 0x40, 0xc4, 0x33, 0xad, 0xa1, 0xdf, 0xdf, 0xb7, 0x4d, 0x6a, 0xd6, - 0x7c, 0xe2, 0x51, 0x0f, 0x6d, 0x5b, 0x9e, 0xf5, 0x92, 0xcb, 0x6b, 0xe1, 0xea, 0xde, 0xed, 0x48, - 0x6d, 0x8c, 0xa9, 0xb9, 0x54, 0xdd, 0xab, 0x06, 0xd4, 0x23, 0xe6, 0x00, 0xef, 0x63, 0x77, 0xe0, - 0xb8, 0xd1, 0x3f, 0xa6, 0x77, 0x6e, 0x59, 0xa1, 0xce, 0x07, 0xd7, 0xe9, 0x3c, 0x0c, 0x95, 0x4a, - 0x13, 0xea, 0x8c, 0xf6, 0x87, 0x23, 0x6b, 0x9f, 0x3a, 0x63, 0x1c, 0x50, 0x73, 0xec, 0x87, 0x2b, - 0xb7, 0x06, 0xde, 0xc0, 0xe3, 0xc3, 0x7d, 0x36, 0x12, 0xd2, 0xea, 0xa7, 0x90, 0xea, 0xf9, 0xa6, - 0x8b, 0xfe, 0x0f, 0x92, 0x2f, 0xf1, 0xb4, 0x94, 0xbc, 0x2b, 0xdd, 0xcb, 0x37, 0x32, 0x6f, 0x67, - 0x95, 0xe4, 0x33, 0x3c, 0xd5, 0x98, 0x0c, 0xdd, 0x85, 0x0c, 0x76, 0x6d, 0x83, 0x2d, 0xa7, 0x2e, - 0x2f, 0x6f, 0x62, 0xd7, 0x7e, 0x86, 0xa7, 0x07, 0xf9, 0x5f, 0xbe, 0xae, 0x6c, 0xfc, 0xf6, 0x75, - 0x45, 0xfa, 0xdb, 0xeb, 0x8a, 0xf4, 0x34, 0x25, 0x4b, 0x4a, 0xe2, 0x69, 0x4a, 0x4e, 0x28, 0xc9, - 0xea, 0x18, 0xd2, 0xa7, 0xe6, 0x68, 0x82, 0xd1, 0x7b, 0x90, 0x25, 0xe6, 0x2b, 0xa3, 0x3f, 0xa5, - 0x38, 0x28, 0x49, 0x0c, 0x46, 0x93, 0x89, 0xf9, 0xaa, 0xc1, 0xe6, 0xa8, 0x0e, 0xd9, 0x85, 0xb7, - 0xa5, 0xc4, 0x5d, 0xe9, 0x5e, 0xee, 0xc1, 0xff, 0xd7, 0x96, 0xc1, 0x63, 0x47, 0xaa, 0x0d, 0x47, - 0x56, 0x4d, 0x8f, 0x94, 0x1a, 0xa9, 0x37, 0xb3, 0xca, 0x86, 0xb6, 0xb4, 0x3a, 0x48, 0xb1, 0xad, - 0xab, 0x9f, 0x80, 0xfc, 0x0c, 0x4f, 0xc5, 0x8e, 0xe1, 0x89, 0xa4, 0x15, 0x27, 0xfa, 0x0e, 0xa4, - 0xcf, 0x99, 0x4e, 0xb8, 0x57, 0xa9, 0x76, 0x25, 0x51, 0x35, 0x8e, 0x11, 0x6e, 0x23, 0x94, 0xab, - 0x7f, 0x90, 0x00, 0x7a, 0xd4, 0x23, 0x58, 0xb5, 0xb1, 0x4b, 0xd1, 0x00, 0xc0, 0x1a, 0x4d, 0x02, - 0x8a, 0x89, 0xe1, 0xd8, 0xe1, 0x36, 0x4f, 0x98, 0xfe, 0x9f, 0x66, 0x95, 0x87, 0x03, 0x87, 0x0e, - 0x27, 0xfd, 0x9a, 0xe5, 0x8d, 0xf7, 0x17, 0xd8, 0x76, 0x7f, 0x39, 0xde, 0xf7, 0x5f, 0x0e, 0xf6, - 0x79, 0xaa, 0x26, 0x13, 0xc7, 0xae, 0x9d, 0x9c, 0xa8, 0xad, 0xf9, 0xac, 0x92, 0x6d, 0x0a, 0x40, - 0xb5, 0xa5, 0x65, 0x43, 0x6c, 0xd5, 0x46, 0x1f, 0x41, 0xc6, 0xf5, 0x6c, 0xcc, 0x76, 0x61, 0xfe, - 0xa6, 0x1b, 0xb7, 0xe6, 0xb3, 0xca, 0x66, 0xd7, 0xb3, 0xb1, 0xda, 0x7a, 0xbb, 0x18, 0x69, 0x9b, - 0x4c, 0x49, 0xb5, 0xd1, 0xb7, 0x41, 0x66, 0x85, 0xc2, 0xf5, 0x93, 0x5c, 0xff, 0xf6, 0x7c, 0x56, - 0xc9, 0x08, 0xcf, 0x99, 0x41, 0x34, 0xd4, 0x32, 0x81, 0x38, 0x4d, 0xf5, 0xd7, 0x12, 0xe4, 0x7b, - 0xfe, 0xc8, 0xa1, 0x3a, 0x71, 0x06, 0x03, 0x4c, 0x50, 0x1b, 0xb2, 0x23, 0x7c, 0x46, 0x0d, 0x1b, - 0x07, 0x16, 0x3f, 0x5a, 0xee, 0x41, 0x75, 0x45, 0x90, 0x34, 0xd3, 0x1d, 0xe0, 0x16, 0x0e, 0x2c, - 0xe2, 0xf8, 0xd4, 0x23, 0x61, 0xb8, 0x64, 0x66, 0xca, 0xa4, 0xe8, 0x31, 0x00, 0x71, 0x06, 0xc3, - 0x10, 0x27, 0x71, 0x43, 0x9c, 0x2c, 0xb7, 0x65, 0x62, 0x91, 0xdd, 0xa7, 0x29, 0x39, 0xa9, 0xa4, - 0xaa, 0xf3, 0x04, 0xe4, 0x3b, 0x98, 0x0c, 0xf0, 0xff, 0xa8, 0xb3, 0xc8, 0x05, 0x45, 0x00, 0xb1, - 0xbe, 0x34, 0x02, 0x6a, 0xd2, 0x80, 0x37, 0x4e, 0xee, 0xc1, 0x87, 0x31, 0xb8, 0xb0, 0x99, 0x6b, - 0xa2, 0x8b, 0x6b, 0x51, 0x33, 0xd7, 0x3a, 0xa7, 0xcd, 0x66, 0x8f, 0xd9, 0x34, 0x6e, 0x33, 0xe0, - 0xf9, 0xac, 0x52, 0xd4, 0x18, 0xda, 0x42, 0xae, 0x15, 0x39, 0x7a, 0xe7, 0xdc, 0xb2, 0xf8, 0x1c, - 0x3d, 0x82, 0xfc, 0x19, 0xc1, 0xf8, 0x33, 0xcc, 0xf6, 0x22, 0xb4, 0x94, 0x5e, 0xbf, 0x81, 0x72, - 0xc2, 0xb0, 0xc7, 0xec, 0x2e, 0x05, 0xf9, 0xf7, 0x09, 0xd8, 0x6d, 0x0e, 0xd9, 0x49, 0x35, 0xec, - 0x8f, 0x1c, 0xcb, 0x0c, 0x96, 0xd1, 0xce, 0x59, 0x7c, 0xc1, 0xa0, 0x53, 0x1f, 0xf3, 0x78, 0x17, - 0x1f, 0x7c, 0x63, 0x55, 0x9c, 0x84, 0xa1, 0x40, 0xd1, 0xa7, 0x3e, 0xd6, 0xc0, 0x5a, 0x8c, 0x51, - 0x0b, 0x32, 0x44, 0x28, 0x84, 0xa1, 0xbe, 0x06, 0xe2, 0x4a, 0xb0, 0x23, 0x53, 0x74, 0x02, 0xca, - 0xc4, 0xb7, 0x4d, 0x8a, 0x6d, 0x23, 0x14, 0x05, 0xa5, 0xe4, 0xdd, 0xe4, 0x0d, 0xe1, 0xb6, 0x42, - 0x8c, 0xe8, 0xa8, 0xe8, 0x11, 0x6c, 0xb9, 0xf8, 0x82, 0x46, 0x98, 0xac, 0x93, 0x52, 0xbc, 0x93, - 0xca, 0xf3, 0x59, 0xa5, 0xd0, 0xc5, 0x17, 0x34, 0x54, 0xe5, 0xfd, 0x94, 0x5d, 0x4c, 0xb4, 0x82, - 0x1b, 0x5b, 0xb3, 0x0f, 0x64, 0xc6, 0x8b, 0x9c, 0x98, 0xbe, 0x90, 0x60, 0xa7, 0xe3, 0xd9, 0xce, - 0x99, 0x83, 0x6d, 0xc6, 0xb7, 0x51, 0x34, 0x3f, 0x04, 0x14, 0x4c, 0x03, 0x8a, 0xc7, 0x86, 0xe5, - 0xb9, 0x67, 0xce, 0xc0, 0x08, 0x7c, 0xd3, 0xe5, 0x41, 0x95, 0x35, 0x45, 0xac, 0x34, 0xf9, 0x02, - 0x27, 0xe9, 0x36, 0x20, 0xce, 0x04, 0x23, 0xe7, 0x1c, 0xbb, 0x38, 0x08, 0x84, 0xb6, 0x88, 0xdf, - 0x9d, 0x15, 0x07, 0x66, 0x46, 0x9a, 0xc2, 0x4c, 0x0e, 0x43, 0x0b, 0x26, 0x09, 0xb9, 0xf2, 0x1f, - 0x09, 0xd8, 0x55, 0x5d, 0x8a, 0x89, 0x6b, 0x8e, 0x9a, 0xde, 0x78, 0xbc, 0xec, 0xfe, 0x16, 0x14, - 0x02, 0xc6, 0x06, 0x06, 0x15, 0x82, 0xb0, 0xa9, 0x2a, 0x2b, 0x77, 0x58, 0xb2, 0x86, 0x96, 0x0f, - 0xe2, 0x1c, 0xd2, 0x82, 0xc2, 0x98, 0xb5, 0xe9, 0x02, 0x25, 0xf1, 0x4e, 0x94, 0x78, 0x3b, 0x6b, - 0xf9, 0x71, 0xbc, 0xb9, 0x7f, 0x0a, 0x77, 0xc2, 0x72, 0x8b, 0x12, 0xbc, 0xc0, 0x4b, 0x72, 0xbc, - 0x7b, 0x2b, 0xf0, 0x56, 0x56, 0xae, 0xb6, 0x6b, 0xad, 0x2c, 0xe8, 0x17, 0xb0, 0x3b, 0x0e, 0x33, - 0xc3, 0xe3, 0xb9, 0xc0, 0x17, 0x3d, 0xfb, 0xcd, 0x55, 0xfe, 0x5e, 0xcd, 0xa4, 0xb6, 0x33, 0xbe, - 0x2a, 0x3c, 0x90, 0x3f, 0x0f, 0x2f, 0xc5, 0xea, 0xcf, 0x25, 0xd8, 0x3e, 0xea, 0x07, 0x98, 0x9c, - 0x63, 0x7b, 0xd1, 0x85, 0x71, 0x6a, 0x97, 0xd6, 0xa0, 0xf6, 0xff, 0xc2, 0x3d, 0x29, 0x47, 0xd7, - 0x74, 0xf5, 0xab, 0x4d, 0xc8, 0xe9, 0xc4, 0x74, 0x03, 0xd3, 0xa2, 0x8e, 0xe7, 0xa2, 0x27, 0x90, - 0x62, 0x8f, 0x92, 0x30, 0xd9, 0xf7, 0xd7, 0xa0, 0x2a, 0xfd, 0xc2, 0xed, 0x60, 0x6a, 0x36, 0x64, - 0xb6, 0xc9, 0x97, 0xb3, 0x8a, 0xa4, 0x71, 0x04, 0x84, 0x20, 0xe5, 0x9a, 0x63, 0x71, 0xbb, 0x66, - 0x35, 0x3e, 0x46, 0x3f, 0x82, 0x4d, 0xc6, 0x84, 0x13, 0x41, 0x85, 0xab, 0x19, 0x23, 0xe6, 0x4d, - 0x8f, 0xeb, 0x6a, 0xa1, 0x0d, 0x7a, 0x0a, 0xc5, 0x91, 0x19, 0x50, 0x63, 0x88, 0x4d, 0x42, 0xfb, - 0xd8, 0xbc, 0x11, 0xc9, 0x15, 0x98, 0xe9, 0x93, 0xc8, 0x92, 0x61, 0x79, 0xc4, 0x19, 0x18, 0xcb, - 0x48, 0x6e, 0xde, 0x00, 0x8b, 0x99, 0x2e, 0xf3, 0xf7, 0x04, 0x0a, 0x63, 0xf3, 0x22, 0x06, 0x95, - 0x59, 0x1f, 0x2a, 0x3f, 0x36, 0x2f, 0x96, 0x48, 0x9f, 0xc0, 0x8e, 0x17, 0x96, 0xc7, 0x12, 0x2e, - 0x28, 0xc9, 0xef, 0x24, 0xb3, 0x2b, 0xc5, 0x14, 0xc2, 0x22, 0xef, 0xdf, 0x17, 0x02, 0x54, 0x82, - 0xcc, 0x2b, 0xe2, 0x50, 0xc7, 0x1d, 0x94, 0xb2, 0x9c, 0x5a, 0xa2, 0x29, 0xfa, 0x3e, 0x64, 0x1c, - 0x97, 0x62, 0x97, 0x06, 0xa5, 0x1c, 0xdf, 0xea, 0x5d, 0x34, 0x12, 0x31, 0x6f, 0xa8, 0x8d, 0xaa, - 0x50, 0x60, 0x18, 0xd8, 0xa0, 0x9e, 0x67, 0x78, 0x23, 0xbb, 0x94, 0xe7, 0xc0, 0x39, 0x2e, 0xd4, - 0x3d, 0xef, 0x68, 0x64, 0x33, 0x1d, 0x82, 0x29, 0x99, 0x1a, 0x9e, 0x6b, 0xf8, 0x93, 0x60, 0x58, - 0x2a, 0x08, 0x1d, 0x2e, 0x3c, 0x72, 0x8f, 0x27, 0xc1, 0x10, 0x9d, 0xc0, 0x2d, 0xec, 0x7b, 0xd6, - 0xd0, 0xf8, 0x0c, 0x13, 0x2f, 0x16, 0xc8, 0xe2, 0xfa, 0x81, 0x44, 0x1c, 0xe0, 0x05, 0x26, 0xde, - 0x32, 0x9c, 0x3a, 0xec, 0x10, 0x7c, 0x46, 0x70, 0x30, 0x8c, 0xc7, 0xb3, 0xb4, 0x75, 0x03, 0xd4, - 0x85, 0xfd, 0x12, 0xf5, 0xc7, 0xf0, 0xde, 0xe5, 0xd2, 0x31, 0x5e, 0x99, 0x81, 0x11, 0x05, 0xbc, - 0xa4, 0xf0, 0xe3, 0x95, 0x2e, 0x95, 0xc8, 0x73, 0x33, 0x88, 0x32, 0x75, 0xf9, 0x99, 0x5c, 0xfd, - 0x9d, 0x04, 0x9b, 0x2a, 0x8f, 0x26, 0xfa, 0x2e, 0xa4, 0x16, 0xbc, 0x7f, 0x4d, 0x0a, 0x62, 0x7d, - 0xc6, 0xd4, 0x51, 0x03, 0x92, 0xf4, 0x22, 0xe2, 0xff, 0x9b, 0x34, 0xac, 0x38, 0x21, 0x33, 0x8e, - 0xf5, 0x65, 0xf2, 0xe6, 0x7d, 0x19, 0xde, 0x24, 0x8f, 0xa1, 0xd8, 0xc3, 0x3f, 0x9b, 0x60, 0xd7, - 0xc2, 0xf6, 0x73, 0x96, 0xff, 0xeb, 0xde, 0xde, 0x7b, 0x20, 0x07, 0xa1, 0xb2, 0x78, 0xce, 0x6a, - 0x8b, 0x79, 0xf5, 0xab, 0x24, 0xa4, 0x0f, 0xb1, 0x19, 0x60, 0xf4, 0x43, 0x48, 0x8b, 0xc7, 0x8c, - 0xb4, 0x7e, 0xc6, 0x84, 0x05, 0xfa, 0x14, 0x00, 0x5f, 0xf8, 0x0e, 0x31, 0x99, 0xbf, 0xeb, 0xb1, - 0x64, 0xf9, 0x9f, 0xb3, 0xca, 0x5e, 0xec, 0x9d, 0x7e, 0x50, 0x25, 0xa6, 0x6b, 0xbb, 0x93, 0xd1, - 0xc8, 0xec, 0x8f, 0x70, 0x55, 0x8b, 0x01, 0xc6, 0x1f, 0x2e, 0xc9, 0xff, 0xfc, 0xe1, 0x32, 0x81, - 0x3b, 0x36, 0xf6, 0x09, 0xb6, 0xf8, 0xdb, 0x85, 0x3b, 0xce, 0xfe, 0x06, 0x4e, 0xf4, 0x54, 0xfc, - 0x9a, 0x1e, 0xef, 0x2e, 0xd1, 0xf9, 0xe3, 0xae, 0xc7, 0xb1, 0x51, 0x17, 0x72, 0x3e, 0xf1, 0x7c, - 0x2f, 0x60, 0x5d, 0x11, 0xac, 0x47, 0xa2, 0xc5, 0xf9, 0xac, 0x02, 0xc7, 0xa1, 0x95, 0xde, 0xd3, - 0x20, 0x42, 0xd0, 0x03, 0x74, 0x0b, 0xd2, 0xbc, 0xf9, 0x38, 0x85, 0x26, 0x35, 0x31, 0x41, 0x1f, - 0xc5, 0x52, 0xcc, 0x08, 0x31, 0xd9, 0xd8, 0x7e, 0x3b, 0xab, 0x14, 0x78, 0x66, 0xa3, 0x42, 0x59, - 0x66, 0x5d, 0xbc, 0x92, 0x58, 0x5b, 0x54, 0x7f, 0x21, 0x41, 0xb1, 0xde, 0xf7, 0x08, 0x65, 0xe5, - 0xde, 0x76, 0x29, 0x99, 0x5e, 0x57, 0x49, 0x5f, 0xff, 0x36, 0x64, 0xc5, 0xe8, 0x13, 0xc7, 0x23, - 0x0e, 0x15, 0x9f, 0xbe, 0x69, 0x6d, 0x31, 0x8f, 0xdd, 0x94, 0x7f, 0x4f, 0x42, 0x5e, 0xbf, 0x70, - 0x9b, 0x9e, 0x47, 0x6c, 0xd6, 0x3f, 0xe8, 0x7b, 0xa2, 0xf1, 0x44, 0x6d, 0x96, 0xaf, 0xef, 0x98, - 0x78, 0xb3, 0xc5, 0xd8, 0x36, 0x71, 0x23, 0xb6, 0xfd, 0x00, 0x0a, 0x96, 0x37, 0x1e, 0x9b, 0xae, - 0x6d, 0x58, 0xde, 0xc4, 0xa5, 0xa1, 0xb3, 0xf9, 0x50, 0xd8, 0x64, 0x32, 0xd4, 0x60, 0x74, 0xcb, - 0x39, 0xcb, 0x20, 0xd8, 0xb4, 0x59, 0x25, 0xad, 0xb1, 0x47, 0x3e, 0xb4, 0xd1, 0x98, 0x09, 0x6a, - 0x41, 0x31, 0xc2, 0xe0, 0x4c, 0xce, 0x6a, 0x64, 0x0d, 0x90, 0x68, 0x63, 0xde, 0xfd, 0x01, 0xfa, - 0x01, 0x94, 0x62, 0xd5, 0x1d, 0x01, 0x9e, 0x9b, 0x23, 0xc7, 0xe6, 0x95, 0x22, 0x6b, 0xb7, 0x97, - 0xeb, 0x9a, 0x58, 0x3e, 0x65, 0xab, 0xe8, 0x5b, 0xb0, 0x15, 0xa9, 0x3b, 0xae, 0x30, 0xc8, 0x70, - 0x83, 0xc8, 0x2d, 0x55, 0x48, 0xd1, 0x29, 0x20, 0x6f, 0x42, 0x03, 0x6a, 0xba, 0xb6, 0xe3, 0x0e, - 0x22, 0x67, 0xc5, 0x75, 0xf9, 0xfe, 0x2a, 0x67, 0x2f, 0x11, 0x54, 0xe8, 0xf6, 0x76, 0x0c, 0x42, - 0xb8, 0x7e, 0xff, 0x37, 0x12, 0x64, 0xf9, 0xb7, 0x3f, 0xff, 0x4a, 0xc9, 0x41, 0xe6, 0xa4, 0xfb, - 0xac, 0x7b, 0xf4, 0xbc, 0xab, 0x6c, 0xa0, 0x0c, 0x24, 0xd5, 0xae, 0xae, 0x48, 0x28, 0x0b, 0xe9, - 0x47, 0x87, 0x47, 0x75, 0x5d, 0x49, 0xb0, 0x61, 0xe3, 0x63, 0xbd, 0xdd, 0x53, 0x92, 0x68, 0x07, - 0xb6, 0x5a, 0xed, 0x43, 0xb5, 0xa3, 0xea, 0xed, 0x96, 0x21, 0x84, 0x32, 0x92, 0x21, 0xa5, 0xab, - 0x9d, 0xb6, 0x92, 0x62, 0x50, 0xad, 0x76, 0x53, 0xed, 0xd4, 0x0f, 0x95, 0x34, 0xda, 0x85, 0xed, - 0xa5, 0x6e, 0x24, 0xce, 0xa2, 0x3c, 0xc8, 0xad, 0x13, 0xad, 0xae, 0xab, 0x47, 0x5d, 0x65, 0x93, - 0x61, 0xeb, 0x27, 0xc7, 0x87, 0x6d, 0x05, 0xd8, 0x42, 0x43, 0xd5, 0xeb, 0x9a, 0x56, 0xff, 0x58, - 0xc9, 0xa1, 0x22, 0x00, 0x03, 0xed, 0xb5, 0x35, 0xb5, 0xdd, 0x53, 0xec, 0x6a, 0x4a, 0xce, 0x28, - 0x99, 0xfb, 0x3f, 0x81, 0xed, 0x2b, 0x9f, 0x5c, 0x68, 0x0b, 0x72, 0xf5, 0x56, 0xcb, 0xd0, 0xda, - 0xc7, 0x87, 0x6a, 0xb3, 0xae, 0x6c, 0x20, 0x04, 0x45, 0xad, 0xdd, 0x39, 0x3a, 0x6d, 0x2f, 0x64, - 0xd2, 0x5e, 0xea, 0xf3, 0x5f, 0x95, 0x37, 0xee, 0x37, 0x60, 0xfb, 0x0a, 0xd1, 0x33, 0xaf, 0x8f, - 0xdb, 0xdd, 0x96, 0xda, 0x7d, 0xac, 0x6c, 0xa0, 0x02, 0x64, 0x9b, 0x47, 0x9d, 0x8e, 0xaa, 0xeb, - 0xed, 0x96, 0x22, 0xb1, 0xb5, 0x7a, 0xe3, 0x48, 0x63, 0x93, 0x84, 0xc0, 0x68, 0xbc, 0xff, 0xe6, - 0x2f, 0xe5, 0x8d, 0x37, 0xf3, 0xb2, 0xf4, 0xe5, 0xbc, 0x2c, 0xfd, 0x71, 0x5e, 0x96, 0xfe, 0x3c, - 0x2f, 0x4b, 0x5f, 0xfc, 0xb5, 0xbc, 0xf1, 0x22, 0x13, 0x26, 0xa2, 0xbf, 0xc9, 0x7f, 0x77, 0x7a, - 0xf8, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x8c, 0x12, 0x75, 0x31, 0x13, 0x00, 0x00, + // 1881 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcb, 0x6f, 0xdb, 0xc8, + 0x19, 0x37, 0xf5, 0xb0, 0xa8, 0x4f, 0x0f, 0xd3, 0xe3, 0x38, 0x51, 0xbd, 0xa8, 0x94, 0xd5, 0x16, + 0x6d, 0x10, 0xec, 0xca, 0x68, 0xd2, 0xa7, 0xd1, 0x16, 0xd0, 0x2b, 0x09, 0x13, 0x4b, 0x0e, 0x28, + 0xda, 0xc1, 0x66, 0xb1, 0x60, 0x69, 0x72, 0x2c, 0x13, 0x91, 0x48, 0x75, 0x38, 0x72, 0xac, 0xfd, + 0x0b, 0xf6, 0xd6, 0x3d, 0xf4, 0xd0, 0x63, 0x80, 0xde, 0xfa, 0x0f, 0xb4, 0xff, 0x41, 0x73, 0x29, + 0xb0, 0xb7, 0x16, 0x3d, 0xa8, 0xad, 0x7a, 0x69, 0xd1, 0x5b, 0x8f, 0x01, 0x0a, 0x14, 0xf3, 0xa0, + 0x44, 0xd7, 0x8a, 0x21, 0x37, 0x3d, 0xec, 0xc5, 0x9e, 0xf9, 0xe6, 0xfb, 0x7e, 0xf3, 0xcd, 0xf7, + 0xf8, 0xcd, 0x50, 0x80, 0x48, 0x60, 0x3b, 0xa7, 0xa3, 0xe3, 0x5d, 0xd7, 0xa6, 0x76, 0x6d, 0x44, + 0x02, 0x1a, 0xa0, 0x4d, 0x27, 0x70, 0x5e, 0x70, 0x79, 0x4d, 0xae, 0xee, 0xdc, 0x8c, 0xd4, 0x86, + 0x98, 0xda, 0x0b, 0xd5, 0x9d, 0x6a, 0x48, 0x03, 0x62, 0xf7, 0xf1, 0x2e, 0xf6, 0xfb, 0x9e, 0x1f, + 0xfd, 0x63, 0x7a, 0x67, 0x8e, 0x23, 0x75, 0x3e, 0xb8, 0x4a, 0xe7, 0xbe, 0x54, 0x2a, 0x8d, 0xa9, + 0x37, 0xd8, 0x3d, 0x1d, 0x38, 0xbb, 0xd4, 0x1b, 0xe2, 0x90, 0xda, 0xc3, 0x91, 0x5c, 0xb9, 0xd1, + 0x0f, 0xfa, 0x01, 0x1f, 0xee, 0xb2, 0x91, 0x90, 0x56, 0x3f, 0x85, 0x54, 0x6f, 0x64, 0xfb, 0xe8, + 0x6b, 0x90, 0x7c, 0x81, 0x27, 0xa5, 0xe4, 0x6d, 0xe5, 0x4e, 0xbe, 0x91, 0x79, 0x33, 0xad, 0x24, + 0x9f, 0xe0, 0x89, 0xc1, 0x64, 0xe8, 0x36, 0x64, 0xb0, 0xef, 0x5a, 0x6c, 0x39, 0x75, 0x71, 0x79, + 0x1d, 0xfb, 0xee, 0x13, 0x3c, 0xd9, 0xcb, 0xff, 0xf2, 0x55, 0x65, 0xed, 0xb7, 0xaf, 0x2a, 0xca, + 0xdf, 0x5f, 0x55, 0x94, 0xc7, 0x29, 0x55, 0xd1, 0x12, 0x8f, 0x53, 0x6a, 0x42, 0x4b, 0x56, 0x87, + 0x90, 0x3e, 0xb2, 0x07, 0x63, 0x8c, 0xde, 0x83, 0x2c, 0xb1, 0x5f, 0x5a, 0xc7, 0x13, 0x8a, 0xc3, + 0x92, 0xc2, 0x60, 0x0c, 0x95, 0xd8, 0x2f, 0x1b, 0x6c, 0x8e, 0xea, 0x90, 0x9d, 0x7b, 0x5b, 0x4a, + 0xdc, 0x56, 0xee, 0xe4, 0xee, 0x7d, 0xbd, 0xb6, 0x08, 0x1e, 0x3b, 0x52, 0xed, 0x74, 0xe0, 0xd4, + 0xcc, 0x48, 0xa9, 0x91, 0x7a, 0x3d, 0xad, 0xac, 0x19, 0x0b, 0xab, 0xbd, 0x14, 0xdb, 0xba, 0xfa, + 0x09, 0xa8, 0x4f, 0xf0, 0x44, 0xec, 0x28, 0x4f, 0xa4, 0x2c, 0x39, 0xd1, 0x77, 0x20, 0x7d, 0xc6, + 0x74, 0xe4, 0x5e, 0xa5, 0xda, 0xa5, 0x44, 0xd5, 0x38, 0x86, 0xdc, 0x46, 0x28, 0x57, 0xff, 0xa0, + 0x00, 0xf4, 0x68, 0x40, 0xb0, 0xee, 0x62, 0x9f, 0xa2, 0x3e, 0x80, 0x33, 0x18, 0x87, 0x14, 0x13, + 0xcb, 0x73, 0xe5, 0x36, 0x8f, 0x98, 0xfe, 0x9f, 0xa6, 0x95, 0xfb, 0x7d, 0x8f, 0x9e, 0x8e, 0x8f, + 0x6b, 0x4e, 0x30, 0xdc, 0x9d, 0x63, 0xbb, 0xc7, 0x8b, 0xf1, 0xee, 0xe8, 0x45, 0x7f, 0x97, 0xa7, + 0x6a, 0x3c, 0xf6, 0xdc, 0xda, 0xe1, 0xa1, 0xde, 0x9a, 0x4d, 0x2b, 0xd9, 0xa6, 0x00, 0xd4, 0x5b, + 0x46, 0x56, 0x62, 0xeb, 0x2e, 0xfa, 0x08, 0x32, 0x7e, 0xe0, 0x62, 0xb6, 0x0b, 0xf3, 0x37, 0xdd, + 0xb8, 0x31, 0x9b, 0x56, 0xd6, 0xbb, 0x81, 0x8b, 0xf5, 0xd6, 0x9b, 0xf9, 0xc8, 0x58, 0x67, 0x4a, + 0xba, 0x8b, 0xbe, 0x0d, 0x2a, 0x2b, 0x14, 0xae, 0x9f, 0xe4, 0xfa, 0x37, 0x67, 0xd3, 0x4a, 0x46, + 0x78, 0xce, 0x0c, 0xa2, 0xa1, 0x91, 0x09, 0xc5, 0x69, 0xaa, 0xbf, 0x56, 0x20, 0xdf, 0x1b, 0x0d, + 0x3c, 0x6a, 0x12, 0xaf, 0xdf, 0xc7, 0x04, 0xb5, 0x21, 0x3b, 0xc0, 0x27, 0xd4, 0x72, 0x71, 0xe8, + 0xf0, 0xa3, 0xe5, 0xee, 0x55, 0x97, 0x04, 0xc9, 0xb0, 0xfd, 0x3e, 0x6e, 0xe1, 0xd0, 0x21, 0xde, + 0x88, 0x06, 0x44, 0x86, 0x4b, 0x65, 0xa6, 0x4c, 0x8a, 0x1e, 0x02, 0x10, 0xaf, 0x7f, 0x2a, 0x71, + 0x12, 0xd7, 0xc4, 0xc9, 0x72, 0x5b, 0x26, 0x16, 0xd9, 0x7d, 0x9c, 0x52, 0x93, 0x5a, 0xaa, 0x3a, + 0x4b, 0x40, 0xbe, 0x83, 0x49, 0x1f, 0x7f, 0x45, 0x9d, 0x45, 0x3e, 0x68, 0x02, 0x88, 0xf5, 0xa5, + 0x15, 0x52, 0x9b, 0x86, 0xbc, 0x71, 0x72, 0xf7, 0x3e, 0x8c, 0xc1, 0xc9, 0x66, 0xae, 0x89, 0x2e, + 0xae, 0x45, 0xcd, 0x5c, 0xeb, 0x1c, 0x35, 0x9b, 0x3d, 0x66, 0xd3, 0xb8, 0xc9, 0x80, 0x67, 0xd3, + 0x4a, 0xd1, 0x60, 0x68, 0x73, 0xb9, 0x51, 0xe4, 0xe8, 0x9d, 0x33, 0xc7, 0xe1, 0x73, 0xf4, 0x00, + 0xf2, 0x27, 0x04, 0xe3, 0xcf, 0x30, 0xdb, 0x8b, 0xd0, 0x52, 0x7a, 0xf5, 0x06, 0xca, 0x09, 0xc3, + 0x1e, 0xb3, 0xbb, 0x10, 0xe4, 0xdf, 0x27, 0x60, 0xbb, 0x79, 0xca, 0x4e, 0x6a, 0xe0, 0xd1, 0xc0, + 0x73, 0xec, 0x70, 0x11, 0xed, 0x9c, 0xc3, 0x17, 0x2c, 0x3a, 0x19, 0x61, 0x1e, 0xef, 0xe2, 0xbd, + 0x6f, 0x2c, 0x8b, 0x93, 0x30, 0x14, 0x28, 0xe6, 0x64, 0x84, 0x0d, 0x70, 0xe6, 0x63, 0xd4, 0x82, + 0x0c, 0x11, 0x0a, 0x32, 0xd4, 0x57, 0x40, 0x5c, 0x0a, 0x76, 0x64, 0x8a, 0x0e, 0x41, 0x1b, 0x8f, + 0x5c, 0x9b, 0x62, 0xd7, 0x92, 0xa2, 0xb0, 0x94, 0xbc, 0x9d, 0xbc, 0x26, 0xdc, 0x86, 0xc4, 0x88, + 0x8e, 0x8a, 0x1e, 0xc0, 0x86, 0x8f, 0xcf, 0x69, 0x84, 0xc9, 0x3a, 0x29, 0xc5, 0x3b, 0xa9, 0x3c, + 0x9b, 0x56, 0x0a, 0x5d, 0x7c, 0x4e, 0xa5, 0x2a, 0xef, 0xa7, 0xec, 0x7c, 0x62, 0x14, 0xfc, 0xd8, + 0x9a, 0xbb, 0xa7, 0x32, 0x5e, 0xe4, 0xc4, 0xf4, 0x85, 0x02, 0x5b, 0x9d, 0xc0, 0xf5, 0x4e, 0x3c, + 0xec, 0x32, 0xbe, 0x8d, 0xa2, 0xf9, 0x21, 0xa0, 0x70, 0x12, 0x52, 0x3c, 0xb4, 0x9c, 0xc0, 0x3f, + 0xf1, 0xfa, 0x56, 0x38, 0xb2, 0x7d, 0x1e, 0x54, 0xd5, 0xd0, 0xc4, 0x4a, 0x93, 0x2f, 0x70, 0x92, + 0x6e, 0x03, 0xe2, 0x4c, 0x30, 0xf0, 0xce, 0xb0, 0x8f, 0xc3, 0x50, 0x68, 0x8b, 0xf8, 0xdd, 0x5a, + 0x72, 0x60, 0x66, 0x64, 0x68, 0xcc, 0x64, 0x5f, 0x5a, 0x30, 0x89, 0xe4, 0xca, 0x7f, 0x26, 0x60, + 0x5b, 0xf7, 0x29, 0x26, 0xbe, 0x3d, 0x68, 0x06, 0xc3, 0xe1, 0xa2, 0xfb, 0x5b, 0x50, 0x08, 0x19, + 0x1b, 0x58, 0x54, 0x08, 0x64, 0x53, 0x55, 0x96, 0xee, 0xb0, 0x60, 0x0d, 0x23, 0x1f, 0xc6, 0x39, + 0xa4, 0x05, 0x85, 0x21, 0x6b, 0xd3, 0x39, 0x4a, 0xe2, 0xad, 0x28, 0xf1, 0x76, 0x36, 0xf2, 0xc3, + 0x78, 0x73, 0xff, 0x14, 0x6e, 0xc9, 0x72, 0x8b, 0x12, 0x3c, 0xc7, 0x4b, 0x72, 0xbc, 0x3b, 0x4b, + 0xf0, 0x96, 0x56, 0xae, 0xb1, 0xed, 0x2c, 0x2d, 0xe8, 0xe7, 0xb0, 0x3d, 0x94, 0x99, 0xe1, 0xf1, + 0x9c, 0xe3, 0x8b, 0x9e, 0xfd, 0xe6, 0x32, 0x7f, 0x2f, 0x67, 0xd2, 0xd8, 0x1a, 0x5e, 0x16, 0xee, + 0xa9, 0x9f, 0xcb, 0x4b, 0xb1, 0xfa, 0x73, 0x05, 0x36, 0x0f, 0x8e, 0x43, 0x4c, 0xce, 0xb0, 0x3b, + 0xef, 0xc2, 0x38, 0xb5, 0x2b, 0x2b, 0x50, 0xfb, 0xff, 0xe1, 0x9e, 0x54, 0xa3, 0x6b, 0xba, 0xfa, + 0xe7, 0x75, 0xc8, 0x99, 0xc4, 0xf6, 0x43, 0xdb, 0xa1, 0x5e, 0xe0, 0xa3, 0x47, 0x90, 0x62, 0x8f, + 0x12, 0x99, 0xec, 0xbb, 0x2b, 0x50, 0x95, 0x79, 0xee, 0x77, 0x30, 0xb5, 0x1b, 0x2a, 0xdb, 0xe4, + 0xcb, 0x69, 0x45, 0x31, 0x38, 0x02, 0x42, 0x90, 0xf2, 0xed, 0xa1, 0xb8, 0x5d, 0xb3, 0x06, 0x1f, + 0xa3, 0x1f, 0xc1, 0x3a, 0x63, 0xc2, 0xb1, 0xa0, 0xc2, 0xe5, 0x8c, 0x11, 0xf3, 0xa6, 0xc7, 0x75, + 0x0d, 0x69, 0x83, 0x1e, 0x43, 0x71, 0x60, 0x87, 0xd4, 0x3a, 0xc5, 0x36, 0xa1, 0xc7, 0xd8, 0xbe, + 0x16, 0xc9, 0x15, 0x98, 0xe9, 0xa3, 0xc8, 0x92, 0x61, 0x05, 0xc4, 0xeb, 0x5b, 0x8b, 0x48, 0xae, + 0x5f, 0x03, 0x8b, 0x99, 0x2e, 0xf2, 0xf7, 0x08, 0x0a, 0x43, 0xfb, 0x3c, 0x06, 0x95, 0x59, 0x1d, + 0x2a, 0x3f, 0xb4, 0xcf, 0x17, 0x48, 0x9f, 0xc0, 0x56, 0x20, 0xcb, 0x63, 0x01, 0x17, 0x96, 0xd4, + 0xb7, 0x92, 0xd9, 0xa5, 0x62, 0x92, 0xb0, 0x28, 0xf8, 0xef, 0x85, 0x10, 0x95, 0x20, 0xf3, 0x92, + 0x78, 0xd4, 0xf3, 0xfb, 0xa5, 0x2c, 0xa7, 0x96, 0x68, 0x8a, 0xbe, 0x0f, 0x19, 0xcf, 0xa7, 0xd8, + 0xa7, 0x61, 0x29, 0xc7, 0xb7, 0x7a, 0x1b, 0x8d, 0x44, 0xcc, 0x2b, 0xb5, 0x51, 0x15, 0x0a, 0x0c, + 0x03, 0x5b, 0x34, 0x08, 0xac, 0x60, 0xe0, 0x96, 0xf2, 0x1c, 0x38, 0xc7, 0x85, 0x66, 0x10, 0x1c, + 0x0c, 0x5c, 0x74, 0x08, 0x37, 0xf0, 0x28, 0x70, 0x4e, 0xad, 0xcf, 0x30, 0x09, 0x62, 0x41, 0x2a, + 0xae, 0x1e, 0x24, 0xc4, 0x01, 0x9e, 0x63, 0x12, 0x2c, 0x42, 0x65, 0xc2, 0x16, 0xc1, 0x27, 0x04, + 0x87, 0xa7, 0xf1, 0x58, 0x95, 0x36, 0xae, 0x81, 0x3a, 0xb7, 0x5f, 0xa0, 0xfe, 0x18, 0xde, 0xbb, + 0x58, 0x16, 0xd6, 0x4b, 0x3b, 0xb4, 0xa2, 0x60, 0x96, 0x34, 0x7e, 0xbc, 0xd2, 0x85, 0xf4, 0x3f, + 0xb3, 0xc3, 0x28, 0x0b, 0x97, 0x9e, 0xc0, 0x05, 0xad, 0x58, 0xfd, 0x9d, 0x02, 0xeb, 0x3a, 0x8f, + 0x17, 0xfa, 0x2e, 0xa4, 0xe6, 0xcc, 0x7e, 0x45, 0x90, 0x63, 0x9d, 0xc4, 0xd4, 0x51, 0x03, 0x92, + 0xf4, 0x3c, 0x62, 0xf8, 0xeb, 0xb4, 0xa4, 0x38, 0x27, 0x33, 0x8e, 0x75, 0x5e, 0xf2, 0xfa, 0x9d, + 0x27, 0xef, 0x8a, 0x87, 0x50, 0xec, 0xe1, 0x9f, 0x8d, 0xb1, 0xef, 0x60, 0xf7, 0x19, 0xcb, 0xf0, + 0x55, 0xaf, 0xeb, 0x1d, 0x50, 0x43, 0xa9, 0x2c, 0x1e, 0xac, 0xc6, 0x7c, 0x5e, 0xfd, 0x77, 0x12, + 0xd2, 0xfb, 0xd8, 0x0e, 0x31, 0xfa, 0x21, 0xa4, 0xc5, 0x73, 0x45, 0x59, 0x3d, 0x6f, 0xc2, 0x02, + 0x7d, 0x0a, 0x80, 0xcf, 0x47, 0x1e, 0xb1, 0x99, 0xbf, 0xab, 0xf1, 0x60, 0xf9, 0x5f, 0xd3, 0xca, + 0x4e, 0xec, 0x25, 0xbe, 0x57, 0x25, 0xb6, 0xef, 0xfa, 0xe3, 0xc1, 0xc0, 0x3e, 0x1e, 0xe0, 0xaa, + 0x11, 0x03, 0x8c, 0x3f, 0x4d, 0x92, 0xff, 0xfb, 0xd3, 0x64, 0x0c, 0xb7, 0x5c, 0x3c, 0x22, 0xd8, + 0xe1, 0xaf, 0x13, 0xee, 0x38, 0xfb, 0x1b, 0x7a, 0xd1, 0x63, 0xf0, 0x1d, 0x3d, 0xde, 0x5e, 0xa0, + 0xf3, 0xe7, 0x5b, 0x8f, 0x63, 0xa3, 0x2e, 0xe4, 0x46, 0x24, 0x18, 0x05, 0x21, 0xeb, 0x8d, 0x70, + 0x35, 0x9a, 0x2c, 0xce, 0xa6, 0x15, 0x78, 0x2a, 0xad, 0xcc, 0x9e, 0x01, 0x11, 0x82, 0x19, 0xa2, + 0x1b, 0x90, 0xe6, 0x2d, 0xc8, 0x49, 0x32, 0x69, 0x88, 0x09, 0xfa, 0x28, 0x96, 0x62, 0x46, 0x79, + 0xc9, 0xc6, 0xe6, 0x9b, 0x69, 0xa5, 0xc0, 0x33, 0x1b, 0x15, 0xca, 0x22, 0xeb, 0xe2, 0x1d, 0xc4, + 0x9a, 0xa3, 0xfa, 0x0b, 0x05, 0x8a, 0xf5, 0xe3, 0x80, 0x50, 0x56, 0xee, 0x6d, 0x9f, 0x92, 0xc9, + 0x55, 0x95, 0xf4, 0xee, 0xf7, 0x1d, 0x2b, 0xc6, 0x11, 0xf1, 0x02, 0xe2, 0x51, 0xf1, 0x71, 0x9b, + 0x36, 0xe6, 0xf3, 0xd8, 0x5d, 0xf8, 0x8f, 0x24, 0xe4, 0xcd, 0x73, 0xbf, 0x19, 0x04, 0xc4, 0x65, + 0xfd, 0x83, 0xbe, 0x27, 0x1a, 0x4f, 0xd4, 0x66, 0xf9, 0xea, 0x8e, 0x89, 0x37, 0x5b, 0x8c, 0x4f, + 0x13, 0xd7, 0xe2, 0xd3, 0x0f, 0xa0, 0xe0, 0x04, 0xc3, 0xa1, 0xed, 0xbb, 0x96, 0x13, 0x8c, 0x7d, + 0x2a, 0x9d, 0xcd, 0x4b, 0x61, 0x93, 0xc9, 0x50, 0x03, 0x0a, 0x92, 0xb9, 0x2c, 0x82, 0x6d, 0x97, + 0x55, 0xd2, 0x0a, 0x7b, 0xe4, 0xa5, 0x8d, 0xc1, 0x4c, 0x50, 0x0b, 0x8a, 0x11, 0x06, 0xe7, 0x6a, + 0x56, 0x23, 0x2b, 0x80, 0x44, 0x1b, 0xf3, 0xee, 0x0f, 0xd1, 0x0f, 0xa0, 0x14, 0xab, 0xee, 0x08, + 0xf0, 0xcc, 0x1e, 0x78, 0x2e, 0xaf, 0x14, 0xd5, 0xb8, 0xb9, 0x58, 0x37, 0xc4, 0xf2, 0x11, 0x5b, + 0x45, 0xdf, 0x82, 0x8d, 0x48, 0xdd, 0xf3, 0x85, 0x41, 0x86, 0x1b, 0x44, 0x6e, 0xe9, 0x42, 0x8a, + 0x8e, 0x00, 0x05, 0x63, 0x1a, 0x52, 0xdb, 0x77, 0x3d, 0xbf, 0x1f, 0x39, 0x2b, 0x2e, 0xc4, 0xf7, + 0x97, 0x39, 0x7b, 0x81, 0xa0, 0xa4, 0xdb, 0x9b, 0x31, 0x08, 0xe1, 0xfa, 0xdd, 0xdf, 0x28, 0x90, + 0xe5, 0x5f, 0xf7, 0xfc, 0x3b, 0x24, 0x07, 0x99, 0xc3, 0xee, 0x93, 0xee, 0xc1, 0xb3, 0xae, 0xb6, + 0x86, 0x32, 0x90, 0xd4, 0xbb, 0xa6, 0xa6, 0xa0, 0x2c, 0xa4, 0x1f, 0xec, 0x1f, 0xd4, 0x4d, 0x2d, + 0xc1, 0x86, 0x8d, 0x8f, 0xcd, 0x76, 0x4f, 0x4b, 0xa2, 0x2d, 0xd8, 0x68, 0xb5, 0xf7, 0xf5, 0x8e, + 0x6e, 0xb6, 0x5b, 0x96, 0x10, 0xaa, 0x48, 0x85, 0x94, 0xa9, 0x77, 0xda, 0x5a, 0x8a, 0x41, 0xb5, + 0xda, 0x4d, 0xbd, 0x53, 0xdf, 0xd7, 0xd2, 0x68, 0x1b, 0x36, 0x17, 0xba, 0x91, 0x38, 0x8b, 0xf2, + 0xa0, 0xb6, 0x0e, 0x8d, 0xba, 0xa9, 0x1f, 0x74, 0xb5, 0x75, 0x86, 0x6d, 0x1e, 0x3e, 0xdd, 0x6f, + 0x6b, 0xc0, 0x16, 0x1a, 0xba, 0x59, 0x37, 0x8c, 0xfa, 0xc7, 0x5a, 0x0e, 0x15, 0x01, 0x18, 0x68, + 0xaf, 0x6d, 0xe8, 0xed, 0x9e, 0xe6, 0x56, 0x53, 0x6a, 0x46, 0xcb, 0xdc, 0xfd, 0x09, 0x6c, 0x5e, + 0xfa, 0xa8, 0x42, 0x1b, 0x90, 0xab, 0xb7, 0x5a, 0x96, 0xd1, 0x7e, 0xba, 0xaf, 0x37, 0xeb, 0xda, + 0x1a, 0x42, 0x50, 0x34, 0xda, 0x9d, 0x83, 0xa3, 0xf6, 0x5c, 0xa6, 0xec, 0xa4, 0x3e, 0xff, 0x55, + 0x79, 0xed, 0x6e, 0x03, 0x36, 0x2f, 0x11, 0x3d, 0xf3, 0xfa, 0x69, 0xbb, 0xdb, 0xd2, 0xbb, 0x0f, + 0xb5, 0x35, 0x54, 0x80, 0x6c, 0xf3, 0xa0, 0xd3, 0xd1, 0x4d, 0xb3, 0xdd, 0xd2, 0x14, 0xb6, 0x56, + 0x6f, 0x1c, 0x18, 0x6c, 0x92, 0x10, 0x18, 0x8d, 0xf7, 0x5f, 0xff, 0xb5, 0xbc, 0xf6, 0x7a, 0x56, + 0x56, 0xbe, 0x9c, 0x95, 0x95, 0x3f, 0xce, 0xca, 0xca, 0x5f, 0x66, 0x65, 0xe5, 0x8b, 0xbf, 0x95, + 0xd7, 0x9e, 0x67, 0x64, 0x22, 0x8e, 0xd7, 0xf9, 0x2f, 0x4b, 0xf7, 0xff, 0x13, 0x00, 0x00, 0xff, + 0xff, 0x3c, 0xb1, 0x20, 0x5b, 0x13, 0x13, 0x00, 0x00, } diff --git a/pkg/roachpb/data.proto b/pkg/roachpb/data.proto index f75333b88337..ae37430748b0 100644 --- a/pkg/roachpb/data.proto +++ b/pkg/roachpb/data.proto @@ -238,11 +238,10 @@ message ObservedTimestamp { } // A Transaction is a unit of work performed on the database. -// Cockroach transactions support two isolation levels: snapshot -// isolation and serializable snapshot isolation. Each Cockroach -// transaction is assigned a random priority. This priority will be -// used to decide whether a transaction will be aborted during -// contention. +// Cockroach transactions always operate at the serializable isolation +// level. Each Cockroach transaction is assigned a random priority. +// This priority will be used to decide whether a transaction will be +// aborted during contention. // // If you add fields to Transaction you'll need to update // Transaction.Clone. Failure to do so will result in test failures. @@ -376,12 +375,7 @@ message Transaction { // error so that intents can continue to be laid down, minimizing // work required on txn restart. bool write_too_old = 12; - // If retry_on_push is true, the transaction must retry in the event - // that the commit timestamp is pushed forward. This flag is set if - // the transaction contains any calls to DeleteRange, in order to - // prevent the LostDeleteRange anomaly. This flag is relevant only - // for SNAPSHOT transactions. - bool retry_on_push = 13; + reserved 13; repeated Span intents = 11 [(gogoproto.nullable) = false]; // Epoch zero timestamp is used to keep track of the earliest timestamp // that any epoch of the transaction used. This is set only if the diff --git a/pkg/roachpb/data_test.go b/pkg/roachpb/data_test.go index d5b34bec9333..cd0dd1670920 100644 --- a/pkg/roachpb/data_test.go +++ b/pkg/roachpb/data_test.go @@ -386,7 +386,7 @@ func TestSetGetChecked(t *testing.T) { func TestTransactionBumpEpoch(t *testing.T) { origNow := makeTS(10, 1) - txn := MakeTransaction("test", Key("a"), 1, enginepb.SERIALIZABLE, origNow, 0) + txn := MakeTransaction("test", Key("a"), 1, origNow, 0) // Advance the txn timestamp. txn.Timestamp.Add(10, 2) txn.BumpEpoch() @@ -407,7 +407,7 @@ func TestTransactionInclusiveTimeBounds(t *testing.T) { } } origNow := makeTS(1, 1) - txn := MakeTransaction("test", Key("a"), 1, enginepb.SERIALIZABLE, origNow, 0) + txn := MakeTransaction("test", Key("a"), 1, origNow, 0) verify(txn, origNow, origNow) txn.Timestamp.Forward(makeTS(1, 2)) verify(txn, origNow, makeTS(1, 2)) @@ -475,7 +475,6 @@ func TestFastPathObservedTimestamp(t *testing.T) { var nonZeroTxn = Transaction{ TxnMeta: enginepb.TxnMeta{ - Isolation: enginepb.SNAPSHOT, Key: Key("foo"), ID: uuid.MakeV4(), Epoch: 2, @@ -492,7 +491,6 @@ var nonZeroTxn = Transaction{ ObservedTimestamps: []ObservedTimestamp{{NodeID: 1, Timestamp: makeTS(1, 2)}}, Writing: true, WriteTooOld: true, - RetryOnPush: true, Intents: []Span{{Key: []byte("a"), EndKey: []byte("b")}}, EpochZeroTimestamp: makeTS(1, 1), OrigTimestampWasObserved: true, @@ -514,7 +512,6 @@ func TestTransactionUpdate(t *testing.T) { var txn3 Transaction txn3.ID = uuid.MakeV4() txn3.Name = "carl" - txn3.Isolation = enginepb.SNAPSHOT txn3.Update(&txn) if err := zerofields.NoZeroField(txn3); err != nil { diff --git a/pkg/roachpb/errors.pb.go b/pkg/roachpb/errors.pb.go index 9bdaeb5d6217..5dab9cefa22b 100644 --- a/pkg/roachpb/errors.pb.go +++ b/pkg/roachpb/errors.pb.go @@ -116,9 +116,6 @@ const ( RETRY_REASON_UNKNOWN TransactionRetryReason = 0 // A concurrent writer finished first, causing restart. RETRY_WRITE_TOO_OLD TransactionRetryReason = 1 - // A transaction containing a delete range command had its timestamp - // moved forward. - RETRY_DELETE_RANGE TransactionRetryReason = 2 // A SERIALIZABLE transaction had its timestamp moved forward. RETRY_SERIALIZABLE TransactionRetryReason = 3 // A possible replay caused by duplicate begin txn or out-of-order @@ -131,7 +128,6 @@ const ( var TransactionRetryReason_name = map[int32]string{ 0: "RETRY_REASON_UNKNOWN", 1: "RETRY_WRITE_TOO_OLD", - 2: "RETRY_DELETE_RANGE", 3: "RETRY_SERIALIZABLE", 4: "RETRY_POSSIBLE_REPLAY", 5: "RETRY_ASYNC_WRITE_FAILURE", @@ -139,7 +135,6 @@ var TransactionRetryReason_name = map[int32]string{ var TransactionRetryReason_value = map[string]int32{ "RETRY_REASON_UNKNOWN": 0, "RETRY_WRITE_TOO_OLD": 1, - "RETRY_DELETE_RANGE": 2, "RETRY_SERIALIZABLE": 3, "RETRY_POSSIBLE_REPLAY": 4, "RETRY_ASYNC_WRITE_FAILURE": 5, @@ -9509,179 +9504,178 @@ var ( func init() { proto.RegisterFile("roachpb/errors.proto", fileDescriptorErrors) } var fileDescriptorErrors = []byte{ - // 2771 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0xcd, 0x73, 0xdb, 0xc6, - 0x15, 0x27, 0x24, 0x4a, 0x94, 0x9e, 0xbe, 0xa0, 0xb5, 0x22, 0xc3, 0x72, 0x4c, 0xd9, 0x72, 0x3e, - 0x9c, 0x74, 0x22, 0x75, 0x9c, 0x7a, 0x3a, 0x71, 0x93, 0x03, 0x3f, 0x20, 0x11, 0x12, 0x3f, 0x14, - 0x90, 0x8a, 0xe3, 0xa4, 0x1d, 0x0c, 0x44, 0xac, 0x28, 0xc4, 0x24, 0xc0, 0x2e, 0x00, 0x8b, 0xba, - 0xf5, 0x98, 0x5b, 0xdb, 0x5b, 0x6f, 0xcd, 0x4c, 0x7b, 0xe9, 0xf4, 0xda, 0xc9, 0xa5, 0xff, 0x40, - 0x8e, 0x3d, 0x66, 0x3a, 0x13, 0x4f, 0xeb, 0x5e, 0x3a, 0xd3, 0xff, 0xc0, 0xa7, 0xce, 0x7e, 0x00, - 0x04, 0x49, 0x80, 0x61, 0x72, 0x22, 0xf1, 0xbe, 0xf6, 0xed, 0xdb, 0xb7, 0xef, 0xfd, 0xde, 0xc2, - 0x16, 0x71, 0xcd, 0xf6, 0x65, 0xff, 0xfc, 0x00, 0x13, 0xe2, 0x12, 0x6f, 0xbf, 0x4f, 0x5c, 0xdf, - 0x45, 0x9b, 0x6d, 0xb7, 0xfd, 0x8c, 0x71, 0xf6, 0x05, 0x7f, 0x07, 0x85, 0x82, 0x96, 0xe9, 0x9b, - 0x5c, 0x6c, 0x67, 0x3b, 0xa4, 0xf5, 0xb0, 0x6f, 0xc6, 0xe8, 0xf7, 0x3d, 0xdf, 0x25, 0x66, 0x07, - 0x1f, 0x60, 0xa7, 0x63, 0x3b, 0xe1, 0x0f, 0x95, 0x7b, 0xde, 0x6e, 0xbf, 0x2f, 0x84, 0x94, 0xc0, - 0xb7, 0xbb, 0x07, 0x97, 0xdd, 0xf6, 0x81, 0x6f, 0xf7, 0xb0, 0xe7, 0x9b, 0xbd, 0xbe, 0xe0, 0x6c, - 0x75, 0xdc, 0x8e, 0xcb, 0xfe, 0x1e, 0xd0, 0x7f, 0x9c, 0xba, 0xf7, 0xf5, 0x1c, 0xdc, 0xa8, 0xbb, - 0x7e, 0x15, 0x9b, 0x1e, 0xae, 0xb8, 0x5d, 0x0b, 0x13, 0x95, 0xba, 0x8c, 0xca, 0x90, 0x23, 0xb8, - 0xdf, 0xb5, 0xdb, 0xa6, 0x22, 0xdd, 0x95, 0x1e, 0xac, 0x3c, 0x7c, 0x63, 0x7f, 0xc2, 0xfb, 0x7d, - 0x9d, 0x4b, 0x94, 0xb1, 0xd7, 0x26, 0x76, 0xdf, 0x77, 0x49, 0x31, 0xfb, 0xcd, 0x8b, 0xdd, 0x8c, - 0x1e, 0xaa, 0xa2, 0x23, 0x58, 0xed, 0x52, 0xcb, 0xc6, 0x25, 0x33, 0xad, 0xcc, 0xcd, 0x6e, 0x4a, - 0x5f, 0xe9, 0x0e, 0x7d, 0x42, 0x8f, 0x60, 0x89, 0x98, 0x4e, 0x07, 0x1b, 0xb6, 0xa5, 0xcc, 0xdf, - 0x95, 0x1e, 0xcc, 0x17, 0x77, 0xe8, 0x4a, 0x2f, 0x5f, 0xec, 0xe6, 0x74, 0x4a, 0xd7, 0xca, 0xaf, - 0x86, 0x7f, 0xf5, 0x1c, 0x93, 0xd5, 0x2c, 0xb4, 0x0f, 0x0b, 0xcc, 0x8a, 0x92, 0x65, 0x0b, 0x2b, - 0x09, 0x0b, 0xb3, 0x9d, 0xeb, 0x5c, 0x0c, 0xdd, 0x07, 0x68, 0x07, 0x9e, 0xef, 0xf6, 0x8c, 0x9e, - 0xd7, 0x51, 0x16, 0xee, 0x4a, 0x0f, 0x96, 0xc5, 0x96, 0x96, 0x39, 0xbd, 0xe6, 0x75, 0x1e, 0x67, - 0xff, 0xfb, 0xd5, 0xae, 0xb4, 0xf7, 0x3a, 0x6c, 0xd5, 0x5d, 0x0b, 0x9f, 0x39, 0xe6, 0x73, 0xd3, - 0xee, 0x9a, 0xe7, 0x5d, 0xcc, 0x02, 0x27, 0xb8, 0xbb, 0x70, 0xf3, 0xcc, 0xf1, 0x82, 0x7e, 0xdf, - 0x25, 0x3e, 0xb6, 0x74, 0xfc, 0xeb, 0x00, 0x7b, 0x7e, 0x5c, 0xe0, 0x4b, 0x09, 0x10, 0x73, 0xb7, - 0xee, 0xfa, 0x87, 0x6e, 0xe0, 0x58, 0x3c, 0xec, 0xf1, 0x7d, 0x4a, 0xb3, 0xef, 0xf3, 0x11, 0x2c, - 0xd1, 0xe4, 0x60, 0x6a, 0x73, 0xa3, 0x6a, 0x4d, 0x4a, 0xe7, 0x6a, 0xe2, 0xaf, 0x9e, 0x63, 0xb2, - 0x9a, 0x25, 0x5c, 0xf9, 0xe3, 0x1c, 0xbc, 0xc6, 0x2c, 0x9e, 0xe0, 0xeb, 0x9a, 0xed, 0xf5, 0x4c, - 0xbf, 0x7d, 0xc9, 0xbd, 0x79, 0x1f, 0x36, 0x09, 0x77, 0xdd, 0xf0, 0x7c, 0x93, 0xf8, 0xc6, 0x33, - 0x7c, 0xcd, 0xdc, 0x5a, 0x2d, 0xe6, 0x5e, 0xbd, 0xd8, 0x9d, 0x3f, 0xc1, 0xd7, 0xfa, 0x86, 0x90, - 0x68, 0x52, 0x81, 0x13, 0x7c, 0x8d, 0x0e, 0x20, 0x24, 0x19, 0xd8, 0xb1, 0x98, 0xca, 0xdc, 0xa8, - 0xca, 0x9a, 0xe0, 0xab, 0x8e, 0x45, 0x15, 0x6a, 0x20, 0xf7, 0xc4, 0xb2, 0xd8, 0x32, 0xd8, 0x96, - 0xd8, 0x19, 0xaf, 0x3c, 0xdc, 0x4b, 0x4a, 0x14, 0xca, 0x8f, 0xa5, 0xc9, 0xc6, 0x50, 0x97, 0xb1, - 0xd0, 0x09, 0x6c, 0x78, 0x41, 0xa7, 0x83, 0x3d, 0x3f, 0xb2, 0x96, 0x9d, 0xd9, 0xda, 0x7a, 0xa4, - 0xca, 0x38, 0x22, 0x42, 0xff, 0x9b, 0x83, 0x3d, 0x1d, 0x9b, 0xd6, 0x13, 0xdb, 0xbf, 0xb4, 0x9d, - 0x33, 0xa7, 0x8d, 0x89, 0x6f, 0xda, 0x8e, 0x7f, 0xad, 0x39, 0x3e, 0x26, 0xcf, 0xcd, 0x2e, 0x0f, - 0xd7, 0x31, 0xac, 0x13, 0x6c, 0x5a, 0x46, 0x74, 0xf3, 0xc4, 0xd5, 0xb9, 0x13, 0x5b, 0x98, 0x5e, - 0xcf, 0xfd, 0xcb, 0x6e, 0x7b, 0xbf, 0x15, 0x0a, 0x89, 0x04, 0x5b, 0xa3, 0xaa, 0x11, 0x11, 0xe9, - 0x80, 0xf0, 0xc0, 0xf6, 0x7c, 0xdb, 0xe9, 0xc4, 0xec, 0xcd, 0xcd, 0x6e, 0x6f, 0x33, 0x54, 0x1f, - 0xda, 0x2c, 0xc2, 0x5a, 0xcf, 0x1c, 0xc4, 0xcc, 0xcd, 0xcf, 0x60, 0x4e, 0x5f, 0xed, 0x99, 0x83, - 0xa1, 0x8d, 0xcf, 0xe1, 0x86, 0x7b, 0xee, 0x61, 0xf2, 0x1c, 0xc7, 0xf6, 0xe9, 0x29, 0xd9, 0xbb, - 0xf3, 0x29, 0x17, 0xbb, 0x21, 0xa4, 0xc7, 0xfd, 0x43, 0xee, 0x38, 0xc3, 0x13, 0xd1, 0xfe, 0x02, - 0x6e, 0xb6, 0x88, 0xe9, 0x78, 0x66, 0xdb, 0xb7, 0x5d, 0xa7, 0x70, 0xce, 0xae, 0x10, 0x8f, 0xb0, - 0x06, 0x8b, 0x04, 0x9b, 0x9e, 0xeb, 0xb0, 0xc8, 0xae, 0x3f, 0xfc, 0x49, 0xc2, 0x82, 0x93, 0xba, - 0x3a, 0x53, 0x11, 0xeb, 0x0a, 0x03, 0x62, 0x2d, 0x13, 0xb6, 0x62, 0xf2, 0xa7, 0x81, 0x27, 0x32, - 0xbf, 0x04, 0xd0, 0x0f, 0xbc, 0x4b, 0x8c, 0x0d, 0x7f, 0xe0, 0x88, 0x63, 0xcc, 0x4f, 0x5f, 0x2c, - 0x2c, 0x14, 0x5c, 0xaf, 0x35, 0x08, 0x97, 0xb8, 0x80, 0xd7, 0x62, 0x52, 0x3a, 0xf6, 0xc9, 0x35, - 0x5f, 0xe3, 0x68, 0x6c, 0x33, 0xef, 0x4c, 0xb7, 0xcf, 0x34, 0xa7, 0x6c, 0xe5, 0x5b, 0x09, 0xb6, - 0x63, 0xe2, 0x4d, 0xdf, 0xf4, 0x03, 0x8f, 0xaf, 0xb4, 0x0d, 0xf3, 0xb4, 0x9e, 0x49, 0xb1, 0x7a, - 0x46, 0x09, 0xa8, 0x1e, 0x79, 0x30, 0xc7, 0x3c, 0xf8, 0xe9, 0x74, 0x0f, 0x62, 0x26, 0xf7, 0x93, - 0x1c, 0xd9, 0x3b, 0x85, 0x45, 0x4e, 0x47, 0x08, 0xd6, 0x75, 0xb5, 0xd0, 0x6c, 0xd4, 0x8d, 0xb3, - 0xfa, 0x49, 0xbd, 0xf1, 0xa4, 0x2e, 0x67, 0x90, 0x02, 0x5b, 0x82, 0xd6, 0xfa, 0xb4, 0x6e, 0xd4, - 0x1b, 0x2d, 0xe3, 0xb0, 0x71, 0x56, 0x2f, 0xcb, 0xd2, 0x18, 0xa7, 0xd4, 0xa8, 0xd5, 0xb4, 0x56, - 0x4b, 0x2d, 0xcb, 0x73, 0x62, 0x6b, 0x4f, 0x41, 0x7e, 0x42, 0x6c, 0x1f, 0xd3, 0xeb, 0xe6, 0xf0, - 0x32, 0x8a, 0x3e, 0x80, 0x9c, 0xcd, 0x3e, 0x3d, 0x45, 0x62, 0xc9, 0x77, 0x2b, 0xc1, 0x79, 0xae, - 0x10, 0x76, 0x25, 0x21, 0xcf, 0x8d, 0x1e, 0x67, 0x97, 0xe6, 0xe4, 0xf9, 0xbd, 0xbf, 0x4a, 0xc2, - 0x76, 0xcb, 0x75, 0x1b, 0x5d, 0x91, 0x66, 0x05, 0x58, 0xfe, 0x51, 0x77, 0x78, 0xa8, 0x85, 0xea, - 0x20, 0x9b, 0x6d, 0x3f, 0x30, 0xbb, 0x3f, 0xee, 0xf6, 0x6e, 0x70, 0xe5, 0x88, 0x2c, 0x02, 0xb1, - 0x03, 0xa8, 0xd1, 0xa7, 0xdd, 0xc4, 0x26, 0xd8, 0x6b, 0x0d, 0x9c, 0x78, 0x47, 0x79, 0x0a, 0x5b, - 0x25, 0xd7, 0xb1, 0x6c, 0x7a, 0x52, 0x87, 0xa6, 0xdd, 0x0d, 0xef, 0xcc, 0x2f, 0x60, 0x55, 0x78, - 0xf2, 0xdc, 0xec, 0x06, 0x58, 0xec, 0x27, 0xa9, 0x15, 0x7e, 0x42, 0xf9, 0xfa, 0x0a, 0x97, 0x66, - 0x1f, 0xc2, 0xf4, 0xdf, 0x24, 0x40, 0xbc, 0x4f, 0xe2, 0x2f, 0x70, 0x3b, 0xba, 0x8d, 0x79, 0xc8, - 0xf5, 0xb0, 0xe7, 0x99, 0x1d, 0x3c, 0x92, 0x5a, 0x21, 0x11, 0x7d, 0x08, 0xcb, 0xa2, 0xd2, 0x63, - 0x4b, 0x6c, 0x3e, 0xb5, 0x03, 0x87, 0x11, 0x8c, 0x14, 0xd0, 0x63, 0x58, 0x0a, 0x4b, 0x98, 0x28, - 0x54, 0xdf, 0xa7, 0x1c, 0xc9, 0x0b, 0xb7, 0x7f, 0x0e, 0xcb, 0x4d, 0xec, 0xcc, 0xe6, 0xec, 0x48, - 0x52, 0x5c, 0xc1, 0x56, 0xa1, 0x77, 0x6e, 0x77, 0x02, 0x37, 0xf0, 0x74, 0xec, 0x05, 0x5d, 0x7f, - 0xb6, 0x0d, 0x7f, 0x00, 0x2b, 0x57, 0xc4, 0xec, 0xf7, 0xb1, 0x65, 0x60, 0x42, 0xa6, 0x6c, 0x99, - 0x99, 0xd3, 0x41, 0x08, 0xab, 0x24, 0x3c, 0xc3, 0x3b, 0xb4, 0x13, 0x5f, 0xf8, 0x47, 0xc4, 0x0d, - 0xfa, 0x65, 0xdc, 0xc5, 0x61, 0xa8, 0x05, 0x1b, 0xc3, 0xb6, 0xc0, 0x49, 0x25, 0x97, 0x90, 0xa0, - 0x4f, 0x8f, 0x9a, 0x7b, 0x76, 0x0f, 0x96, 0x19, 0xd4, 0x34, 0xc6, 0xef, 0xf9, 0x12, 0x23, 0xd7, - 0xbc, 0x0e, 0xda, 0x83, 0xe5, 0x3e, 0x71, 0xdb, 0xd8, 0xf3, 0xc4, 0x69, 0x2c, 0x45, 0x15, 0x2b, - 0x24, 0x47, 0x99, 0x84, 0xc4, 0x32, 0xf1, 0x4b, 0xf1, 0x11, 0x80, 0x80, 0x75, 0x21, 0x38, 0x59, - 0x28, 0xe6, 0x05, 0xca, 0x58, 0x16, 0xf2, 0x0c, 0x67, 0x0c, 0x3f, 0xe8, 0x71, 0xf2, 0xbf, 0xa1, - 0xe9, 0x8f, 0x01, 0x31, 0x14, 0x32, 0x81, 0x7a, 0x22, 0xf8, 0x22, 0xfd, 0x50, 0xf8, 0x52, 0xa3, - 0x50, 0xeb, 0xd2, 0x74, 0xac, 0x2e, 0xad, 0xf4, 0x3e, 0xb9, 0x8e, 0xb0, 0x18, 0x7a, 0x08, 0xd9, - 0xbe, 0x4a, 0xc8, 0x94, 0x94, 0x67, 0x72, 0x22, 0x0e, 0x4c, 0x76, 0xef, 0x3b, 0x09, 0x94, 0xca, - 0x98, 0xb5, 0xf0, 0xa6, 0xa5, 0x16, 0xd2, 0xcf, 0x61, 0xd1, 0x1f, 0x38, 0x21, 0xfa, 0x5a, 0x2d, - 0x96, 0x29, 0xeb, 0x9f, 0x2f, 0x76, 0xdf, 0xef, 0xd8, 0xfe, 0x65, 0x70, 0xbe, 0xdf, 0x76, 0x7b, - 0x07, 0xd1, 0xe2, 0xd6, 0xf9, 0xf0, 0xff, 0x41, 0xff, 0x59, 0xe7, 0x80, 0x41, 0xf6, 0x20, 0xb0, - 0xad, 0xfd, 0xb3, 0x33, 0xad, 0xfc, 0xf2, 0xc5, 0xee, 0x42, 0x6b, 0xe0, 0x68, 0x65, 0x7d, 0xc1, - 0x1f, 0x38, 0x9a, 0x85, 0x0e, 0x61, 0xc5, 0x1f, 0x16, 0x61, 0x71, 0x17, 0x66, 0x6b, 0x46, 0x71, - 0x45, 0x11, 0xae, 0xb7, 0x61, 0xb7, 0x35, 0x70, 0x0a, 0x5d, 0x0a, 0x37, 0xae, 0x55, 0xa7, 0xed, - 0x06, 0x14, 0xc3, 0x88, 0x3c, 0x8b, 0x27, 0xdb, 0xef, 0x25, 0xd8, 0xa2, 0xf5, 0xb3, 0x83, 0x49, - 0xe3, 0x39, 0x26, 0x17, 0x5d, 0xf7, 0x8a, 0x07, 0xe1, 0x16, 0xcc, 0x27, 0xe0, 0x40, 0x4a, 0x43, - 0xef, 0xc0, 0x5a, 0x3b, 0x20, 0x04, 0x3b, 0xbe, 0x28, 0x36, 0x1c, 0x8c, 0x72, 0x67, 0x56, 0x05, - 0x8b, 0x55, 0x16, 0xf4, 0x1e, 0x6c, 0xd8, 0x4e, 0x9b, 0xe0, 0xde, 0x50, 0x78, 0x3e, 0x26, 0xbc, - 0x1e, 0x31, 0xe3, 0x85, 0xa8, 0x06, 0x9b, 0x35, 0x7b, 0x80, 0xad, 0x66, 0xd0, 0xa6, 0x19, 0x1b, - 0x9e, 0x72, 0x4e, 0x5c, 0xa4, 0xef, 0x3b, 0x68, 0x3d, 0x14, 0x14, 0xe6, 0xfe, 0x22, 0xc1, 0xed, - 0x22, 0xc5, 0x8e, 0xc3, 0xf2, 0x8b, 0x2f, 0x5c, 0x82, 0x8f, 0x4a, 0x51, 0x1f, 0x68, 0xfd, 0xa8, - 0x3e, 0x30, 0xc4, 0x4b, 0xd4, 0xc4, 0x25, 0xc1, 0x1e, 0x1d, 0x80, 0x7e, 0x48, 0x03, 0x18, 0x6a, - 0x09, 0x5f, 0x3f, 0x05, 0xc4, 0xbb, 0x59, 0xcd, 0xf6, 0x3c, 0xdb, 0xe9, 0x70, 0x0f, 0x3f, 0x84, - 0xd5, 0x2b, 0xe2, 0x3a, 0x1d, 0x83, 0xf7, 0x36, 0xe1, 0x64, 0x7a, 0x2b, 0xd4, 0x57, 0x98, 0x38, - 0xff, 0x18, 0x4e, 0x32, 0x35, 0x4c, 0x3a, 0x58, 0x73, 0x4e, 0x89, 0xdb, 0x21, 0x61, 0x5c, 0x05, - 0xf7, 0x95, 0x04, 0x37, 0x18, 0x16, 0x3e, 0xc4, 0xe2, 0x46, 0xf0, 0x95, 0x4f, 0xc6, 0xd0, 0xcb, - 0x7b, 0x69, 0xe8, 0x7a, 0x54, 0x2f, 0x19, 0x38, 0xfc, 0x56, 0x8a, 0x90, 0xc3, 0x0e, 0x6c, 0x0b, - 0x2c, 0xa0, 0xab, 0xa7, 0x55, 0xad, 0x54, 0x30, 0x74, 0xb5, 0xd6, 0xf8, 0x44, 0x2d, 0xcb, 0x19, - 0xb4, 0x0d, 0x28, 0xe4, 0x15, 0xea, 0x47, 0xaa, 0xd1, 0x3c, 0xad, 0x6a, 0x2d, 0x59, 0x42, 0x37, - 0xe1, 0xc6, 0x08, 0xbd, 0xa6, 0xea, 0x47, 0x14, 0x3e, 0xc4, 0x80, 0x85, 0x5e, 0x38, 0x6c, 0x19, - 0xcd, 0x7a, 0xe1, 0xb4, 0x59, 0x69, 0xb4, 0xe4, 0x79, 0x94, 0x87, 0x1d, 0xc1, 0xa9, 0x36, 0x8e, - 0xb4, 0x52, 0xa1, 0x6a, 0x34, 0x4e, 0x9b, 0x46, 0x4d, 0x6b, 0x36, 0xb5, 0xfa, 0x91, 0x9c, 0x15, - 0x9b, 0xff, 0xf3, 0x16, 0xac, 0x30, 0xb7, 0xcb, 0xd8, 0x37, 0xed, 0x2e, 0xd2, 0x41, 0x76, 0x5c, - 0xdf, 0x18, 0x99, 0x69, 0x79, 0xc8, 0xdf, 0x4a, 0xd8, 0x7e, 0xc2, 0x5c, 0x5d, 0xc9, 0xe8, 0xeb, - 0xce, 0x08, 0x19, 0x35, 0x60, 0x83, 0x8f, 0x7c, 0xd4, 0xf2, 0x05, 0x2d, 0x8a, 0x22, 0x4f, 0xde, - 0x4c, 0x8b, 0xe8, 0x48, 0xf1, 0xac, 0xd0, 0xd1, 0x21, 0x4e, 0x45, 0x9f, 0x02, 0xe2, 0x06, 0x9f, - 0xe1, 0x6b, 0x23, 0x9c, 0x8e, 0x44, 0xd9, 0x78, 0x90, 0x66, 0x73, 0x7c, 0xf6, 0xab, 0x64, 0x74, - 0x99, 0x8c, 0x31, 0xd0, 0x6f, 0x24, 0xb8, 0xcb, 0x26, 0x9c, 0x2b, 0x36, 0x08, 0x19, 0xc1, 0x70, - 0x12, 0x62, 0x09, 0x48, 0x47, 0x21, 0x31, 0x6c, 0x3d, 0x4a, 0x9c, 0xf1, 0xbf, 0x6f, 0x84, 0xaa, - 0x64, 0xf4, 0x3b, 0x64, 0x9a, 0x14, 0xfa, 0x15, 0xdc, 0x88, 0xd5, 0x34, 0xc3, 0xe4, 0x08, 0x9f, - 0x8d, 0xea, 0x2b, 0x0f, 0xdf, 0x9d, 0x69, 0x1c, 0x08, 0x57, 0x42, 0xfe, 0x04, 0x0b, 0xb5, 0x40, - 0x8e, 0x9b, 0xa7, 0x58, 0x5e, 0x59, 0x64, 0xb6, 0xdf, 0x9e, 0x6e, 0x3b, 0x1a, 0x1d, 0x2a, 0x19, - 0x7d, 0xc3, 0x1f, 0xa5, 0xa3, 0x27, 0xb0, 0x19, 0xb7, 0x4a, 0xe8, 0x6d, 0x50, 0x72, 0xa9, 0x07, - 0x92, 0x38, 0x2e, 0xd0, 0x03, 0xf1, 0xc7, 0x18, 0xe8, 0x33, 0x88, 0x6f, 0x82, 0x0e, 0xe9, 0x7e, - 0xe0, 0x29, 0x4b, 0xcc, 0xf2, 0x3b, 0x33, 0x83, 0xf9, 0x4a, 0x46, 0x8f, 0xfb, 0xc7, 0x39, 0xa8, - 0x42, 0x4b, 0x8b, 0xed, 0xe3, 0xb0, 0xb4, 0x2c, 0x33, 0xab, 0xf7, 0x13, 0xac, 0x8e, 0x63, 0xf3, - 0x4a, 0x86, 0x96, 0x99, 0x88, 0x86, 0x34, 0x58, 0xe3, 0x96, 0x7c, 0xd7, 0x35, 0x68, 0x1d, 0x84, - 0xe9, 0xa6, 0x62, 0xa8, 0x23, 0x32, 0xc5, 0x69, 0xf4, 0xb2, 0xb8, 0x7d, 0x83, 0x08, 0x04, 0xcc, - 0x86, 0xb3, 0x95, 0xd4, 0xcb, 0x32, 0x09, 0x95, 0xe9, 0x65, 0x71, 0xe3, 0x54, 0x7a, 0xe0, 0xed, - 0x10, 0x35, 0x1b, 0x17, 0x0c, 0x36, 0x2b, 0xab, 0xa9, 0x07, 0x9e, 0x04, 0xb0, 0xe9, 0x81, 0xb7, - 0x47, 0xe9, 0xa8, 0x0e, 0xeb, 0xbc, 0x46, 0x10, 0x01, 0x98, 0x95, 0xb5, 0x54, 0x2f, 0x27, 0x81, - 0x35, 0xf5, 0xb2, 0x1b, 0xa7, 0x52, 0x2f, 0x1d, 0xd7, 0xc2, 0x46, 0x30, 0x7c, 0x6d, 0x52, 0xd6, - 0x53, 0xbd, 0x4c, 0x7a, 0x97, 0xa2, 0x5e, 0x3a, 0xa3, 0x74, 0x0a, 0x8f, 0x3c, 0xec, 0x58, 0xca, - 0x06, 0xb3, 0xf4, 0x7a, 0x82, 0xa5, 0x08, 0x3e, 0x57, 0x32, 0x3a, 0x93, 0xe5, 0xc5, 0xe5, 0xc2, - 0x37, 0x3a, 0x14, 0xa2, 0x1a, 0x16, 0xc7, 0xa8, 0x8a, 0x3c, 0xa5, 0xb8, 0x24, 0xc0, 0x59, 0x5e, - 0x5c, 0x46, 0x19, 0x34, 0x97, 0x43, 0x7c, 0xd9, 0x8e, 0xd0, 0xad, 0xb2, 0x99, 0x9a, 0xcb, 0xc9, - 0x48, 0x98, 0xe6, 0x32, 0x19, 0xe7, 0xb0, 0x1a, 0x2b, 0x6c, 0x87, 0x39, 0x88, 0xd2, 0x6b, 0xec, - 0x04, 0xf6, 0x65, 0x35, 0x36, 0x4e, 0xa5, 0x07, 0x62, 0x86, 0x13, 0x82, 0x41, 0xd8, 0x88, 0xa0, - 0xec, 0xa4, 0x1e, 0x48, 0xd2, 0x30, 0x41, 0x0f, 0xc4, 0x1c, 0xa5, 0x53, 0x37, 0x39, 0x0e, 0x1e, - 0xb6, 0x82, 0xdb, 0xa9, 0x6e, 0x4e, 0xe2, 0x68, 0xea, 0xa6, 0x17, 0xa7, 0xa2, 0x2e, 0xdc, 0x16, - 0xc8, 0x98, 0x17, 0x1d, 0x7a, 0xec, 0xf4, 0xd2, 0x18, 0x6c, 0x2a, 0x50, 0x5e, 0x67, 0xc6, 0x93, - 0x1e, 0x51, 0xd2, 0x10, 0x70, 0x25, 0xa3, 0x2b, 0x97, 0x69, 0xe8, 0xb8, 0x05, 0xb2, 0xcd, 0x01, - 0xa3, 0xe1, 0x0a, 0xc4, 0xa8, 0xec, 0xa6, 0x06, 0x25, 0x09, 0x5b, 0xd2, 0xa0, 0xd8, 0xa3, 0x74, - 0x5a, 0xf1, 0x83, 0xe1, 0x53, 0xaa, 0x21, 0x06, 0x44, 0xe5, 0x6e, 0x6a, 0xc5, 0x4f, 0x79, 0x78, - 0xa5, 0x15, 0x3f, 0x98, 0x60, 0xa1, 0x13, 0x58, 0xeb, 0x51, 0x48, 0x69, 0x78, 0x1c, 0x53, 0x2a, - 0xf7, 0x52, 0xdf, 0xa8, 0x27, 0xa0, 0x67, 0x25, 0xa3, 0xaf, 0xf6, 0x62, 0x44, 0xf4, 0x39, 0xc8, - 0xd1, 0xb8, 0x6f, 0x9c, 0x33, 0x2c, 0xa9, 0xec, 0x31, 0x7b, 0xfb, 0x09, 0xf6, 0xa6, 0x40, 0x4f, - 0xd6, 0x45, 0x46, 0x39, 0xe8, 0x0a, 0xee, 0xd0, 0xa3, 0x33, 0x39, 0x74, 0x37, 0xf0, 0x10, 0xbb, - 0x8b, 0xe3, 0xbc, 0xcf, 0x56, 0x7a, 0x98, 0x54, 0xf7, 0xa7, 0x23, 0xfe, 0x4a, 0x46, 0xdf, 0xf1, - 0x53, 0x45, 0x68, 0x35, 0xe3, 0x3d, 0x80, 0xa2, 0x09, 0x8a, 0x3d, 0x95, 0x37, 0x52, 0xb3, 0x72, - 0x12, 0xa3, 0xd2, 0xac, 0xb4, 0xe3, 0x54, 0x74, 0x06, 0x9b, 0x3d, 0x0a, 0x38, 0x0d, 0xdb, 0x31, - 0xfa, 0x02, 0x72, 0x2a, 0x6f, 0xa6, 0x26, 0x4a, 0x12, 0x38, 0xa5, 0xf1, 0xe9, 0x8d, 0xd2, 0xd1, - 0xc7, 0x02, 0x48, 0x5d, 0xe0, 0x30, 0xdd, 0x95, 0xb7, 0x52, 0xb1, 0x59, 0x02, 0x34, 0xa5, 0xd8, - 0x2c, 0x32, 0xc0, 0xc8, 0x1c, 0x05, 0x16, 0x73, 0xb0, 0xc0, 0x06, 0x94, 0xe3, 0xec, 0xd2, 0xb6, - 0x7c, 0xf3, 0x38, 0xbb, 0x74, 0x4b, 0xde, 0x39, 0xce, 0x2e, 0xdd, 0x91, 0xf3, 0xc7, 0xd9, 0xa5, - 0xbc, 0xbc, 0xbb, 0x77, 0xc0, 0x50, 0xe2, 0xa9, 0xeb, 0xb1, 0x1e, 0x80, 0x76, 0x60, 0xc1, 0x76, - 0x2c, 0x3c, 0x10, 0x43, 0x32, 0x87, 0xba, 0x9c, 0x24, 0x70, 0xe5, 0xd7, 0xf3, 0xb0, 0x30, 0xdb, - 0x93, 0xc2, 0x2f, 0x47, 0xf1, 0x0e, 0xc1, 0xec, 0x21, 0x9e, 0xa1, 0xb9, 0xf5, 0xc4, 0x03, 0x18, - 0x01, 0x0f, 0x4c, 0x38, 0x7c, 0x70, 0xf5, 0x27, 0x38, 0xa8, 0x04, 0x6b, 0x81, 0x83, 0x07, 0x7d, - 0xd7, 0xc3, 0x16, 0x6b, 0xa6, 0xd9, 0x59, 0x86, 0x4b, 0x7d, 0x35, 0x52, 0xa2, 0x2d, 0xf4, 0x00, - 0x56, 0x5c, 0x62, 0x77, 0x6c, 0xc7, 0xa0, 0x0d, 0x86, 0x41, 0xb1, 0x85, 0xe2, 0x3a, 0x5d, 0xf3, - 0xd5, 0x8b, 0xdd, 0x45, 0xda, 0x8c, 0xb4, 0xb2, 0x0e, 0x5c, 0x84, 0x7e, 0xa1, 0x0f, 0x61, 0xd1, - 0x62, 0x78, 0x5a, 0x40, 0xab, 0x7c, 0xda, 0xbc, 0xc6, 0x51, 0x77, 0x38, 0x2b, 0x70, 0x1d, 0xf4, - 0xb3, 0x30, 0xba, 0xb9, 0x69, 0xca, 0xe1, 0x61, 0x88, 0xb8, 0xa3, 0x47, 0x30, 0xef, 0xb8, 0x57, - 0x02, 0x1a, 0xcd, 0x34, 0x81, 0x51, 0xf9, 0xc7, 0x4b, 0x7f, 0xf8, 0x6a, 0x37, 0x33, 0x7c, 0x19, - 0x7a, 0xf7, 0xbb, 0x39, 0x50, 0xd2, 0x1e, 0x98, 0xe9, 0xb4, 0x51, 0x28, 0x36, 0xf4, 0x96, 0x31, - 0xf1, 0xf4, 0xf9, 0x26, 0xdc, 0x1b, 0xe1, 0xb0, 0x0f, 0xb5, 0x6c, 0xe8, 0x6a, 0xa9, 0xa1, 0x97, - 0xa3, 0x77, 0xd0, 0x3c, 0xec, 0x8c, 0x88, 0x15, 0xd5, 0x23, 0xad, 0x6e, 0xb4, 0x1a, 0x0d, 0xa3, - 0x51, 0xa5, 0xe3, 0xcc, 0x38, 0xbf, 0x54, 0xd5, 0xd4, 0x3a, 0xfd, 0x3a, 0x56, 0x4b, 0x74, 0xa8, - 0xd9, 0x85, 0xdb, 0x23, 0xfc, 0xd3, 0xb3, 0x66, 0x45, 0xd5, 0xc3, 0xd5, 0xe4, 0x2c, 0xba, 0x0d, - 0x37, 0x27, 0xfd, 0x30, 0x9a, 0xa7, 0x85, 0xba, 0xbc, 0x80, 0x0a, 0xf0, 0xd1, 0x28, 0xb3, 0xaa, - 0xab, 0x85, 0xf2, 0xd3, 0xe1, 0x7b, 0xac, 0xd1, 0xd0, 0x0d, 0xbd, 0x51, 0xad, 0xaa, 0x65, 0xa3, - 0x58, 0x28, 0x9d, 0x18, 0xa7, 0x8d, 0x66, 0x53, 0x2b, 0x56, 0x55, 0x36, 0xa9, 0x15, 0x9e, 0xca, - 0x8b, 0xe8, 0x03, 0x78, 0x34, 0x62, 0xa2, 0xa5, 0xd5, 0xd4, 0x66, 0xab, 0x50, 0x3b, 0x35, 0x4a, - 0x85, 0x52, 0x45, 0x15, 0x9e, 0xaa, 0xe5, 0x09, 0xd5, 0xdc, 0x4e, 0xf6, 0xcb, 0x3f, 0xe5, 0x33, - 0xef, 0xfe, 0x7d, 0xf4, 0x11, 0x3b, 0xf6, 0xe6, 0xcd, 0x67, 0xb9, 0x96, 0xfe, 0x74, 0x32, 0xba, - 0x6c, 0xfc, 0xa3, 0x9c, 0x27, 0xba, 0xd6, 0x52, 0xa3, 0x78, 0x49, 0x7c, 0x5e, 0xa4, 0x8c, 0xb2, - 0x5a, 0x55, 0x5b, 0x2a, 0x9f, 0x0e, 0xe5, 0xb9, 0x21, 0xbd, 0xa9, 0xea, 0x5a, 0xa1, 0xaa, 0x7d, - 0x56, 0x28, 0x56, 0x55, 0x79, 0x1e, 0xdd, 0x82, 0xd7, 0x38, 0x7d, 0xdc, 0xbd, 0x2c, 0xba, 0x03, - 0xb7, 0x38, 0xab, 0xd0, 0x7c, 0x5a, 0x2f, 0x89, 0x95, 0x0e, 0x0b, 0x5a, 0xf5, 0x4c, 0x57, 0xe5, - 0x05, 0xe1, 0xfd, 0x63, 0x40, 0x93, 0xd7, 0x0f, 0x2d, 0x41, 0xb6, 0xde, 0xa8, 0xab, 0x72, 0x06, - 0xad, 0x40, 0x8e, 0x06, 0xae, 0x71, 0x78, 0x28, 0x4b, 0x68, 0x0d, 0x96, 0xb5, 0x5a, 0x4d, 0x2d, - 0x6b, 0x85, 0x96, 0x2a, 0xcf, 0x15, 0xef, 0x7d, 0xf3, 0xef, 0x7c, 0xe6, 0x9b, 0x97, 0x79, 0xe9, - 0x1f, 0x2f, 0xf3, 0xd2, 0xb7, 0x2f, 0xf3, 0xd2, 0xbf, 0x5e, 0xe6, 0xa5, 0xdf, 0xfd, 0x27, 0x9f, - 0xf9, 0x2c, 0x27, 0xd2, 0xfa, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x82, 0x01, 0xe3, 0xfb, 0x56, - 0x1e, 0x00, 0x00, + // 2767 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0xcb, 0x73, 0xdb, 0xd6, + 0xd5, 0x27, 0x24, 0x4a, 0x94, 0x8e, 0x5e, 0xd0, 0xb5, 0x22, 0xc3, 0x72, 0x4c, 0xd9, 0x72, 0x1e, + 0x8e, 0xbf, 0x89, 0xf4, 0x8d, 0xf3, 0x79, 0xbe, 0x89, 0x9b, 0x2c, 0xf8, 0x80, 0x44, 0x48, 0x7c, + 0x28, 0x20, 0x15, 0xc7, 0x49, 0x3b, 0x18, 0x88, 0xb8, 0xa2, 0x10, 0x93, 0x00, 0x7b, 0x01, 0x58, + 0xd4, 0xae, 0xcb, 0xec, 0xda, 0xee, 0xba, 0x6b, 0x66, 0xda, 0x4d, 0xa6, 0xdb, 0x4e, 0xfe, 0x86, + 0x2c, 0xbb, 0xcc, 0x74, 0x26, 0x9e, 0xd6, 0xdd, 0x74, 0xa6, 0xff, 0x81, 0x57, 0x9d, 0xfb, 0x00, + 0x08, 0x92, 0x00, 0xc3, 0x64, 0x45, 0xe2, 0x3c, 0x7e, 0xf7, 0xdc, 0x7b, 0xcf, 0x3d, 0xf7, 0x77, + 0x2e, 0x6c, 0x11, 0xd7, 0x6c, 0x5f, 0xf6, 0xcf, 0x0f, 0x30, 0x21, 0x2e, 0xf1, 0xf6, 0xfb, 0xc4, + 0xf5, 0x5d, 0xb4, 0xd9, 0x76, 0xdb, 0xcf, 0x99, 0x66, 0x5f, 0xe8, 0x77, 0x50, 0x68, 0x68, 0x99, + 0xbe, 0xc9, 0xcd, 0x76, 0xb6, 0x43, 0x59, 0x0f, 0xfb, 0x66, 0x4c, 0x7e, 0xdf, 0xf3, 0x5d, 0x62, + 0x76, 0xf0, 0x01, 0x76, 0x3a, 0xb6, 0x13, 0xfe, 0x50, 0xbb, 0x17, 0xed, 0xf6, 0x07, 0xc2, 0x48, + 0x09, 0x7c, 0xbb, 0x7b, 0x70, 0xd9, 0x6d, 0x1f, 0xf8, 0x76, 0x0f, 0x7b, 0xbe, 0xd9, 0xeb, 0x0b, + 0xcd, 0x56, 0xc7, 0xed, 0xb8, 0xec, 0xef, 0x01, 0xfd, 0xc7, 0xa5, 0x7b, 0xdf, 0xce, 0xc1, 0x8d, + 0xba, 0xeb, 0x57, 0xb1, 0xe9, 0xe1, 0x8a, 0xdb, 0xb5, 0x30, 0x51, 0x69, 0xc8, 0xa8, 0x0c, 0x39, + 0x82, 0xfb, 0x5d, 0xbb, 0x6d, 0x2a, 0xd2, 0x5d, 0xe9, 0xc1, 0xca, 0xa3, 0xb7, 0xf6, 0x27, 0xa2, + 0xdf, 0xd7, 0xb9, 0x45, 0x19, 0x7b, 0x6d, 0x62, 0xf7, 0x7d, 0x97, 0x14, 0xb3, 0xdf, 0xbd, 0xdc, + 0xcd, 0xe8, 0xa1, 0x2b, 0x3a, 0x82, 0xd5, 0x2e, 0x45, 0x36, 0x2e, 0x19, 0xb4, 0x32, 0x37, 0x3b, + 0x94, 0xbe, 0xd2, 0x1d, 0xc6, 0x84, 0x1e, 0xc3, 0x12, 0x31, 0x9d, 0x0e, 0x36, 0x6c, 0x4b, 0x99, + 0xbf, 0x2b, 0x3d, 0x98, 0x2f, 0xee, 0xd0, 0x91, 0x5e, 0xbd, 0xdc, 0xcd, 0xe9, 0x54, 0xae, 0x95, + 0x5f, 0x0f, 0xff, 0xea, 0x39, 0x66, 0xab, 0x59, 0x68, 0x1f, 0x16, 0x18, 0x8a, 0x92, 0x65, 0x03, + 0x2b, 0x09, 0x03, 0xb3, 0x99, 0xeb, 0xdc, 0x0c, 0xdd, 0x07, 0x68, 0x07, 0x9e, 0xef, 0xf6, 0x8c, + 0x9e, 0xd7, 0x51, 0x16, 0xee, 0x4a, 0x0f, 0x96, 0xc5, 0x94, 0x96, 0xb9, 0xbc, 0xe6, 0x75, 0x9e, + 0x64, 0xff, 0xfd, 0xf5, 0xae, 0xb4, 0xf7, 0x26, 0x6c, 0xd5, 0x5d, 0x0b, 0x9f, 0x39, 0xe6, 0x0b, + 0xd3, 0xee, 0x9a, 0xe7, 0x5d, 0xcc, 0x16, 0x4e, 0x68, 0x77, 0xe1, 0xe6, 0x99, 0xe3, 0x05, 0xfd, + 0xbe, 0x4b, 0x7c, 0x6c, 0xe9, 0xf8, 0xd7, 0x01, 0xf6, 0xfc, 0xb8, 0xc1, 0x57, 0x12, 0x20, 0x16, + 0x6e, 0xdd, 0xf5, 0x0f, 0xdd, 0xc0, 0xb1, 0xf8, 0xb2, 0xc7, 0xe7, 0x29, 0xcd, 0x3e, 0xcf, 0xc7, + 0xb0, 0x44, 0x93, 0x83, 0xb9, 0xcd, 0x8d, 0xba, 0x35, 0xa9, 0x9c, 0xbb, 0x89, 0xbf, 0x7a, 0x8e, + 0xd9, 0x6a, 0x96, 0x08, 0xe5, 0x8f, 0x73, 0xf0, 0x06, 0x43, 0x3c, 0xc1, 0xd7, 0x35, 0xdb, 0xeb, + 0x99, 0x7e, 0xfb, 0x92, 0x47, 0xf3, 0x01, 0x6c, 0x12, 0x1e, 0xba, 0xe1, 0xf9, 0x26, 0xf1, 0x8d, + 0xe7, 0xf8, 0x9a, 0x85, 0xb5, 0x5a, 0xcc, 0xbd, 0x7e, 0xb9, 0x3b, 0x7f, 0x82, 0xaf, 0xf5, 0x0d, + 0x61, 0xd1, 0xa4, 0x06, 0x27, 0xf8, 0x1a, 0x1d, 0x40, 0x28, 0x32, 0xb0, 0x63, 0x31, 0x97, 0xb9, + 0x51, 0x97, 0x35, 0xa1, 0x57, 0x1d, 0x8b, 0x3a, 0xd4, 0x40, 0xee, 0x89, 0x61, 0xb1, 0x65, 0xb0, + 0x29, 0xb1, 0x3d, 0x5e, 0x79, 0xb4, 0x97, 0x94, 0x28, 0x54, 0x1f, 0x4b, 0x93, 0x8d, 0xa1, 0x2f, + 0x53, 0xa1, 0x13, 0xd8, 0xf0, 0x82, 0x4e, 0x07, 0x7b, 0x7e, 0x84, 0x96, 0x9d, 0x19, 0x6d, 0x3d, + 0x72, 0x65, 0x1a, 0xb1, 0x42, 0xff, 0x99, 0x83, 0x3d, 0x1d, 0x9b, 0xd6, 0x53, 0xdb, 0xbf, 0xb4, + 0x9d, 0x33, 0xa7, 0x8d, 0x89, 0x6f, 0xda, 0x8e, 0x7f, 0xad, 0x39, 0x3e, 0x26, 0x2f, 0xcc, 0x2e, + 0x5f, 0xae, 0x63, 0x58, 0x27, 0xd8, 0xb4, 0x8c, 0xe8, 0xe4, 0x89, 0xa3, 0x73, 0x27, 0x36, 0x30, + 0x3d, 0x9e, 0xfb, 0x97, 0xdd, 0xf6, 0x7e, 0x2b, 0x34, 0x12, 0x09, 0xb6, 0x46, 0x5d, 0x23, 0x21, + 0xd2, 0x01, 0xe1, 0x81, 0xed, 0xf9, 0xb6, 0xd3, 0x89, 0xe1, 0xcd, 0xcd, 0x8e, 0xb7, 0x19, 0xba, + 0x0f, 0x31, 0x8b, 0xb0, 0xd6, 0x33, 0x07, 0x31, 0xb8, 0xf9, 0x19, 0xe0, 0xf4, 0xd5, 0x9e, 0x39, + 0x18, 0x62, 0x7c, 0x01, 0x37, 0xdc, 0x73, 0x0f, 0x93, 0x17, 0x38, 0x36, 0x4f, 0x4f, 0xc9, 0xde, + 0x9d, 0x4f, 0x39, 0xd8, 0x0d, 0x61, 0x3d, 0x1e, 0x1f, 0x72, 0xc7, 0x15, 0x9e, 0x58, 0xed, 0x2f, + 0xe1, 0x66, 0x8b, 0x98, 0x8e, 0x67, 0xb6, 0x7d, 0xdb, 0x75, 0x0a, 0xe7, 0xec, 0x08, 0xf1, 0x15, + 0xd6, 0x60, 0x91, 0x60, 0xd3, 0x73, 0x1d, 0xb6, 0xb2, 0xeb, 0x8f, 0xfe, 0x27, 0x61, 0xc0, 0x49, + 0x5f, 0x9d, 0xb9, 0x88, 0x71, 0x05, 0x80, 0x18, 0xcb, 0x84, 0xad, 0x98, 0xfd, 0x69, 0xe0, 0x89, + 0xcc, 0x2f, 0x01, 0xf4, 0x03, 0xef, 0x12, 0x63, 0xc3, 0x1f, 0x38, 0x62, 0x1b, 0xf3, 0xd3, 0x07, + 0x0b, 0x0b, 0x05, 0xf7, 0x6b, 0x0d, 0xc2, 0x21, 0x2e, 0xe0, 0x8d, 0x98, 0x95, 0x8e, 0x7d, 0x72, + 0xcd, 0xc7, 0x38, 0x1a, 0x9b, 0xcc, 0x7b, 0xd3, 0xf1, 0x99, 0xe7, 0x94, 0xa9, 0x7c, 0x2f, 0xc1, + 0x76, 0xcc, 0xbc, 0xe9, 0x9b, 0x7e, 0xe0, 0xf1, 0x91, 0xb6, 0x61, 0x9e, 0xd6, 0x33, 0x29, 0x56, + 0xcf, 0xa8, 0x00, 0xd5, 0xa3, 0x08, 0xe6, 0x58, 0x04, 0xff, 0x3b, 0x3d, 0x82, 0x18, 0xe4, 0x7e, + 0x52, 0x20, 0x7b, 0xa7, 0xb0, 0xc8, 0xe5, 0x08, 0xc1, 0xba, 0xae, 0x16, 0x9a, 0x8d, 0xba, 0x71, + 0x56, 0x3f, 0xa9, 0x37, 0x9e, 0xd6, 0xe5, 0x0c, 0x52, 0x60, 0x4b, 0xc8, 0x5a, 0x9f, 0xd5, 0x8d, + 0x7a, 0xa3, 0x65, 0x1c, 0x36, 0xce, 0xea, 0x65, 0x59, 0x1a, 0xd3, 0x94, 0x1a, 0xb5, 0x9a, 0xd6, + 0x6a, 0xa9, 0x65, 0x79, 0x4e, 0x4c, 0xed, 0x19, 0xc8, 0x4f, 0x89, 0xed, 0x63, 0x7a, 0xdc, 0x1c, + 0x5e, 0x46, 0xd1, 0x87, 0x90, 0xb3, 0xd9, 0xa7, 0xa7, 0x48, 0x2c, 0xf9, 0x6e, 0x25, 0x04, 0xcf, + 0x1d, 0xc2, 0x5b, 0x49, 0xd8, 0x73, 0xd0, 0xe3, 0xec, 0xd2, 0x9c, 0x3c, 0xbf, 0xf7, 0x17, 0x49, + 0x60, 0xb7, 0x5c, 0xb7, 0xd1, 0x15, 0x69, 0x56, 0x80, 0xe5, 0x9f, 0x75, 0x86, 0x87, 0x5e, 0xa8, + 0x0e, 0xb2, 0xd9, 0xf6, 0x03, 0xb3, 0xfb, 0xf3, 0x4e, 0xef, 0x06, 0x77, 0x8e, 0xc4, 0x62, 0x21, + 0x76, 0x00, 0x35, 0xfa, 0xf4, 0x36, 0xb1, 0x09, 0xf6, 0x5a, 0x03, 0x27, 0x7e, 0xa3, 0x3c, 0x83, + 0xad, 0x92, 0xeb, 0x58, 0x36, 0xdd, 0xa9, 0x43, 0xd3, 0xee, 0x86, 0x67, 0xe6, 0x17, 0xb0, 0x2a, + 0x22, 0x79, 0x61, 0x76, 0x03, 0x2c, 0xe6, 0x93, 0x74, 0x15, 0x7e, 0x4a, 0xf5, 0xfa, 0x0a, 0xb7, + 0x66, 0x1f, 0x02, 0xfa, 0xaf, 0x12, 0x20, 0x7e, 0x4f, 0xe2, 0x2f, 0x71, 0x3b, 0x3a, 0x8d, 0x79, + 0xc8, 0xf5, 0xb0, 0xe7, 0x99, 0x1d, 0x3c, 0x92, 0x5a, 0xa1, 0x10, 0x7d, 0x04, 0xcb, 0xa2, 0xd2, + 0x63, 0x4b, 0x4c, 0x3e, 0xf5, 0x06, 0x0e, 0x57, 0x30, 0x72, 0x40, 0x4f, 0x60, 0x29, 0x2c, 0x61, + 0xa2, 0x50, 0xfd, 0x98, 0x73, 0x64, 0x2f, 0xc2, 0xfe, 0x7f, 0x58, 0x6e, 0x62, 0x67, 0xb6, 0x60, + 0x47, 0x92, 0xe2, 0x0a, 0xb6, 0x0a, 0xbd, 0x73, 0xbb, 0x13, 0xb8, 0x81, 0xa7, 0x63, 0x2f, 0xe8, + 0xfa, 0xb3, 0x4d, 0xf8, 0x43, 0x58, 0xb9, 0x22, 0x66, 0xbf, 0x8f, 0x2d, 0x03, 0x13, 0x32, 0x65, + 0xca, 0x0c, 0x4e, 0x07, 0x61, 0xac, 0x92, 0x70, 0x0f, 0xef, 0xd0, 0x9b, 0xf8, 0xc2, 0x3f, 0x22, + 0x6e, 0xd0, 0x2f, 0xe3, 0x2e, 0x0e, 0x97, 0x5a, 0xa8, 0x31, 0x6c, 0x0b, 0x9e, 0x54, 0x72, 0x09, + 0x09, 0xfa, 0x74, 0xab, 0x79, 0x64, 0xf7, 0x60, 0x99, 0x51, 0x4d, 0x63, 0xfc, 0x9c, 0x2f, 0x31, + 0x71, 0xcd, 0xeb, 0xa0, 0x3d, 0x58, 0xee, 0x13, 0xb7, 0x8d, 0x3d, 0x4f, 0xec, 0xc6, 0x52, 0x54, + 0xb1, 0x42, 0x71, 0x94, 0x49, 0x48, 0x0c, 0x13, 0x3f, 0x14, 0x1f, 0x03, 0x08, 0x5a, 0x17, 0x92, + 0x93, 0x85, 0x62, 0x5e, 0xb0, 0x8c, 0x65, 0x61, 0xcf, 0x78, 0xc6, 0xf0, 0x83, 0x6e, 0x27, 0xff, + 0x1b, 0x42, 0x7f, 0x02, 0x88, 0xb1, 0x90, 0x09, 0xd6, 0x13, 0xd1, 0x17, 0xe9, 0xa7, 0xd2, 0x97, + 0x1a, 0xa5, 0x5a, 0x97, 0xa6, 0x63, 0x75, 0x69, 0xa5, 0xf7, 0xc9, 0x75, 0xc4, 0xc5, 0xd0, 0x23, + 0xc8, 0xf6, 0x55, 0x42, 0xa6, 0xa4, 0x3c, 0xb3, 0x13, 0xeb, 0xc0, 0x6c, 0xf7, 0x7e, 0x90, 0x40, + 0xa9, 0x8c, 0xa1, 0x85, 0x27, 0x2d, 0xb5, 0x90, 0x7e, 0x01, 0x8b, 0xfe, 0xc0, 0x09, 0xd9, 0xd7, + 0x6a, 0xb1, 0x4c, 0x55, 0x7f, 0x7f, 0xb9, 0xfb, 0x41, 0xc7, 0xf6, 0x2f, 0x83, 0xf3, 0xfd, 0xb6, + 0xdb, 0x3b, 0x88, 0x06, 0xb7, 0xce, 0x87, 0xff, 0x0f, 0xfa, 0xcf, 0x3b, 0x07, 0x8c, 0xb2, 0x07, + 0x81, 0x6d, 0xed, 0x9f, 0x9d, 0x69, 0xe5, 0x57, 0x2f, 0x77, 0x17, 0x5a, 0x03, 0x47, 0x2b, 0xeb, + 0x0b, 0xfe, 0xc0, 0xd1, 0x2c, 0x74, 0x08, 0x2b, 0xfe, 0xb0, 0x08, 0x8b, 0xb3, 0x30, 0xdb, 0x65, + 0x14, 0x77, 0x14, 0xcb, 0xf5, 0x2e, 0xec, 0xb6, 0x06, 0x4e, 0xa1, 0x4b, 0xe9, 0xc6, 0xb5, 0xea, + 0xb4, 0xdd, 0x80, 0x72, 0x18, 0x91, 0x67, 0xf1, 0x64, 0xfb, 0xbd, 0x04, 0x5b, 0xb4, 0x7e, 0x76, + 0x30, 0x69, 0xbc, 0xc0, 0xe4, 0xa2, 0xeb, 0x5e, 0xf1, 0x45, 0xb8, 0x05, 0xf3, 0x09, 0x3c, 0x90, + 0xca, 0xd0, 0x7b, 0xb0, 0xd6, 0x0e, 0x08, 0xc1, 0x8e, 0x2f, 0x8a, 0x0d, 0x27, 0xa3, 0x3c, 0x98, + 0x55, 0xa1, 0x62, 0x95, 0x05, 0xbd, 0x0f, 0x1b, 0xb6, 0xd3, 0x26, 0xb8, 0x37, 0x34, 0x9e, 0x8f, + 0x19, 0xaf, 0x47, 0xca, 0x78, 0x21, 0xaa, 0xc1, 0x66, 0xcd, 0x1e, 0x60, 0xab, 0x19, 0xb4, 0x69, + 0xc6, 0x86, 0xbb, 0x9c, 0x13, 0x07, 0xe9, 0xc7, 0x36, 0x5a, 0x0f, 0x0d, 0x05, 0xdc, 0x37, 0x12, + 0xdc, 0x2e, 0x52, 0xee, 0x38, 0x2c, 0xbf, 0xf8, 0xc2, 0x25, 0xf8, 0xa8, 0x14, 0xdd, 0x03, 0xad, + 0x9f, 0x75, 0x0f, 0x0c, 0xf9, 0x12, 0x85, 0xb8, 0x24, 0xd8, 0xa3, 0x0d, 0xd0, 0x4f, 0xb9, 0x00, + 0x86, 0x5e, 0x22, 0xd6, 0xcf, 0x00, 0xf1, 0xdb, 0xac, 0x66, 0x7b, 0x9e, 0xed, 0x74, 0x78, 0x84, + 0x1f, 0xc1, 0xea, 0x15, 0x71, 0x9d, 0x8e, 0xc1, 0xef, 0x36, 0x11, 0x64, 0xfa, 0x55, 0xa8, 0xaf, + 0x30, 0x73, 0xfe, 0x31, 0xec, 0x64, 0x6a, 0x98, 0x74, 0xb0, 0xe6, 0x9c, 0x12, 0xb7, 0x43, 0xc2, + 0x75, 0x15, 0xda, 0xd7, 0x12, 0xdc, 0x60, 0x5c, 0xf8, 0x10, 0x8b, 0x13, 0xc1, 0x47, 0x3e, 0x19, + 0x63, 0x2f, 0xef, 0xa7, 0xb1, 0xeb, 0x51, 0xbf, 0x64, 0xe2, 0xf0, 0x5b, 0x29, 0x62, 0x0e, 0x3b, + 0xb0, 0x2d, 0xb8, 0x80, 0xae, 0x9e, 0x56, 0xb5, 0x52, 0xc1, 0xd0, 0xd5, 0x5a, 0xe3, 0x53, 0xb5, + 0x2c, 0x67, 0xd0, 0x36, 0xa0, 0x50, 0x57, 0xa8, 0x1f, 0xa9, 0x46, 0xf3, 0xb4, 0xaa, 0xb5, 0x64, + 0x09, 0xdd, 0x84, 0x1b, 0x23, 0xf2, 0x9a, 0xaa, 0x1f, 0x51, 0xfa, 0x10, 0x23, 0x16, 0x7a, 0xe1, + 0xb0, 0x65, 0x34, 0xeb, 0x85, 0xd3, 0x66, 0xa5, 0xd1, 0x92, 0xe7, 0x51, 0x1e, 0x76, 0x84, 0xa6, + 0xda, 0x38, 0xd2, 0x4a, 0x85, 0xaa, 0xd1, 0x38, 0x6d, 0x1a, 0x35, 0xad, 0xd9, 0xd4, 0xea, 0x47, + 0x72, 0x56, 0x4c, 0xfe, 0xcf, 0x5b, 0xb0, 0xc2, 0xc2, 0x2e, 0x63, 0xdf, 0xb4, 0xbb, 0x48, 0x07, + 0xd9, 0x71, 0x7d, 0x63, 0xa4, 0xa7, 0xe5, 0x4b, 0xfe, 0x4e, 0xc2, 0xf4, 0x13, 0xfa, 0xea, 0x4a, + 0x46, 0x5f, 0x77, 0x46, 0xc4, 0xa8, 0x01, 0x1b, 0xbc, 0xe5, 0xa3, 0xc8, 0x17, 0xb4, 0x28, 0x8a, + 0x3c, 0x79, 0x3b, 0x6d, 0x45, 0x47, 0x8a, 0x67, 0x85, 0xb6, 0x0e, 0x71, 0x29, 0xfa, 0x0c, 0x10, + 0x07, 0x7c, 0x8e, 0xaf, 0x8d, 0xb0, 0x3b, 0x12, 0x65, 0xe3, 0x41, 0x1a, 0xe6, 0x78, 0xef, 0x57, + 0xc9, 0xe8, 0x32, 0x19, 0x53, 0xa0, 0xdf, 0x48, 0x70, 0x97, 0x75, 0x38, 0x57, 0xac, 0x11, 0x32, + 0x82, 0x61, 0x27, 0xc4, 0x12, 0x90, 0xb6, 0x42, 0xa2, 0xd9, 0x7a, 0x9c, 0xd8, 0xe3, 0xff, 0x58, + 0x0b, 0x55, 0xc9, 0xe8, 0x77, 0xc8, 0x34, 0x2b, 0xf4, 0x2b, 0xb8, 0x11, 0xab, 0x69, 0x86, 0xc9, + 0x19, 0x3e, 0x6b, 0xd5, 0x57, 0x1e, 0x3d, 0x9c, 0xa9, 0x1d, 0x08, 0x47, 0x42, 0xfe, 0x84, 0x0a, + 0xb5, 0x40, 0x8e, 0xc3, 0x53, 0x2e, 0xaf, 0x2c, 0x32, 0xec, 0x77, 0xa7, 0x63, 0x47, 0xad, 0x43, + 0x25, 0xa3, 0x6f, 0xf8, 0xa3, 0x72, 0xf4, 0x14, 0x36, 0xe3, 0xa8, 0x84, 0x9e, 0x06, 0x25, 0x97, + 0xba, 0x21, 0x89, 0xed, 0x02, 0xdd, 0x10, 0x7f, 0x4c, 0x81, 0x3e, 0x87, 0xf8, 0x24, 0x68, 0x93, + 0xee, 0x07, 0x9e, 0xb2, 0xc4, 0x90, 0xdf, 0x9b, 0x99, 0xcc, 0x57, 0x32, 0x7a, 0x3c, 0x3e, 0xae, + 0x41, 0x15, 0x5a, 0x5a, 0x6c, 0x1f, 0x87, 0xa5, 0x65, 0x99, 0xa1, 0xde, 0x4f, 0x40, 0x1d, 0xe7, + 0xe6, 0x95, 0x0c, 0x2d, 0x33, 0x91, 0x0c, 0x69, 0xb0, 0xc6, 0x91, 0x7c, 0xd7, 0x35, 0x68, 0x1d, + 0x84, 0xe9, 0x50, 0x31, 0xd6, 0x11, 0x41, 0x71, 0x19, 0x3d, 0x2c, 0x6e, 0xdf, 0x20, 0x82, 0x01, + 0xb3, 0xe6, 0x6c, 0x25, 0xf5, 0xb0, 0x4c, 0x52, 0x65, 0x7a, 0x58, 0xdc, 0xb8, 0x94, 0x6e, 0x78, + 0x3b, 0x64, 0xcd, 0xc6, 0x05, 0xa3, 0xcd, 0xca, 0x6a, 0xea, 0x86, 0x27, 0x11, 0x6c, 0xba, 0xe1, + 0xed, 0x51, 0x39, 0xaa, 0xc3, 0x3a, 0xaf, 0x11, 0x44, 0x10, 0x66, 0x65, 0x2d, 0x35, 0xca, 0x49, + 0x62, 0x4d, 0xa3, 0xec, 0xc6, 0xa5, 0x34, 0x4a, 0xc7, 0xb5, 0xb0, 0x11, 0x0c, 0x5f, 0x9b, 0x94, + 0xf5, 0xd4, 0x28, 0x93, 0xde, 0xa5, 0x68, 0x94, 0xce, 0xa8, 0x9c, 0xd2, 0x23, 0x0f, 0x3b, 0x96, + 0xb2, 0xc1, 0x90, 0xde, 0x4c, 0x40, 0x8a, 0xe8, 0x73, 0x25, 0xa3, 0x33, 0x5b, 0x5e, 0x5c, 0x2e, + 0x7c, 0xa3, 0x43, 0x29, 0xaa, 0x61, 0x71, 0x8e, 0xaa, 0xc8, 0x53, 0x8a, 0x4b, 0x02, 0x9d, 0xe5, + 0xc5, 0x65, 0x54, 0x41, 0x73, 0x39, 0xe4, 0x97, 0xed, 0x88, 0xdd, 0x2a, 0x9b, 0xa9, 0xb9, 0x9c, + 0xcc, 0x84, 0x69, 0x2e, 0x93, 0x71, 0x0d, 0xab, 0xb1, 0x02, 0x3b, 0xcc, 0x41, 0x94, 0x5e, 0x63, + 0x27, 0xb8, 0x2f, 0xab, 0xb1, 0x71, 0x29, 0xdd, 0x10, 0x33, 0xec, 0x10, 0x0c, 0xc2, 0x5a, 0x04, + 0x65, 0x27, 0x75, 0x43, 0x92, 0x9a, 0x09, 0xba, 0x21, 0xe6, 0xa8, 0x9c, 0x86, 0xc9, 0x79, 0xf0, + 0xf0, 0x2a, 0xb8, 0x9d, 0x1a, 0xe6, 0x24, 0x8f, 0xa6, 0x61, 0x7a, 0x71, 0x29, 0xea, 0xc2, 0x6d, + 0xc1, 0x8c, 0x79, 0xd1, 0xa1, 0xdb, 0x4e, 0x0f, 0x8d, 0xc1, 0xba, 0x02, 0xe5, 0x4d, 0x06, 0x9e, + 0xf4, 0x88, 0x92, 0xc6, 0x80, 0x2b, 0x19, 0x5d, 0xb9, 0x4c, 0x63, 0xc7, 0x2d, 0x90, 0x6d, 0x4e, + 0x18, 0x0d, 0x57, 0x30, 0x46, 0x65, 0x37, 0x75, 0x51, 0x92, 0xb8, 0x25, 0x5d, 0x14, 0x7b, 0x54, + 0x4e, 0x2b, 0x7e, 0x30, 0x7c, 0x4a, 0x35, 0x44, 0x83, 0xa8, 0xdc, 0x4d, 0xad, 0xf8, 0x29, 0x0f, + 0xaf, 0xb4, 0xe2, 0x07, 0x13, 0x2a, 0x74, 0x02, 0x6b, 0x3d, 0x4a, 0x29, 0x0d, 0x8f, 0x73, 0x4a, + 0xe5, 0x5e, 0xea, 0x1b, 0xf5, 0x04, 0xf5, 0xac, 0x64, 0xf4, 0xd5, 0x5e, 0x4c, 0x88, 0xbe, 0x00, + 0x39, 0x6a, 0xf7, 0x8d, 0x73, 0xc6, 0x25, 0x95, 0x3d, 0x86, 0xb7, 0x9f, 0x80, 0x37, 0x85, 0x7a, + 0xb2, 0x5b, 0x64, 0x54, 0x83, 0xae, 0xe0, 0x0e, 0xdd, 0x3a, 0x93, 0x53, 0x77, 0x03, 0x0f, 0xb9, + 0xbb, 0xd8, 0xce, 0xfb, 0x6c, 0xa4, 0x47, 0x49, 0x75, 0x7f, 0x3a, 0xe3, 0xaf, 0x64, 0xf4, 0x1d, + 0x3f, 0xd5, 0x84, 0x56, 0x33, 0x7e, 0x07, 0x50, 0x36, 0x41, 0xb9, 0xa7, 0xf2, 0x56, 0x6a, 0x56, + 0x4e, 0x72, 0x54, 0x9a, 0x95, 0x76, 0x5c, 0x8a, 0xce, 0x60, 0xb3, 0x47, 0x09, 0xa7, 0x61, 0x3b, + 0x46, 0x5f, 0x50, 0x4e, 0xe5, 0xed, 0xd4, 0x44, 0x49, 0x22, 0xa7, 0x74, 0x7d, 0x7a, 0xa3, 0x72, + 0xf4, 0x89, 0x20, 0x52, 0x17, 0x38, 0x4c, 0x77, 0xe5, 0x9d, 0x54, 0x6e, 0x96, 0x40, 0x4d, 0x29, + 0x37, 0x8b, 0x00, 0x98, 0x98, 0xb3, 0xc0, 0x62, 0x0e, 0x16, 0x58, 0x83, 0x72, 0x9c, 0x5d, 0xda, + 0x96, 0x6f, 0x1e, 0x67, 0x97, 0x6e, 0xc9, 0x3b, 0xc7, 0xd9, 0xa5, 0x3b, 0x72, 0xfe, 0x38, 0xbb, + 0x94, 0x97, 0x77, 0xf7, 0x0e, 0x18, 0x4b, 0x3c, 0x75, 0x3d, 0x76, 0x07, 0xa0, 0x1d, 0x58, 0xb0, + 0x1d, 0x0b, 0x0f, 0x44, 0x93, 0xcc, 0xa9, 0x2e, 0x17, 0x09, 0x5e, 0xf9, 0xed, 0x3c, 0x2c, 0xcc, + 0xf6, 0xa4, 0xf0, 0xcb, 0x51, 0xbe, 0x43, 0x30, 0x7b, 0x88, 0x67, 0x6c, 0x6e, 0x3d, 0x71, 0x03, + 0x46, 0xc8, 0x03, 0x33, 0x0e, 0x1f, 0x5c, 0xfd, 0x09, 0x0d, 0x2a, 0xc1, 0x5a, 0xe0, 0xe0, 0x41, + 0xdf, 0xf5, 0xb0, 0xc5, 0x2e, 0xd3, 0xec, 0x2c, 0xcd, 0xa5, 0xbe, 0x1a, 0x39, 0xd1, 0x2b, 0xf4, + 0x00, 0x56, 0x5c, 0x62, 0x77, 0x6c, 0xc7, 0xa0, 0x17, 0x0c, 0xa3, 0x62, 0x0b, 0xc5, 0x75, 0x3a, + 0xe6, 0xeb, 0x97, 0xbb, 0x8b, 0xf4, 0x32, 0xd2, 0xca, 0x3a, 0x70, 0x13, 0xfa, 0x85, 0x3e, 0x82, + 0x45, 0x8b, 0xf1, 0x69, 0x41, 0xad, 0xf2, 0x69, 0xfd, 0x1a, 0x67, 0xdd, 0x61, 0xaf, 0xc0, 0x7d, + 0xd0, 0xff, 0x85, 0xab, 0x9b, 0x9b, 0xe6, 0x1c, 0x6e, 0x86, 0x58, 0x77, 0xf4, 0x18, 0xe6, 0x1d, + 0xf7, 0x4a, 0x50, 0xa3, 0x99, 0x3a, 0x30, 0x6a, 0xff, 0x64, 0xe9, 0x0f, 0x5f, 0xef, 0x66, 0x86, + 0x2f, 0x43, 0x0f, 0x7f, 0x98, 0x03, 0x25, 0xed, 0x81, 0x99, 0x76, 0x1b, 0x85, 0x62, 0x43, 0x6f, + 0x19, 0x13, 0x4f, 0x9f, 0x6f, 0xc3, 0xbd, 0x11, 0x0d, 0xfb, 0x50, 0xcb, 0x86, 0xae, 0x96, 0x1a, + 0x7a, 0x39, 0x7a, 0x07, 0xcd, 0xc3, 0xce, 0x88, 0x59, 0x51, 0x3d, 0xd2, 0xea, 0x46, 0xab, 0xd1, + 0x30, 0x1a, 0x55, 0xda, 0xce, 0x8c, 0xeb, 0x4b, 0x55, 0x4d, 0xad, 0xd3, 0xaf, 0x63, 0xb5, 0x44, + 0x9b, 0x9a, 0x5d, 0xb8, 0x3d, 0xa2, 0x3f, 0x3d, 0x6b, 0x56, 0x54, 0x3d, 0x1c, 0x4d, 0xce, 0xa2, + 0xdb, 0x70, 0x73, 0x32, 0x0e, 0xa3, 0x79, 0x5a, 0xa8, 0xcb, 0x0b, 0xa8, 0x00, 0x1f, 0x8f, 0x2a, + 0xab, 0xba, 0x5a, 0x28, 0x3f, 0x1b, 0xbe, 0xc7, 0x1a, 0x0d, 0xdd, 0xd0, 0x1b, 0xd5, 0xaa, 0x5a, + 0x36, 0x8a, 0x85, 0xd2, 0x89, 0x71, 0xda, 0x68, 0x36, 0xb5, 0x62, 0x55, 0x65, 0x9d, 0x5a, 0xe1, + 0x99, 0xbc, 0x88, 0x3e, 0x84, 0xc7, 0x23, 0x10, 0x2d, 0xad, 0xa6, 0x36, 0x5b, 0x85, 0xda, 0xa9, + 0x51, 0x2a, 0x94, 0x2a, 0xaa, 0x88, 0x54, 0x2d, 0x4f, 0xb8, 0xe6, 0x76, 0xb2, 0x5f, 0xfd, 0x29, + 0x9f, 0x79, 0xf8, 0xcd, 0xe8, 0x23, 0x76, 0xec, 0xcd, 0x9b, 0xf7, 0x72, 0x2d, 0xfd, 0xd9, 0xe4, + 0xea, 0xb2, 0xf6, 0x8f, 0x6a, 0x9e, 0xea, 0x5a, 0x4b, 0x8d, 0xd6, 0x4b, 0xe2, 0xfd, 0x22, 0x55, + 0x34, 0x55, 0x5d, 0x2b, 0x54, 0xb5, 0xcf, 0x0b, 0xc5, 0xaa, 0x2a, 0xcf, 0xa3, 0x5b, 0xf0, 0x06, + 0x97, 0x8f, 0x87, 0x91, 0x45, 0x77, 0xe0, 0x16, 0x57, 0x15, 0x9a, 0xcf, 0xea, 0x25, 0x81, 0x78, + 0x58, 0xd0, 0xaa, 0x67, 0xba, 0x2a, 0x2f, 0xf0, 0x28, 0xf7, 0x68, 0x2e, 0xcc, 0x3d, 0x7c, 0x02, + 0x68, 0xf2, 0xb0, 0xa1, 0x25, 0xc8, 0xd6, 0x1b, 0x75, 0x55, 0xce, 0xa0, 0x15, 0xc8, 0xd1, 0x65, + 0x6a, 0x1c, 0x1e, 0xca, 0x12, 0x5a, 0x83, 0x65, 0xad, 0x56, 0x53, 0xcb, 0x5a, 0xa1, 0xa5, 0xca, + 0x73, 0xc5, 0x7b, 0xdf, 0xfd, 0x33, 0x9f, 0xf9, 0xee, 0x55, 0x5e, 0xfa, 0xdb, 0xab, 0xbc, 0xf4, + 0xfd, 0xab, 0xbc, 0xf4, 0x8f, 0x57, 0x79, 0xe9, 0x77, 0xff, 0xca, 0x67, 0x3e, 0xcf, 0x89, 0x24, + 0xfe, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x44, 0x6d, 0x68, 0x9c, 0x44, 0x1e, 0x00, 0x00, } diff --git a/pkg/roachpb/errors.proto b/pkg/roachpb/errors.proto index 7ecc967ce823..1c492541ba69 100644 --- a/pkg/roachpb/errors.proto +++ b/pkg/roachpb/errors.proto @@ -200,9 +200,7 @@ enum TransactionRetryReason { RETRY_REASON_UNKNOWN = 0; // A concurrent writer finished first, causing restart. RETRY_WRITE_TOO_OLD = 1; - // A transaction containing a delete range command had its timestamp - // moved forward. - RETRY_DELETE_RANGE = 2; + reserved 2; // A SERIALIZABLE transaction had its timestamp moved forward. RETRY_SERIALIZABLE = 3; // A possible replay caused by duplicate begin txn or out-of-order diff --git a/pkg/roachpb/errors_test.go b/pkg/roachpb/errors_test.go index 8b99bb620575..9531db7f07cd 100644 --- a/pkg/roachpb/errors_test.go +++ b/pkg/roachpb/errors_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/hlc" ) @@ -48,7 +47,7 @@ func TestNewErrorNil(t *testing.T) { // TestSetTxn vefifies that SetTxn updates the error message. func TestSetTxn(t *testing.T) { e := NewError(NewTransactionAbortedError(ABORT_REASON_ABORTED_RECORD_FOUND)) - txn := MakeTransaction("test", Key("a"), 1, enginepb.SERIALIZABLE, hlc.Timestamp{}, 0) + txn := MakeTransaction("test", Key("a"), 1, hlc.Timestamp{}, 0) e.SetTxn(&txn) if !strings.HasPrefix( e.Message, "TransactionAbortedError(ABORT_REASON_ABORTED_RECORD_FOUND): \"test\"") { diff --git a/pkg/roachpb/string_test.go b/pkg/roachpb/string_test.go index 60a257600047..f98e2e2d7556 100644 --- a/pkg/roachpb/string_test.go +++ b/pkg/roachpb/string_test.go @@ -33,7 +33,6 @@ func TestTransactionString(t *testing.T) { } txn := roachpb.Transaction{ TxnMeta: enginepb.TxnMeta{ - Isolation: enginepb.SERIALIZABLE, Key: roachpb.Key("foo"), ID: txnID, Epoch: 2, @@ -47,8 +46,8 @@ func TestTransactionString(t *testing.T) { OrigTimestamp: hlc.Timestamp{WallTime: 30, Logical: 31}, MaxTimestamp: hlc.Timestamp{WallTime: 40, Logical: 41}, } - expStr := `"name" id=d7aa0f5e key="foo" rw=false pri=44.58039917 iso=SERIALIZABLE stat=COMMITTED ` + - `epo=2 ts=0.000000020,21 orig=0.000000030,31 max=0.000000040,41 wto=false rop=false seq=15` + expStr := `"name" id=d7aa0f5e key="foo" rw=false pri=44.58039917 stat=COMMITTED ` + + `epo=2 ts=0.000000020,21 orig=0.000000030,31 max=0.000000040,41 wto=false seq=15` if str := txn.String(); str != expStr { t.Errorf("expected txn %s; got %s", expStr, str) @@ -61,7 +60,6 @@ func TestBatchRequestString(t *testing.T) { "test", nil, /* baseKey */ roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, hlc.Timestamp{}, // now 0, // maxOffsetNs ) diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 33db61c1a784..08839e3a3b5d 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -377,7 +377,7 @@ func TestMultiRangeScanDeleteRange(t *testing.T) { t.Errorf("expected %d keys to be deleted, but got %d instead", writes, dr.Keys) } - txnProto := roachpb.MakeTransaction("MyTxn", nil, 0, 0, s.Clock().Now(), 0) + txnProto := roachpb.MakeTransaction("MyTxn", nil, 0, s.Clock().Now(), 0) txn := client.NewTxnWithProto(ctx, db, s.NodeID(), client.RootTxn, txnProto) scan := roachpb.NewScan(writes[0], writes[len(writes)-1].Next()) diff --git a/pkg/sql/conn_executor.go b/pkg/sql/conn_executor.go index cb8243ed64f0..dff3df57b630 100644 --- a/pkg/sql/conn_executor.go +++ b/pkg/sql/conn_executor.go @@ -37,7 +37,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/cockroachdb/cockroach/pkg/sql/sqlutil" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/cockroach/pkg/util/envutil" "github.com/cockroachdb/cockroach/pkg/util/errorutil" @@ -565,7 +564,6 @@ func (s *Server) newConnExecutorWithTxn( ctx, explicitTxn, txn.OrigTimestamp().GoTime(), - txn.Isolation(), txn.UserPriority(), tree.ReadWrite, txn, @@ -1679,32 +1677,13 @@ func (ex *connExecutor) setTransactionModes(modes tree.TransactionModes) error { return err } } - if modes.Isolation != tree.UnspecifiedIsolation { - iso, err := ex.isolationToProto(modes.Isolation) - if err != nil { - return err - } - if err := ex.state.setIsolationLevel(iso); err != nil { - return err - } + if modes.Isolation != tree.UnspecifiedIsolation && modes.Isolation != tree.SerializableIsolation { + return errors.Errorf("unknown isolation level: %s", modes.Isolation) } return ex.state.setReadOnlyMode(modes.ReadWriteMode) } -func (ex *connExecutor) isolationToProto(mode tree.IsolationLevel) (enginepb.IsolationType, error) { - var iso enginepb.IsolationType - switch mode { - case tree.UnspecifiedIsolation: - iso = ex.sessionData.DefaultIsolationLevel - case tree.SerializableIsolation: - iso = enginepb.SERIALIZABLE - default: - return enginepb.IsolationType(0), errors.Errorf("unknown isolation level: %s", mode) - } - return iso, nil -} - func priorityToProto(mode tree.UserPriority) (roachpb.UserPriority, error) { var pri roachpb.UserPriority switch mode { diff --git a/pkg/sql/conn_executor_exec.go b/pkg/sql/conn_executor_exec.go index 2f6c20b705aa..d955fcec6840 100644 --- a/pkg/sql/conn_executor_exec.go +++ b/pkg/sql/conn_executor_exec.go @@ -547,7 +547,6 @@ func (ex *connExecutor) checkTableTwoVersionInvariant(ctx context.Context) error // TODO(vivek): Change this to restart a txn while fixing #20526 . All the // table descriptor intents can be laid down here after the invariant // has been checked. - isolation := txn.Isolation() userPriority := txn.UserPriority() // We cleanup the transaction and create a new transaction wait time // might be extensive and so we'd better get rid of all the intents. @@ -572,9 +571,6 @@ func (ex *connExecutor) checkTableTwoVersionInvariant(ctx context.Context) error // Create a new transaction to retry with a higher timestamp than the // timestamps used in the retry loop above. ex.state.mu.txn = client.NewTxn(ctx, ex.transitionCtx.db, ex.transitionCtx.nodeID, client.RootTxn) - if err := ex.state.mu.txn.SetIsolation(isolation); err != nil { - return err - } if err := ex.state.mu.txn.SetUserPriority(userPriority); err != nil { return err } @@ -1041,10 +1037,6 @@ func (ex *connExecutor) execStmtInNoTxnState( switch s := stmt.AST.(type) { case *tree.BeginTransaction: ex.incrementStmtCounter(stmt) - iso, err := ex.isolationToProto(s.Modes.Isolation) - if err != nil { - return ex.makeErrEvent(err, s) - } pri, err := priorityToProto(s.Modes.UserPriority) if err != nil { return ex.makeErrEvent(err, s) @@ -1052,7 +1044,7 @@ func (ex *connExecutor) execStmtInNoTxnState( return eventTxnStart{ImplicitTxn: fsm.False}, makeEventTxnStartPayload( - iso, pri, ex.readWriteModeWithSessionDefault(s.Modes.ReadWriteMode), + pri, ex.readWriteModeWithSessionDefault(s.Modes.ReadWriteMode), ex.server.cfg.Clock.PhysicalTime(), ex.transitionCtx) case *tree.CommitTransaction, *tree.ReleaseSavepoint, @@ -1065,7 +1057,6 @@ func (ex *connExecutor) execStmtInNoTxnState( } return eventTxnStart{ImplicitTxn: fsm.True}, makeEventTxnStartPayload( - ex.sessionData.DefaultIsolationLevel, roachpb.NormalUserPriority, mode, ex.server.cfg.Clock.PhysicalTime(), @@ -1160,9 +1151,7 @@ func (ex *connExecutor) execStmtInAbortedState( rwMode = tree.ReadOnly } payload := makeEventTxnStartPayload( - ex.state.isolation, ex.state.priority, - rwMode, ex.state.sqlTimestamp, - ex.transitionCtx) + ex.state.priority, rwMode, ex.state.sqlTimestamp, ex.transitionCtx) return ev, payload default: ev := eventNonRetriableErr{IsCommit: fsm.False} diff --git a/pkg/sql/conn_fsm.go b/pkg/sql/conn_fsm.go index 4aad394cc546..5216a541823a 100644 --- a/pkg/sql/conn_fsm.go +++ b/pkg/sql/conn_fsm.go @@ -26,7 +26,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" // We dot-import fsm to use common names such as fsm.True/False. State machine // implementations using that library are weird beasts intimately inter-twined // with that package; therefor this file should stay as small as possible. @@ -125,7 +124,6 @@ type eventTxnStart struct { type eventTxnStartPayload struct { tranCtx transitionCtx - iso enginepb.IsolationType pri roachpb.UserPriority // txnSQLTimestamp is the timestamp that statements executed in the // transaction that is started by this event will report for now(), @@ -135,14 +133,12 @@ type eventTxnStartPayload struct { } func makeEventTxnStartPayload( - iso enginepb.IsolationType, pri roachpb.UserPriority, readOnly tree.ReadWriteMode, txnSQLTimestamp time.Time, tranCtx transitionCtx, ) eventTxnStartPayload { return eventTxnStartPayload{ - iso: iso, pri: pri, readOnly: readOnly, txnSQLTimestamp: txnSQLTimestamp, @@ -446,7 +442,7 @@ var TxnStateTransitions = Compile(Pattern{ ts.resetForNewSQLTxn( ts.connCtx, explicitTxn, - payload.txnSQLTimestamp, payload.iso, payload.pri, payload.readOnly, + payload.txnSQLTimestamp, payload.pri, payload.readOnly, nil, /* txn */ args.Payload.(eventTxnStartPayload).tranCtx, ) @@ -544,7 +540,6 @@ func (ts *txnState) noTxnToOpen( connCtx, txnTyp, payload.txnSQLTimestamp, - payload.iso, payload.pri, payload.readOnly, nil, /* txn */ diff --git a/pkg/sql/distsqlrun/cluster_test.go b/pkg/sql/distsqlrun/cluster_test.go index 9febeab143fa..3464c3b10608 100644 --- a/pkg/sql/distsqlrun/cluster_test.go +++ b/pkg/sql/distsqlrun/cluster_test.go @@ -27,7 +27,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/cockroachdb/cockroach/pkg/storage" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/storage/storagebase" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" @@ -88,7 +87,6 @@ func TestClusterFlow(t *testing.T) { "cluster-test", nil, // baseKey roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, tc.Server(0).Clock().Now(), 0, // maxOffset ) @@ -391,7 +389,6 @@ func TestLimitedBufferingDeadlock(t *testing.T) { "deadlock-test", nil, // baseKey roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, tc.Server(0).Clock().Now(), 0, // maxOffset ) @@ -646,7 +643,6 @@ func BenchmarkInfrastructure(b *testing.B) { "cluster-test", nil, // baseKey roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, tc.Server(0).Clock().Now(), 0, // maxOffset ) diff --git a/pkg/sql/exec_util.go b/pkg/sql/exec_util.go index e5ac0f564703..02e6b3aaaa5b 100644 --- a/pkg/sql/exec_util.go +++ b/pkg/sql/exec_util.go @@ -49,7 +49,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/cockroachdb/cockroach/pkg/sql/sqlutil" "github.com/cockroachdb/cockroach/pkg/sql/stats" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/bitarray" "github.com/cockroachdb/cockroach/pkg/util/duration" "github.com/cockroachdb/cockroach/pkg/util/hlc" @@ -1605,10 +1604,6 @@ func (m *sessionDataMutator) SetDatabase(dbName string) { m.data.Database = dbName } -func (m *sessionDataMutator) SetDefaultIsolationLevel(iso enginepb.IsolationType) { - m.data.DefaultIsolationLevel = iso -} - func (m *sessionDataMutator) SetDefaultReadOnly(val bool) { m.data.DefaultReadOnly = val } diff --git a/pkg/sql/lease.go b/pkg/sql/lease.go index 6f2a457dace9..cfeb5885f546 100644 --- a/pkg/sql/lease.go +++ b/pkg/sql/lease.go @@ -35,7 +35,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/retry" @@ -317,12 +316,6 @@ func maybeIncrementVersion( if desc.Version == desc.ClusterVersion.Version+1 { return nil } - // Use SERIALIZABLE transactions so that the ModificationTime on the - // descriptor is the commit timestamp. - if txn.Isolation() != enginepb.SERIALIZABLE { - return pgerror.NewErrorf(pgerror.CodeInvalidTransactionStateError, - "transaction involving a schemas change needs to be SERIALIZABLE") - } desc.Version++ // We need to set ModificationTime to the transaction's commit // timestamp. Using CommitTimestamp() guarantees that the diff --git a/pkg/sql/sem/tree/timeconv_test.go b/pkg/sql/sem/tree/timeconv_test.go index 7c35e5415b9b..72f029276358 100644 --- a/pkg/sql/sem/tree/timeconv_test.go +++ b/pkg/sql/sem/tree/timeconv_test.go @@ -23,7 +23,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" _ "github.com/cockroachdb/cockroach/pkg/sql/sem/builtins" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/util/hlc" ) @@ -66,7 +65,6 @@ func TestClusterTimestampConversion(t *testing.T) { "test", nil, // baseKey roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, ts, 0, /* maxOffsetNs */ ), diff --git a/pkg/sql/sem/tree/txn.go b/pkg/sql/sem/tree/txn.go index 50544e4fd0cb..9c32ae0b0e91 100644 --- a/pkg/sql/sem/tree/txn.go +++ b/pkg/sql/sem/tree/txn.go @@ -38,7 +38,6 @@ var isolationLevelNames = [...]string{ // level, in the lowercase format that set isolation_level supports. var IsolationLevelMap = map[string]IsolationLevel{ "serializable": SerializableIsolation, - "snapshot": SerializableIsolation, } func (i IsolationLevel) String() string { diff --git a/pkg/sql/sessiondata/session_data.go b/pkg/sql/sessiondata/session_data.go index f4f8fda34083..312db91cd17d 100644 --- a/pkg/sql/sessiondata/session_data.go +++ b/pkg/sql/sessiondata/session_data.go @@ -20,7 +20,6 @@ import ( "strings" "time" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/duration" ) @@ -34,9 +33,6 @@ type SessionData struct { // Database indicates the "current" database for the purpose of // resolving names. See searchAndQualifyDatabase() for details. Database string - // DefaultIsolationLevel indicates the default isolation level of - // newly created transactions. - DefaultIsolationLevel enginepb.IsolationType // DefaultReadOnly indicates the default read-only status of newly created // transactions. DefaultReadOnly bool diff --git a/pkg/sql/set_default_isolation.go b/pkg/sql/set_default_isolation.go index c9d340f378d4..4573404869f4 100644 --- a/pkg/sql/set_default_isolation.go +++ b/pkg/sql/set_default_isolation.go @@ -19,16 +19,14 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" ) func (p *planner) SetSessionCharacteristics(n *tree.SetSessionCharacteristics) (planNode, error) { // Note: We also support SET DEFAULT_TRANSACTION_ISOLATION TO ' .... ' above. // Ensure both versions stay in sync. switch n.Modes.Isolation { - case tree.SerializableIsolation: - p.sessionDataMutator.SetDefaultIsolationLevel(enginepb.SERIALIZABLE) - case tree.UnspecifiedIsolation: + case tree.SerializableIsolation, tree.UnspecifiedIsolation: + // Do nothing. All transactions execute with serializable isolation. default: return nil, fmt.Errorf("unsupported default isolation level: %s", n.Modes.Isolation) } diff --git a/pkg/sql/txn_state.go b/pkg/sql/txn_state.go index 6c5964ea0328..e20ab2a375c7 100644 --- a/pkg/sql/txn_state.go +++ b/pkg/sql/txn_state.go @@ -22,7 +22,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/contextutil" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/log" @@ -80,9 +79,6 @@ type txnState struct { // This must be constant for the lifetime of a SQL transaction. sqlTimestamp time.Time - // The transaction's isolation level. - isolation enginepb.IsolationType - // The transaction's priority. priority roachpb.UserPriority @@ -133,7 +129,6 @@ const ( // used for everything that happens within this SQL transaction. // txnType: The type of the starting txn. // sqlTimestamp: The timestamp to report for current_timestamp(), now() etc. -// isolation: The transaction's isolation level. // priority: The transaction's priority. // readOnly: The read-only character of the new txn. // txn: If not nil, this txn will be used instead of creating a new txn. If so, @@ -143,7 +138,6 @@ func (ts *txnState) resetForNewSQLTxn( connCtx context.Context, txnType txnType, sqlTimestamp time.Time, - isolation enginepb.IsolationType, priority roachpb.UserPriority, readOnly tree.ReadWriteMode, txn *client.Txn, @@ -211,12 +205,6 @@ func (ts *txnState) resetForNewSQLTxn( } ts.mu.Unlock() - if err := ts.mu.txn.SetIsolation(isolation); err != nil { - panic(err) - } - if err := ts.setIsolationLevel(isolation); err != nil { - panic(err) - } if err := ts.setPriority(priority); err != nil { panic(err) } @@ -284,14 +272,6 @@ func (ts *txnState) finishExternalTxn() { ts.mu.txn = nil } -func (ts *txnState) setIsolationLevel(isolation enginepb.IsolationType) error { - if err := ts.mu.txn.SetIsolation(isolation); err != nil { - return err - } - ts.isolation = isolation - return nil -} - func (ts *txnState) setPriority(userPriority roachpb.UserPriority) error { if err := ts.mu.txn.SetUserPriority(userPriority); err != nil { return err diff --git a/pkg/sql/txn_state_test.go b/pkg/sql/txn_state_test.go index eb098ab9917b..dcf393d9fe20 100644 --- a/pkg/sql/txn_state_test.go +++ b/pkg/sql/txn_state_test.go @@ -25,7 +25,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/testutils" // We dot-import fsm to use common names such as fsm.True/False. . "github.com/cockroachdb/cockroach/pkg/util/fsm" @@ -119,7 +118,6 @@ func (tc *testContext) createOpenState( sp: sp, cancel: cancel, sqlTimestamp: timeutil.Now(), - isolation: enginepb.SERIALIZABLE, priority: roachpb.NormalUserPriority, mon: &txnStateMon, txnAbortCount: metric.NewCounter(MetaTxnAbort), @@ -200,7 +198,6 @@ func checkAdv(adv advanceInfo, expCode advanceCode, expRewPos CmdPos, expEv txnE // correspond to expectations. Any field left nil will not be checked. type expKVTxn struct { debugName *string - isolation *enginepb.IsolationType userPriority *roachpb.UserPriority // For the timestamps we just check the physical part. The logical part is // incremented every time the clock is read and so it's unpredictable. @@ -217,10 +214,6 @@ func checkTxn(txn *client.Txn, exp expKVTxn) error { return errors.Errorf("expected DebugName: %s, but got: %s", *exp.debugName, txn.DebugName()) } - if exp.isolation != nil && *exp.isolation != txn.Isolation() { - return errors.Errorf("expected isolation: %s, but got: %s", - *exp.isolation, txn.Isolation()) - } if exp.userPriority != nil && *exp.userPriority != txn.UserPriority() { return errors.Errorf("expected UserPriority: %s, but got: %s", *exp.userPriority, txn.UserPriority()) @@ -265,7 +258,6 @@ func TestTransitions(t *testing.T) { txnName := sqlTxnName now := testCon.clock.Now() - iso := enginepb.SERIALIZABLE pri := roachpb.NormalUserPriority maxTS := testCon.clock.Now().Add(testCon.clock.MaxOffset().Nanoseconds(), 0 /* logical */) type test struct { @@ -306,7 +298,7 @@ func TestTransitions(t *testing.T) { return s, ts, nil }, ev: eventTxnStart{ImplicitTxn: True}, - evPayload: makeEventTxnStartPayload(iso, pri, tree.ReadWrite, timeutil.Now(), tranCtx), + evPayload: makeEventTxnStartPayload(pri, tree.ReadWrite, timeutil.Now(), tranCtx), expState: stateOpen{ImplicitTxn: True, RetryIntent: False}, expAdv: expAdvance{ // We expect to stayInPlace; upon starting a txn the statement is @@ -316,7 +308,6 @@ func TestTransitions(t *testing.T) { }, expTxn: &expKVTxn{ debugName: &txnName, - isolation: &iso, userPriority: &pri, tsNanos: &now.WallTime, origTSNanos: &now.WallTime, @@ -331,7 +322,7 @@ func TestTransitions(t *testing.T) { return s, ts, nil }, ev: eventTxnStart{ImplicitTxn: False}, - evPayload: makeEventTxnStartPayload(iso, pri, tree.ReadWrite, timeutil.Now(), tranCtx), + evPayload: makeEventTxnStartPayload(pri, tree.ReadWrite, timeutil.Now(), tranCtx), expState: stateOpen{ImplicitTxn: False, RetryIntent: False}, expAdv: expAdvance{ expCode: advanceOne, @@ -339,7 +330,6 @@ func TestTransitions(t *testing.T) { }, expTxn: &expKVTxn{ debugName: &txnName, - isolation: &iso, userPriority: &pri, tsNanos: &now.WallTime, origTSNanos: &now.WallTime, @@ -658,7 +648,7 @@ func TestTransitions(t *testing.T) { return s, ts, nil }, ev: eventTxnStart{ImplicitTxn: False}, - evPayload: makeEventTxnStartPayload(iso, pri, tree.ReadWrite, timeutil.Now(), tranCtx), + evPayload: makeEventTxnStartPayload(pri, tree.ReadWrite, timeutil.Now(), tranCtx), expState: stateOpen{ImplicitTxn: False, RetryIntent: True}, expAdv: expAdvance{ expCode: advanceOne, diff --git a/pkg/sql/vars.go b/pkg/sql/vars.go index b466f7308148..b9b30188e097 100644 --- a/pkg/sql/vars.go +++ b/pkg/sql/vars.go @@ -31,7 +31,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/timeutil" "github.com/cockroachdb/cockroach/pkg/util/tracing" ) @@ -226,7 +225,7 @@ var varGen = map[string]sessionVar{ Set: func(_ context.Context, m *sessionDataMutator, s string) error { switch strings.ToUpper(s) { case `READ UNCOMMITTED`, `READ COMMITTED`, `SNAPSHOT`, `REPEATABLE READ`, `SERIALIZABLE`, `DEFAULT`: - m.SetDefaultIsolationLevel(enginepb.SERIALIZABLE) + // Do nothing. All transactions execute with serializable isolation. default: return newVarValueError(`default_transaction_isolation`, s, "serializable") } @@ -234,7 +233,7 @@ var varGen = map[string]sessionVar{ return nil }, Get: func(evalCtx *extendedEvalContext) string { - return evalCtx.SessionData.DefaultIsolationLevel.ToLowerCaseString() + return "serializable" }, GlobalDefault: func(sv *settings.Values) string { return "default" }, }, @@ -563,17 +562,14 @@ var varGen = map[string]sessionVar{ // See https://github.com/postgres/postgres/blob/REL_10_STABLE/src/backend/utils/misc/guc.c#L3401-L3409 `transaction_isolation`: { Get: func(evalCtx *extendedEvalContext) string { - return evalCtx.Txn.Isolation().ToLowerCaseString() + return "serializable" }, RuntimeSet: func(_ context.Context, evalCtx *extendedEvalContext, s string) error { - isolationLevel, ok := tree.IsolationLevelMap[s] + _, ok := tree.IsolationLevelMap[s] if !ok { return newVarValueError(`transaction_isolation`, s, "serializable") } - return evalCtx.TxnModesSetter.setTransactionModes( - tree.TransactionModes{ - Isolation: isolationLevel, - }) + return nil }, GlobalDefault: func(_ *settings.Values) string { return "serializable" }, }, diff --git a/pkg/storage/batcheval/cmd_add_sstable_test.go b/pkg/storage/batcheval/cmd_add_sstable_test.go index 2360cf50f209..316ae1fa9e2e 100644 --- a/pkg/storage/batcheval/cmd_add_sstable_test.go +++ b/pkg/storage/batcheval/cmd_add_sstable_test.go @@ -299,7 +299,6 @@ func TestAddSSTableMVCCStats(t *testing.T) { "test", nil, // baseKey roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, ts, base.DefaultMaxClockOffset.Nanoseconds(), ) diff --git a/pkg/storage/batcheval/cmd_delete_range.go b/pkg/storage/batcheval/cmd_delete_range.go index a7b3e3757cd0..1554004fe80d 100644 --- a/pkg/storage/batcheval/cmd_delete_range.go +++ b/pkg/storage/batcheval/cmd_delete_range.go @@ -20,7 +20,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/batcheval/result" "github.com/cockroachdb/cockroach/pkg/storage/engine" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/hlc" ) @@ -46,13 +45,6 @@ func DeleteRange( ) if err == nil { reply.Keys = deleted - // DeleteRange requires that we retry on push (for snapshot) to - // avoid the lost delete range anomaly. - if h.Txn != nil && h.Txn.Isolation == enginepb.SNAPSHOT { - clonedTxn := h.Txn.Clone() - clonedTxn.RetryOnPush = true - reply.Txn = &clonedTxn - } } reply.NumKeys = num if resumeSpan != nil { diff --git a/pkg/storage/batcheval/cmd_end_transaction.go b/pkg/storage/batcheval/cmd_end_transaction.go index 7cdae20925e6..727e5a067458 100644 --- a/pkg/storage/batcheval/cmd_end_transaction.go +++ b/pkg/storage/batcheval/cmd_end_transaction.go @@ -383,21 +383,15 @@ func IsEndTransactionTriggeringRetryError( origTimestamp.Forward(txn.RefreshedTimestamp) isTxnPushed := txn.Timestamp != origTimestamp - // If the isolation level is SERIALIZABLE, return a transaction - // retry error if the commit timestamp isn't equal to the txn - // timestamp. + // Return a transaction retry error if the commit timestamp isn't equal to + // the txn timestamp. if isTxnPushed { - if txn.Isolation == enginepb.SERIALIZABLE { - retry, reason = true, roachpb.RETRY_SERIALIZABLE - } else if txn.RetryOnPush { - // If pushing requires a retry and the transaction was pushed, retry. - retry, reason = true, roachpb.RETRY_DELETE_RANGE - } + retry, reason = true, roachpb.RETRY_SERIALIZABLE } } - // A serializable transaction can still avoid a retry under certain conditions. - if retry && txn.IsSerializable() && canForwardSerializableTimestamp(txn, args.NoRefreshSpans) { + // A transaction can still avoid a retry under certain conditions. + if retry && canForwardSerializableTimestamp(txn, args.NoRefreshSpans) { retry, reason = false, 0 } diff --git a/pkg/storage/batcheval/cmd_push_txn.go b/pkg/storage/batcheval/cmd_push_txn.go index a8a4325a70d4..ac925d2a8b4f 100644 --- a/pkg/storage/batcheval/cmd_push_txn.go +++ b/pkg/storage/batcheval/cmd_push_txn.go @@ -22,7 +22,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/batcheval/result" "github.com/cockroachdb/cockroach/pkg/storage/engine" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/storage/spanset" "github.com/cockroachdb/cockroach/pkg/storage/txnwait" "github.com/cockroachdb/cockroach/pkg/util/hlc" @@ -187,11 +186,6 @@ func PushTxn( // If just attempting to cleanup old or already-committed txns, // pusher always fails. pusherWins = false - case args.PushType == roachpb.PUSH_TIMESTAMP && - reply.PusheeTxn.Isolation == enginepb.SNAPSHOT: - // Can always push a SNAPSHOT txn's timestamp. - reason = "pushee is SNAPSHOT" - pusherWins = true case CanPushWithPriority(&args.PusherTxn, &reply.PusheeTxn): reason = "pusher has priority" pusherWins = true diff --git a/pkg/storage/batcheval/cmd_query_intent.go b/pkg/storage/batcheval/cmd_query_intent.go index 48c0c8e541a8..38b2c0539204 100644 --- a/pkg/storage/batcheval/cmd_query_intent.go +++ b/pkg/storage/batcheval/cmd_query_intent.go @@ -20,7 +20,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/batcheval/result" "github.com/cockroachdb/cockroach/pkg/storage/engine" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/pkg/errors" @@ -40,15 +39,6 @@ func QueryIntent( h := cArgs.Header reply := resp.(*roachpb.QueryIntentResponse) - // Snapshot transactions cannot be prevented using a QueryIntent command. - // This is because we use the timestamp cache to prevent a transaction from - // committing, but a SNAPSHOT transaction does not need to restart/abort if - // it runs into the timestamp cache and its timestamp is pushed forwards. - if args.Txn.Isolation == enginepb.SNAPSHOT && - args.IfMissing == roachpb.QueryIntentRequest_PREVENT { - return result.Result{}, errors.Errorf("cannot prevent SNAPSHOT transaction with QueryIntent") - } - // Read at the specified key at the maximum timestamp. This ensures that we // see an intent if one exists, regardless of what timestamp it is written // at. @@ -83,14 +73,10 @@ func QueryIntent( // Check whether the intent was pushed past its expected timestamp. if reply.FoundIntent && args.Txn.Timestamp.Less(curIntent.Txn.Timestamp) { - // The intent matched but was pushed to a later timestamp. + // The intent matched but was pushed to a later timestamp. Consider a + // pushed intent a missing intent. curIntentPushed = true - - // If the transaction is SERIALIZABLE, consider a pushed intent as a - // missing intent. If the transaction is SNAPSHOT, don't. - if args.Txn.Isolation == enginepb.SERIALIZABLE { - reply.FoundIntent = false - } + reply.FoundIntent = false // If the request was querying an intent in its own transaction, update // the response transaction. diff --git a/pkg/storage/below_raft_protos_test.go b/pkg/storage/below_raft_protos_test.go index 895f296bd821..9f8eda55fd11 100644 --- a/pkg/storage/below_raft_protos_test.go +++ b/pkg/storage/below_raft_protos_test.go @@ -63,7 +63,7 @@ var belowRaftGoldenProtos = map[reflect.Type]fixture{ return m }, emptySum: 7551962144604783939, - populatedSum: 3716674106872807900, + populatedSum: 4484813141137719798, }, reflect.TypeOf(&enginepb.RangeAppliedState{}): { populatedConstructor: func(r *rand.Rand) protoutil.Message { diff --git a/pkg/storage/client_metrics_test.go b/pkg/storage/client_metrics_test.go index 6a9e6c44a40e..c3d94c02f2bc 100644 --- a/pkg/storage/client_metrics_test.go +++ b/pkg/storage/client_metrics_test.go @@ -25,7 +25,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" "github.com/cockroachdb/cockroach/pkg/storage/batcheval/result" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/leaktest" @@ -178,7 +177,7 @@ func TestStoreResolveMetrics(t *testing.T) { span := roachpb.Span{Key: roachpb.Key("a"), EndKey: roachpb.Key("b")} - txn := roachpb.MakeTransaction("foo", span.Key, roachpb.MinUserPriority, enginepb.SERIALIZABLE, hlc.Timestamp{WallTime: 123}, 999) + txn := roachpb.MakeTransaction("foo", span.Key, roachpb.MinUserPriority, hlc.Timestamp{WallTime: 123}, 999) const resolveCommitCount = int64(200) const resolveAbortCount = int64(800) diff --git a/pkg/storage/client_replica_test.go b/pkg/storage/client_replica_test.go index c011246327f5..0c7112ea8cb1 100644 --- a/pkg/storage/client_replica_test.go +++ b/pkg/storage/client_replica_test.go @@ -34,7 +34,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/storage" "github.com/cockroachdb/cockroach/pkg/storage/batcheval" "github.com/cockroachdb/cockroach/pkg/storage/engine" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/storage/storagebase" "github.com/cockroachdb/cockroach/pkg/storage/storagepb" "github.com/cockroachdb/cockroach/pkg/testutils" @@ -895,7 +894,7 @@ func TestRangeLimitTxnMaxTimestamp(t *testing.T) { mtc.clocks = []*hlc.Clock{clock1, clock2} // Start a transaction using node2 as a gateway. - txn := roachpb.MakeTransaction("test", keyA, 1, enginepb.SERIALIZABLE, clock2.Now(), 250 /* maxOffsetNs */) + txn := roachpb.MakeTransaction("test", keyA, 1, clock2.Now(), 250 /* maxOffsetNs */) // Simulate a read to another range on node2 by setting the observed timestamp. txn.UpdateObservedTimestamp(2, clock2.Now()) @@ -1478,7 +1477,7 @@ func TestRangeInfo(t *testing.T) { EndKey: roachpb.KeyMax, }, } - txn := roachpb.MakeTransaction("test", roachpb.KeyMin, 1, enginepb.SERIALIZABLE, mtc.clock.Now(), 0) + txn := roachpb.MakeTransaction("test", roachpb.KeyMin, 1, mtc.clock.Now(), 0) h.Txn = &txn reply, pErr = client.SendWrappedWith(context.Background(), mtc.distSenders[0], h, &scanArgs) if pErr != nil { diff --git a/pkg/storage/client_split_test.go b/pkg/storage/client_split_test.go index e3db91c3bad7..93031634a02d 100644 --- a/pkg/storage/client_split_test.go +++ b/pkg/storage/client_split_test.go @@ -120,7 +120,7 @@ func TestStoreSplitAbortSpan(t *testing.T) { left, middle, right := roachpb.Key("a"), roachpb.Key("b"), roachpb.Key("c") txn := func(key roachpb.Key, ts hlc.Timestamp) *roachpb.Transaction { - txn := roachpb.MakeTransaction("test", key, 0, enginepb.SERIALIZABLE, ts, 0) + txn := roachpb.MakeTransaction("test", key, 0, ts, 0) return &txn } @@ -594,8 +594,7 @@ func TestStoreRangeSplitIdempotency(t *testing.T) { // Increments are a good way of testing idempotency. Up here, we // address them to the original range, then later to the one that // contains the key. - txn := roachpb.MakeTransaction("test", []byte("c"), 10, enginepb.SERIALIZABLE, - store.Clock().Now(), 0) + txn := roachpb.MakeTransaction("test", []byte("c"), 10, store.Clock().Now(), 0) lIncArgs := incrementArgs([]byte("apoptosis"), 100) lTxn := txn lTxn.Sequence++ @@ -3164,7 +3163,7 @@ func TestRangeLookupAsyncResolveIntent(t *testing.T) { if err != nil { t.Fatal(err) } - txn := roachpb.MakeTransaction("test", key2, 1, enginepb.SERIALIZABLE, + txn := roachpb.MakeTransaction("test", key2, 1, store.Clock().Now(), store.Clock().MaxOffset().Nanoseconds()) // Officially begin the transaction. If not for this, the intent resolution // machinery would simply remove the intent we write below, see #3020. diff --git a/pkg/storage/closed_timestamp_test.go b/pkg/storage/closed_timestamp_test.go index 4ad2ac48cd93..9ba73683848b 100644 --- a/pkg/storage/closed_timestamp_test.go +++ b/pkg/storage/closed_timestamp_test.go @@ -23,7 +23,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/base" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" "github.com/cockroachdb/cockroach/pkg/util" @@ -183,7 +182,7 @@ CREATE TABLE cttest.kv (id INT PRIMARY KEY, value STRING); var baWrite roachpb.BatchRequest r := &roachpb.DeleteRequest{} r.Key = desc.StartKey.AsRawKey() - txn := roachpb.MakeTransaction("testwrite", r.Key, roachpb.NormalUserPriority, enginepb.SERIALIZABLE, baRead.Timestamp, 100) + txn := roachpb.MakeTransaction("testwrite", r.Key, roachpb.NormalUserPriority, baRead.Timestamp, 100) baWrite.Txn = &txn baWrite.Add(r) baWrite.RangeID = repls[0].RangeID diff --git a/pkg/storage/engine/enginepb/mvcc3.go b/pkg/storage/engine/enginepb/mvcc3.go index fd0feb83123f..adf442d7d8a6 100644 --- a/pkg/storage/engine/enginepb/mvcc3.go +++ b/pkg/storage/engine/enginepb/mvcc3.go @@ -14,11 +14,7 @@ package enginepb -import ( - "fmt" - - proto "github.com/gogo/protobuf/proto" -) +import "fmt" // ToStats converts the receiver to an MVCCStats. func (ms *MVCCStatsDelta) ToStats() MVCCStats { @@ -40,18 +36,6 @@ func (ms *MVCCStats) ToPersistentStats() MVCCPersistentStats { return MVCCPersistentStats(*ms) } -var isolationTypeLowerCase = map[int32]string{ - 0: "serializable", - 1: "snapshot", -} - -// ToLowerCaseString returns the lower case version of String(). -// Asking for lowercase is common enough (pg_setting / SHOW in SQL) -// that we don't want to call strings.ToLower(x.String()) all the time. -func (x IsolationType) ToLowerCaseString() string { - return proto.EnumName(isolationTypeLowerCase, int32(x)) -} - // MustSetValue is like SetValue, except it resets the enum and panics if the // provided value is not a valid variant type. func (op *MVCCLogicalOp) MustSetValue(value interface{}) { diff --git a/pkg/storage/engine/enginepb/mvcc3.pb.go b/pkg/storage/engine/enginepb/mvcc3.pb.go index cd1e3abccfbf..86a4abf374b3 100644 --- a/pkg/storage/engine/enginepb/mvcc3.pb.go +++ b/pkg/storage/engine/enginepb/mvcc3.pb.go @@ -21,35 +21,11 @@ var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf -// TODO(tschottdorf): Should not live in enginepb (but can't live in roachpb -// either). -type IsolationType int32 - -const ( - SERIALIZABLE IsolationType = 0 - SNAPSHOT IsolationType = 1 -) - -var IsolationType_name = map[int32]string{ - 0: "SERIALIZABLE", - 1: "SNAPSHOT", -} -var IsolationType_value = map[string]int32{ - "SERIALIZABLE": 0, - "SNAPSHOT": 1, -} - -func (x IsolationType) String() string { - return proto.EnumName(IsolationType_name, int32(x)) -} -func (IsolationType) EnumDescriptor() ([]byte, []int) { return fileDescriptorMvcc3, []int{0} } - // TxnMeta is the metadata of a Transaction record. type TxnMeta struct { // id is a unique UUID value which identifies the transaction. // This field is always filled in. - ID github_com_cockroachdb_cockroach_pkg_util_uuid.UUID `protobuf:"bytes,1,opt,name=id,proto3,customtype=github.com/cockroachdb/cockroach/pkg/util/uuid.UUID" json:"id"` - Isolation IsolationType `protobuf:"varint,2,opt,name=isolation,proto3,enum=cockroach.storage.engine.enginepb.IsolationType" json:"isolation,omitempty"` + ID github_com_cockroachdb_cockroach_pkg_util_uuid.UUID `protobuf:"bytes,1,opt,name=id,proto3,customtype=github.com/cockroachdb/cockroach/pkg/util/uuid.UUID" json:"id"` // key is the key which anchors the transaction. This is typically // the first key read or written during the transaction and // determines which range in the cluster will hold the transaction @@ -258,7 +234,6 @@ func init() { proto.RegisterType((*MVCCCommitIntentOp)(nil), "cockroach.storage.engine.enginepb.MVCCCommitIntentOp") proto.RegisterType((*MVCCAbortIntentOp)(nil), "cockroach.storage.engine.enginepb.MVCCAbortIntentOp") proto.RegisterType((*MVCCLogicalOp)(nil), "cockroach.storage.engine.enginepb.MVCCLogicalOp") - proto.RegisterEnum("cockroach.storage.engine.enginepb.IsolationType", IsolationType_name, IsolationType_value) } func (this *TxnMeta) Equal(that interface{}) bool { if that == nil { @@ -282,9 +257,6 @@ func (this *TxnMeta) Equal(that interface{}) bool { if !this.ID.Equal(that1.ID) { return false } - if this.Isolation != that1.Isolation { - return false - } if !bytes.Equal(this.Key, that1.Key) { return false } @@ -484,11 +456,6 @@ func (m *TxnMeta) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n1 - if m.Isolation != 0 { - dAtA[i] = 0x10 - i++ - i = encodeVarintMvcc3(dAtA, i, uint64(m.Isolation)) - } if len(m.Key) > 0 { dAtA[i] = 0x1a i++ @@ -1019,7 +986,6 @@ func NewPopulatedTxnMeta(r randyMvcc3, easy bool) *TxnMeta { this := &TxnMeta{} v1 := github_com_cockroachdb_cockroach_pkg_util_uuid.NewPopulatedUUID(r) this.ID = *v1 - this.Isolation = IsolationType([]int32{0, 1}[r.Intn(2)]) v2 := r.Intn(100) this.Key = make([]byte, v2) for i := 0; i < v2; i++ { @@ -1193,9 +1159,6 @@ func (m *TxnMeta) Size() (n int) { _ = l l = m.ID.Size() n += 1 + l + sovMvcc3(uint64(l)) - if m.Isolation != 0 { - n += 1 + sovMvcc3(uint64(m.Isolation)) - } l = len(m.Key) if l > 0 { n += 1 + l + sovMvcc3(uint64(l)) @@ -1527,25 +1490,6 @@ func (m *TxnMeta) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Isolation", wireType) - } - m.Isolation = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowMvcc3 - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Isolation |= (IsolationType(b) & 0x7F) << shift - if b < 0x80 { - break - } - } case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) @@ -3390,73 +3334,69 @@ var ( func init() { proto.RegisterFile("storage/engine/enginepb/mvcc3.proto", fileDescriptorMvcc3) } var fileDescriptorMvcc3 = []byte{ - // 1079 bytes of a gzipped FileDescriptorProto + // 1013 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xaf, 0xe3, 0xa4, 0x4d, 0x5e, 0xd2, 0x92, 0xce, 0x56, 0x10, 0x15, 0x6d, 0x92, 0x0d, 0x97, - 0x68, 0x05, 0xce, 0xaa, 0xdd, 0xe5, 0xd0, 0x5b, 0xd2, 0x56, 0x10, 0xd1, 0x6d, 0x97, 0x69, 0xba, - 0x2b, 0x2d, 0x42, 0xd6, 0xc4, 0x19, 0x9c, 0x51, 0x1d, 0xdb, 0xd8, 0x93, 0x6e, 0x73, 0xe0, 0xce, - 0x0d, 0x3e, 0x42, 0x25, 0xbe, 0x02, 0x07, 0x3e, 0x42, 0x0f, 0x1c, 0xb8, 0x20, 0xa1, 0x15, 0xaa, - 0x20, 0x5c, 0xf8, 0x00, 0x5c, 0x91, 0xd0, 0xcc, 0xd8, 0x4e, 0xb2, 0x82, 0xf4, 0x9f, 0x54, 0x71, - 0x8a, 0xdf, 0xfb, 0xbd, 0xdf, 0x7b, 0xf3, 0xe6, 0xf7, 0xfc, 0x1c, 0x78, 0x2f, 0xe4, 0x5e, 0x40, - 0x6c, 0xda, 0xa0, 0xae, 0xcd, 0xdc, 0xf8, 0xc7, 0xef, 0x36, 0x06, 0x27, 0x96, 0xb5, 0x69, 0xf8, - 0x81, 0xc7, 0x3d, 0xf4, 0xc0, 0xf2, 0xac, 0xe3, 0xc0, 0x23, 0x56, 0xdf, 0x88, 0xc2, 0x0d, 0x15, - 0x67, 0xc4, 0xe1, 0xeb, 0xa5, 0x21, 0x67, 0x4e, 0xa3, 0xef, 0x58, 0x0d, 0xce, 0x06, 0x34, 0xe4, - 0x64, 0xe0, 0x2b, 0xf2, 0xfa, 0x9a, 0xed, 0xd9, 0x9e, 0x7c, 0x6c, 0x88, 0x27, 0xe5, 0xad, 0x7d, - 0xa3, 0xc3, 0x52, 0xe7, 0xd4, 0x7d, 0x4a, 0x39, 0x41, 0x9f, 0x42, 0x8a, 0xf5, 0x4a, 0x5a, 0x55, - 0xab, 0x17, 0x5a, 0xcd, 0xf3, 0x8b, 0xca, 0xc2, 0xeb, 0x8b, 0xca, 0xa6, 0xcd, 0x78, 0x7f, 0xd8, - 0x35, 0x2c, 0x6f, 0xd0, 0x48, 0xaa, 0xf7, 0xba, 0x93, 0xe7, 0x86, 0x7f, 0x6c, 0x37, 0x64, 0xd1, - 0xe1, 0x90, 0xf5, 0x8c, 0xa3, 0xa3, 0xf6, 0xce, 0xf8, 0xa2, 0x92, 0x6a, 0xef, 0xe0, 0x14, 0xeb, - 0xa1, 0x7d, 0xc8, 0xb1, 0xd0, 0x73, 0x08, 0x67, 0x9e, 0x5b, 0x4a, 0x55, 0xb5, 0xfa, 0xca, 0xc6, - 0x23, 0xe3, 0xd2, 0x2e, 0x8c, 0x76, 0xcc, 0xe9, 0x8c, 0x7c, 0x8a, 0x27, 0x29, 0x50, 0x11, 0xf4, - 0x63, 0x3a, 0x2a, 0xe9, 0xe2, 0x8c, 0x58, 0x3c, 0xa2, 0x35, 0xc8, 0x50, 0xdf, 0xb3, 0xfa, 0xa5, - 0x74, 0x55, 0xab, 0x2f, 0x63, 0x65, 0xa0, 0x26, 0xe4, 0x92, 0xfe, 0x4b, 0x99, 0xaa, 0x56, 0xcf, - 0x6f, 0xdc, 0x9f, 0xaa, 0x2b, 0xce, 0x6b, 0xf4, 0x1d, 0xcb, 0xe8, 0xc4, 0x41, 0xad, 0xb4, 0x68, - 0x18, 0x4f, 0x58, 0x68, 0x1d, 0xb2, 0x7e, 0xc0, 0xbc, 0x80, 0xf1, 0x51, 0x69, 0xb1, 0xaa, 0xd5, - 0x33, 0x38, 0xb1, 0x05, 0x16, 0xd2, 0x2f, 0x87, 0xd4, 0xb5, 0x68, 0x69, 0x49, 0x61, 0xb1, 0x8d, - 0x1e, 0xc3, 0xdb, 0x3d, 0xea, 0x07, 0xd4, 0x22, 0x9c, 0xf6, 0xcc, 0x2e, 0xe1, 0x56, 0xdf, 0x64, - 0x6e, 0x8f, 0x9e, 0x96, 0xb2, 0x32, 0x72, 0x6d, 0x82, 0xb6, 0x04, 0xd8, 0x16, 0xd8, 0x56, 0xf6, - 0x87, 0xb3, 0x8a, 0xf6, 0xe7, 0x59, 0x45, 0xab, 0xfd, 0xa5, 0xc3, 0xca, 0xd3, 0xe7, 0xdb, 0xdb, - 0x87, 0x9c, 0xf0, 0x70, 0x87, 0x3a, 0x9c, 0xa0, 0x87, 0xb0, 0xea, 0x90, 0x90, 0x9b, 0x43, 0xbf, - 0x47, 0x38, 0x35, 0x5d, 0xe2, 0x7a, 0xa1, 0xd4, 0xa9, 0x88, 0xdf, 0x12, 0xc0, 0x91, 0xf4, 0xef, - 0x0b, 0x37, 0xba, 0x0f, 0xc0, 0x5c, 0x4e, 0x5d, 0x6e, 0x12, 0x9b, 0xca, 0x2b, 0x2f, 0xe2, 0x9c, - 0xf2, 0x34, 0x6d, 0x8a, 0x1e, 0x41, 0xc1, 0xb6, 0xcc, 0xee, 0x88, 0xd3, 0x50, 0x06, 0x88, 0x9b, - 0x2c, 0xb6, 0x56, 0xc6, 0x17, 0x15, 0xf8, 0x68, 0xbb, 0x25, 0xdc, 0x4d, 0x9b, 0x62, 0xb0, 0xad, - 0xf8, 0x59, 0x24, 0x74, 0xd8, 0x09, 0x55, 0x1c, 0x79, 0xcb, 0x08, 0xe7, 0x84, 0x47, 0x46, 0x24, - 0xb0, 0xe5, 0x0d, 0x5d, 0x2e, 0xaf, 0x3a, 0x82, 0xb7, 0x85, 0x03, 0xbd, 0x0b, 0xb9, 0x63, 0x3a, - 0x8a, 0xc8, 0x8b, 0x12, 0xcd, 0x1e, 0xd3, 0x91, 0xe2, 0x46, 0xa0, 0xa2, 0x2e, 0x25, 0x60, 0xc2, - 0x3c, 0x21, 0x4e, 0xc4, 0xcc, 0x2a, 0xf0, 0x84, 0x38, 0x09, 0x53, 0x80, 0x8a, 0x99, 0x4b, 0x40, - 0xc5, 0x7c, 0x00, 0x85, 0xe8, 0x0a, 0x14, 0x19, 0x24, 0x9e, 0x57, 0x3e, 0xc5, 0x9f, 0x84, 0xa8, - 0x14, 0xf9, 0xe9, 0x90, 0xa4, 0x7e, 0x38, 0x0a, 0xa3, 0x14, 0x05, 0x55, 0x22, 0x1c, 0x85, 0x49, - 0x7d, 0x01, 0x2a, 0xf2, 0x72, 0x02, 0x2a, 0xe6, 0x07, 0x80, 0x2c, 0xcf, 0xe5, 0x84, 0xb9, 0xa1, - 0x49, 0x43, 0xce, 0x06, 0x44, 0xa4, 0x58, 0xa9, 0x6a, 0xf5, 0x2c, 0x5e, 0x8d, 0x91, 0xdd, 0x18, - 0xd8, 0x4a, 0x4b, 0xd9, 0xff, 0xd6, 0xe1, 0x9e, 0x90, 0xfd, 0x19, 0x0d, 0x42, 0x16, 0x8a, 0x63, - 0xc8, 0x01, 0xf8, 0xbf, 0x69, 0xaf, 0xcf, 0xd7, 0x5e, 0x9f, 0xab, 0xbd, 0x3e, 0x4f, 0x7b, 0x7d, - 0x9e, 0xf6, 0xfa, 0x3c, 0xed, 0xf5, 0x4b, 0xb4, 0xd7, 0x2f, 0xd7, 0x5e, 0xbf, 0x44, 0x7b, 0x7d, - 0x9e, 0xf6, 0xfa, 0xcd, 0xb5, 0x9f, 0xbc, 0xf6, 0xaf, 0x35, 0x58, 0xc5, 0xc4, 0xb5, 0x69, 0xd3, - 0xf7, 0x1d, 0x46, 0x7b, 0x42, 0x7d, 0x8a, 0xde, 0x07, 0x14, 0x90, 0x2f, 0xb8, 0x49, 0x94, 0x33, - 0x5a, 0x24, 0x42, 0xfe, 0x34, 0x2e, 0x0a, 0x24, 0x8a, 0x96, 0x4b, 0x04, 0x19, 0x70, 0xcf, 0xa1, - 0x24, 0xa4, 0x6f, 0x84, 0xa7, 0x64, 0xf8, 0xaa, 0x84, 0x66, 0xe2, 0x3f, 0x87, 0x7c, 0x20, 0x4a, - 0x9a, 0xa1, 0x18, 0x35, 0x39, 0x0f, 0xf9, 0x8d, 0x0f, 0xaf, 0xb0, 0x9f, 0xff, 0x65, 0x50, 0xa3, - 0x05, 0x0a, 0x32, 0xa1, 0xf4, 0x4c, 0x35, 0xf7, 0x15, 0x14, 0x05, 0xe5, 0x45, 0xc0, 0x38, 0x7d, - 0x4e, 0x9c, 0x21, 0x3d, 0xf0, 0xe3, 0x55, 0xae, 0x4d, 0x56, 0xf9, 0xcc, 0xd2, 0x4e, 0xdd, 0x68, - 0x69, 0xaf, 0x41, 0xe6, 0x44, 0xe4, 0x8f, 0xbe, 0x10, 0xca, 0xa8, 0xfd, 0xa8, 0xc1, 0x6a, 0x52, - 0xbf, 0x2d, 0x75, 0x3e, 0xf0, 0xd1, 0x67, 0xb0, 0xc8, 0x4f, 0x5d, 0x33, 0xf9, 0xe4, 0xed, 0xdc, - 0xee, 0x93, 0x97, 0xe9, 0x9c, 0xba, 0xed, 0x1d, 0x9c, 0xe1, 0xa7, 0x6e, 0xbb, 0x87, 0xde, 0x81, - 0x25, 0x91, 0x5c, 0x74, 0x98, 0x92, 0x47, 0x11, 0xb5, 0x3e, 0x79, 0xb3, 0x49, 0xfd, 0x26, 0x4d, - 0xd6, 0xbe, 0xd7, 0x00, 0x89, 0x76, 0xd4, 0xab, 0x7f, 0x37, 0xfd, 0xdc, 0x5e, 0x9b, 0xda, 0xaf, - 0xd1, 0xb1, 0xb7, 0xbd, 0xc1, 0x80, 0xf1, 0xbb, 0x39, 0x76, 0x34, 0x64, 0xa9, 0xff, 0x18, 0x32, - 0xfd, 0x76, 0x43, 0x96, 0x9e, 0x1e, 0x32, 0x5f, 0xcd, 0x58, 0xb3, 0xeb, 0x05, 0x77, 0xd3, 0x5c, - 0xed, 0x67, 0x1d, 0x96, 0x45, 0xc9, 0x3d, 0xcf, 0x66, 0x16, 0x71, 0x0e, 0x7c, 0xd4, 0x81, 0xfc, - 0x2b, 0x31, 0xe3, 0xa6, 0x3a, 0x9f, 0x26, 0xdb, 0xdb, 0xbc, 0xe2, 0x0b, 0x3d, 0xfd, 0x76, 0x62, - 0x78, 0x95, 0x58, 0xe8, 0x05, 0x14, 0x54, 0x56, 0xb5, 0x22, 0x23, 0xf9, 0x1f, 0x5f, 0x27, 0x6d, - 0x7c, 0x21, 0x58, 0x9d, 0x4f, 0x99, 0xe8, 0x25, 0x2c, 0x47, 0x9f, 0xb5, 0x28, 0xb3, 0xd2, 0xe3, - 0xc9, 0x15, 0x33, 0xcf, 0xce, 0x3f, 0x2e, 0x0c, 0xa7, 0x6c, 0x91, 0xdb, 0x92, 0x83, 0x16, 0xe7, - 0x4e, 0x5f, 0x2b, 0xf7, 0xec, 0x90, 0xe2, 0x82, 0x35, 0x65, 0x8b, 0x0b, 0x21, 0x42, 0xe6, 0x38, - 0x75, 0xe6, 0x5a, 0x17, 0x32, 0x33, 0x21, 0x38, 0x4f, 0x26, 0xe6, 0x56, 0xfa, 0xfc, 0xac, 0xa2, - 0x3d, 0x7c, 0x02, 0xcb, 0x33, 0x7f, 0x80, 0x51, 0x11, 0x0a, 0x87, 0xbb, 0xb8, 0xdd, 0xdc, 0x6b, - 0xbf, 0x6c, 0xb6, 0xf6, 0x76, 0x8b, 0x0b, 0xa8, 0x00, 0xd9, 0xc3, 0xfd, 0xe6, 0xb3, 0xc3, 0x8f, - 0x0f, 0x3a, 0x45, 0x6d, 0x3d, 0xfd, 0xf5, 0x77, 0xe5, 0x85, 0x56, 0xe9, 0xfc, 0xf7, 0xf2, 0xc2, - 0xf9, 0xb8, 0xac, 0xfd, 0x34, 0x2e, 0x6b, 0xbf, 0x8c, 0xcb, 0xda, 0x6f, 0xe3, 0xb2, 0xf6, 0xed, - 0x1f, 0xe5, 0x85, 0xee, 0xa2, 0xfc, 0xaf, 0xbf, 0xf9, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x53, - 0xce, 0xdc, 0x9b, 0x65, 0x0c, 0x00, 0x00, + 0x14, 0xaf, 0xed, 0xa4, 0x4d, 0x26, 0x69, 0x49, 0x66, 0x2b, 0xb0, 0x8a, 0x36, 0xc9, 0x86, 0x4b, + 0x84, 0xc0, 0x41, 0xdb, 0x85, 0x43, 0x6f, 0xf9, 0x83, 0x50, 0x80, 0xa5, 0x60, 0xda, 0x5d, 0x09, + 0x84, 0xac, 0xc9, 0x78, 0x70, 0x46, 0x71, 0x6c, 0x63, 0x8f, 0xb3, 0xc9, 0x81, 0xef, 0xc0, 0x47, + 0xe8, 0x87, 0xe0, 0xc0, 0x17, 0x40, 0xea, 0x81, 0x03, 0x17, 0x24, 0xb4, 0x42, 0x15, 0x84, 0x0b, + 0x1f, 0x80, 0x2b, 0x12, 0x9a, 0x19, 0xdb, 0x49, 0x56, 0x90, 0xfe, 0x93, 0xaa, 0x3d, 0x65, 0xde, + 0xfb, 0xbd, 0xf7, 0x7b, 0xf3, 0xe6, 0xf7, 0x3c, 0x13, 0xf0, 0x46, 0xc4, 0xfc, 0x10, 0x39, 0xa4, + 0x4d, 0x3c, 0x87, 0x7a, 0xe9, 0x4f, 0x30, 0x6c, 0x4f, 0xa6, 0x18, 0x1f, 0x1a, 0x41, 0xe8, 0x33, + 0x1f, 0x3e, 0xc0, 0x3e, 0x1e, 0x87, 0x3e, 0xc2, 0x23, 0x23, 0x09, 0x37, 0x64, 0x9c, 0x91, 0x86, + 0x1f, 0xe8, 0x31, 0xa3, 0x6e, 0x7b, 0xe4, 0xe2, 0x36, 0xa3, 0x13, 0x12, 0x31, 0x34, 0x09, 0x64, + 0xf2, 0xc1, 0xbe, 0xe3, 0x3b, 0xbe, 0x58, 0xb6, 0xf9, 0x4a, 0x7a, 0x9b, 0x3f, 0xaa, 0x60, 0xe7, + 0x64, 0xe6, 0x3d, 0x26, 0x0c, 0xc1, 0xcf, 0x80, 0x4a, 0x6d, 0x5d, 0x69, 0x28, 0xad, 0x72, 0xb7, + 0x73, 0x7e, 0x51, 0xdf, 0x7a, 0x7e, 0x51, 0x3f, 0x74, 0x28, 0x1b, 0xc5, 0x43, 0x03, 0xfb, 0x93, + 0x76, 0x56, 0xdd, 0x1e, 0x2e, 0xd7, 0xed, 0x60, 0xec, 0xb4, 0x45, 0xd1, 0x38, 0xa6, 0xb6, 0x71, + 0x7a, 0x3a, 0xe8, 0x2f, 0x2e, 0xea, 0xea, 0xa0, 0x6f, 0xaa, 0xd4, 0x86, 0x15, 0xa0, 0x8d, 0xc9, + 0x5c, 0xd7, 0x38, 0xa7, 0xc9, 0x97, 0x70, 0x1f, 0xe4, 0x49, 0xe0, 0xe3, 0x91, 0x9e, 0x6b, 0x28, + 0xad, 0x5d, 0x53, 0x1a, 0xb0, 0x03, 0x8a, 0xd9, 0x7e, 0xf5, 0x7c, 0x43, 0x69, 0x95, 0x1e, 0xde, + 0x37, 0x96, 0xdd, 0x72, 0x7e, 0x63, 0xe4, 0x62, 0xe3, 0x24, 0x0d, 0xea, 0xe6, 0xf8, 0x06, 0xcd, + 0x65, 0x16, 0x3c, 0x00, 0x85, 0x20, 0xa4, 0x7e, 0x48, 0xd9, 0x5c, 0xdf, 0x6e, 0x28, 0xad, 0xbc, + 0x99, 0xd9, 0x1c, 0x8b, 0xc8, 0x37, 0x31, 0xf1, 0x30, 0xd1, 0x77, 0x24, 0x96, 0xda, 0xf0, 0x11, + 0x78, 0xd5, 0x26, 0x41, 0x48, 0x30, 0x62, 0xc4, 0xb6, 0x86, 0x88, 0xe1, 0x91, 0x45, 0x3d, 0x9b, + 0xcc, 0xf4, 0x82, 0x88, 0xdc, 0x5f, 0xa2, 0x5d, 0x0e, 0x0e, 0x38, 0x76, 0x54, 0xf8, 0xe1, 0xac, + 0xae, 0xfc, 0x75, 0x56, 0x57, 0x3e, 0xcc, 0x15, 0xd4, 0x8a, 0xd6, 0xfc, 0x5b, 0x03, 0x7b, 0x8f, + 0x9f, 0xf4, 0x7a, 0x9f, 0x33, 0xc4, 0xa2, 0x3e, 0x71, 0x19, 0x82, 0x6f, 0x82, 0xaa, 0x8b, 0x22, + 0x66, 0xc5, 0x81, 0x8d, 0x18, 0xb1, 0x3c, 0xe4, 0xf9, 0x91, 0x38, 0xdd, 0x8a, 0xf9, 0x0a, 0x07, + 0x4e, 0x85, 0xff, 0x13, 0xee, 0x86, 0xf7, 0x01, 0xa0, 0x1e, 0x23, 0x1e, 0xb3, 0x90, 0x43, 0x74, + 0x55, 0x04, 0x15, 0xa5, 0xa7, 0xe3, 0x10, 0xf8, 0x0e, 0x28, 0x3b, 0xd8, 0x1a, 0xce, 0x19, 0x89, + 0x44, 0x00, 0x3f, 0xcf, 0x4a, 0x77, 0x6f, 0x71, 0x51, 0x07, 0x1f, 0xf4, 0xba, 0xdc, 0xdd, 0x71, + 0x88, 0x09, 0x1c, 0x9c, 0xae, 0x39, 0xa1, 0x4b, 0xa7, 0x44, 0xe6, 0x88, 0xb3, 0x86, 0x66, 0x91, + 0x7b, 0x44, 0x44, 0x06, 0x63, 0x3f, 0xf6, 0x98, 0x38, 0xf0, 0x04, 0xee, 0x71, 0x07, 0x7c, 0x1d, + 0x14, 0xc7, 0x64, 0x9e, 0x24, 0x6f, 0x0b, 0xb4, 0x30, 0x26, 0x73, 0x99, 0x9b, 0x80, 0x32, 0x75, + 0x27, 0x03, 0xb3, 0xcc, 0x29, 0x72, 0x93, 0xcc, 0x82, 0x04, 0xa7, 0xc8, 0xcd, 0x32, 0x39, 0x28, + 0x33, 0x8b, 0x19, 0x28, 0x33, 0x1f, 0x80, 0x72, 0x72, 0x04, 0x32, 0x19, 0x08, 0xbc, 0x24, 0x7d, + 0x32, 0x7f, 0x19, 0x22, 0x29, 0x4a, 0xab, 0x21, 0x59, 0xfd, 0x68, 0x1e, 0x25, 0x14, 0x65, 0x59, + 0x22, 0x9a, 0x47, 0x59, 0x7d, 0x0e, 0xca, 0xe4, 0xdd, 0x0c, 0x94, 0x99, 0x6f, 0x03, 0x88, 0x7d, + 0x8f, 0x21, 0xea, 0x45, 0x16, 0x89, 0x18, 0x9d, 0x20, 0x4e, 0xb1, 0xd7, 0x50, 0x5a, 0x05, 0xb3, + 0x9a, 0x22, 0xef, 0xa7, 0xc0, 0x51, 0x8e, 0x8b, 0xdf, 0xfc, 0x47, 0x03, 0xf7, 0xb8, 0xec, 0x9f, + 0x92, 0x30, 0xa2, 0x11, 0xdf, 0x86, 0x18, 0x80, 0x97, 0x4d, 0x7b, 0x6d, 0xb3, 0xf6, 0xda, 0x46, + 0xed, 0xb5, 0x4d, 0xda, 0x6b, 0x9b, 0xb4, 0xd7, 0x36, 0x69, 0xaf, 0x5d, 0xa2, 0xbd, 0x76, 0xb9, + 0xf6, 0xda, 0x25, 0xda, 0x6b, 0x9b, 0xb4, 0xd7, 0x6e, 0xae, 0x7d, 0xf6, 0xf1, 0x37, 0x9f, 0x2b, + 0xa0, 0x6a, 0x22, 0xcf, 0x21, 0x9d, 0x20, 0x70, 0x29, 0xb1, 0xb9, 0xfa, 0x04, 0xbe, 0x05, 0x60, + 0x88, 0xbe, 0x66, 0x16, 0x92, 0xce, 0xe4, 0x3a, 0xe1, 0xf2, 0xe7, 0xcc, 0x0a, 0x47, 0x92, 0x68, + 0x71, 0x95, 0x40, 0x03, 0xdc, 0x73, 0x09, 0x8a, 0xc8, 0x0b, 0xe1, 0xaa, 0x08, 0xaf, 0x0a, 0x68, + 0x2d, 0xfe, 0x2b, 0x50, 0x0a, 0x79, 0x49, 0x2b, 0xe2, 0xa3, 0x26, 0xe6, 0xa1, 0xf4, 0xf0, 0x3d, + 0xe3, 0xd2, 0xb7, 0xc1, 0xf8, 0x8f, 0x41, 0x4d, 0xae, 0x51, 0x20, 0x08, 0x85, 0x67, 0xa5, 0xb9, + 0x6f, 0x41, 0x85, 0xa7, 0x3c, 0x0d, 0x29, 0x23, 0x4f, 0x90, 0x1b, 0x93, 0xe3, 0x20, 0xbd, 0xd0, + 0x95, 0xe5, 0x85, 0xbe, 0x76, 0x75, 0xab, 0x37, 0xba, 0xba, 0xf7, 0x41, 0x7e, 0xca, 0xf9, 0x93, + 0x77, 0x42, 0x1a, 0xcd, 0x9f, 0x14, 0x50, 0xcd, 0xea, 0x0f, 0x84, 0xce, 0xc7, 0x01, 0xfc, 0x12, + 0x6c, 0xb3, 0x99, 0x67, 0x65, 0x0f, 0x55, 0xff, 0x76, 0x0f, 0x55, 0xfe, 0x64, 0xe6, 0x0d, 0xfa, + 0x66, 0x9e, 0xcd, 0xbc, 0x81, 0x0d, 0x5f, 0x03, 0x3b, 0x9c, 0x9c, 0x77, 0xa8, 0x8a, 0xad, 0xf0, + 0x5a, 0x1f, 0xbd, 0xd8, 0xa4, 0x76, 0x93, 0x26, 0x9b, 0xdf, 0x2b, 0x00, 0xf2, 0x76, 0xe4, 0xa7, + 0x7f, 0x37, 0xfd, 0xdc, 0x5e, 0x9b, 0xe6, 0x6f, 0xc9, 0xb6, 0x7b, 0xfe, 0x64, 0x42, 0xd9, 0xdd, + 0x6c, 0x3b, 0x19, 0x32, 0xf5, 0x7f, 0x86, 0x4c, 0xbb, 0xdd, 0x90, 0xe5, 0x56, 0x87, 0x2c, 0x90, + 0x33, 0xd6, 0x19, 0xfa, 0xe1, 0xdd, 0x34, 0xd7, 0xfc, 0x45, 0x03, 0xbb, 0xbc, 0xe4, 0xc7, 0xbe, + 0x43, 0x31, 0x72, 0x8f, 0x03, 0x78, 0x02, 0x4a, 0xcf, 0xf8, 0x8c, 0x5b, 0x72, 0x7f, 0x8a, 0x68, + 0xef, 0xf0, 0x8a, 0x1f, 0xf4, 0xea, 0xd7, 0x69, 0x82, 0x67, 0x99, 0x05, 0x9f, 0x82, 0xb2, 0x64, + 0x95, 0x57, 0x64, 0x22, 0xff, 0xa3, 0xeb, 0xd0, 0xa6, 0x07, 0x62, 0xca, 0xfd, 0x49, 0x13, 0x7e, + 0x01, 0x76, 0x93, 0x67, 0x2d, 0x61, 0x96, 0x7a, 0xbc, 0x7b, 0x45, 0xe6, 0xf5, 0xf9, 0x37, 0xcb, + 0xf1, 0x8a, 0xcd, 0xb9, 0xb1, 0x18, 0xb4, 0x94, 0x3b, 0x77, 0x2d, 0xee, 0xf5, 0x21, 0x35, 0xcb, + 0x78, 0xc5, 0xe6, 0x07, 0x82, 0xb8, 0xcc, 0x29, 0x75, 0xfe, 0x5a, 0x07, 0xb2, 0x36, 0x21, 0x66, + 0x09, 0x2d, 0xcd, 0xa3, 0xdc, 0xf9, 0x59, 0x5d, 0xe9, 0xea, 0xe7, 0x7f, 0xd4, 0xb6, 0xce, 0x17, + 0x35, 0xe5, 0xe7, 0x45, 0x4d, 0xf9, 0x75, 0x51, 0x53, 0x7e, 0x5f, 0xd4, 0x94, 0xef, 0xfe, 0xac, + 0x6d, 0x0d, 0xb7, 0xc5, 0x5f, 0xed, 0xc3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x33, 0x5c, + 0x16, 0xe4, 0x0b, 0x00, 0x00, } diff --git a/pkg/storage/engine/enginepb/mvcc3.proto b/pkg/storage/engine/enginepb/mvcc3.proto index d1d2a9e4cda3..9428599e7b80 100644 --- a/pkg/storage/engine/enginepb/mvcc3.proto +++ b/pkg/storage/engine/enginepb/mvcc3.proto @@ -18,15 +18,6 @@ package cockroach.storage.engine.enginepb; import "util/hlc/timestamp.proto"; import "gogoproto/gogo.proto"; -// TODO(tschottdorf): Should not live in enginepb (but can't live in roachpb -// either). -enum IsolationType { - option (gogoproto.goproto_enum_prefix) = false; - - SERIALIZABLE = 0; - SNAPSHOT = 1; -} - // TxnMeta is the metadata of a Transaction record. message TxnMeta { option (gogoproto.equal) = true; @@ -37,7 +28,7 @@ message TxnMeta { bytes id = 1 [(gogoproto.customname) = "ID", (gogoproto.customtype) = "github.com/cockroachdb/cockroach/pkg/util/uuid.UUID", (gogoproto.nullable) = false]; - IsolationType isolation = 2; + reserved 2; // key is the key which anchors the transaction. This is typically // the first key read or written during the transaction and // determines which range in the cluster will hold the transaction @@ -85,7 +76,7 @@ message MVCCStatsDelta { option (gogoproto.equal) = true; // TODO(nvanbenschoten): now that we've split MVCCPersistentStats - // from this MVCCStatsDelta type, we can turn contains_estimates + // from this MVCCStatsDelta type, we can turn contains_estimates // into a three-valued type ('UNCHANGED', 'NO', and 'YES'). bool contains_estimates = 14; sfixed64 last_update_nanos = 1; diff --git a/pkg/storage/gc_queue_test.go b/pkg/storage/gc_queue_test.go index 021f8436ff1b..89931dba9e98 100644 --- a/pkg/storage/gc_queue_test.go +++ b/pkg/storage/gc_queue_test.go @@ -347,7 +347,7 @@ func TestGCQueueMakeGCScoreRealistic(t *testing.T) { irrelevantTTL := 24 * time.Hour * 365 ms, valSize := initialMS(), 1<<10 txn := newTransaction( - "txn", roachpb.Key("key"), roachpb.NormalUserPriority, enginepb.SERIALIZABLE, + "txn", roachpb.Key("key"), roachpb.NormalUserPriority, hlc.NewClock(func() int64 { return ms.LastUpdateNanos }, time.Millisecond)) // Write 1000 distinct 1kb intents at the initial timestamp. This means that @@ -446,7 +446,7 @@ func TestGCQueueProcess(t *testing.T) { dArgs := deleteArgs(datum.key) var txn *roachpb.Transaction if datum.txn { - txn = newTransaction("test", datum.key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn = newTransaction("test", datum.key, 1, tc.Clock()) txn.OrigTimestamp = datum.ts txn.Timestamp = datum.ts assignSeqNumsForReqs(txn, &dArgs) @@ -461,7 +461,7 @@ func TestGCQueueProcess(t *testing.T) { pArgs := putArgs(datum.key, []byte("value")) var txn *roachpb.Transaction if datum.txn { - txn = newTransaction("test", datum.key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn = newTransaction("test", datum.key, 1, tc.Clock()) txn.OrigTimestamp = datum.ts txn.Timestamp = datum.ts assignSeqNumsForReqs(txn, &pArgs) @@ -709,7 +709,7 @@ func TestGCQueueTransactionTable(t *testing.T) { for strKey, test := range testCases { baseKey := roachpb.Key(strKey) txnClock := hlc.NewClock(hlc.NewManualClock(test.orig).UnixNano, time.Nanosecond) - txn := newTransaction("txn1", baseKey, 1, enginepb.SERIALIZABLE, txnClock) + txn := newTransaction("txn1", baseKey, 1, txnClock) txn.Status = test.status txn.Intents = testIntents if test.hb > 0 { @@ -828,8 +828,8 @@ func TestGCQueueIntentResolution(t *testing.T) { now := tc.Clock().Now().WallTime txns := []*roachpb.Transaction{ - newTransaction("txn1", roachpb.Key("0-0"), 1, enginepb.SERIALIZABLE, tc.Clock()), - newTransaction("txn2", roachpb.Key("1-0"), 1, enginepb.SERIALIZABLE, tc.Clock()), + newTransaction("txn1", roachpb.Key("0-0"), 1, tc.Clock()), + newTransaction("txn2", roachpb.Key("1-0"), 1, tc.Clock()), } intentResolveTS := makeTS(now-intentAgeThreshold.Nanoseconds(), 0) txns[0].OrigTimestamp = intentResolveTS diff --git a/pkg/storage/intent_resolver_test.go b/pkg/storage/intent_resolver_test.go index 6569b2d39929..4c1922b961ae 100644 --- a/pkg/storage/intent_resolver_test.go +++ b/pkg/storage/intent_resolver_test.go @@ -24,7 +24,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/internal/client" "github.com/cockroachdb/cockroach/pkg/roachpb" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/stop" @@ -62,7 +61,7 @@ func TestPushTransactionsWithNonPendingIntent(t *testing.T) { func beginTransaction( t *testing.T, store *Store, pri roachpb.UserPriority, key roachpb.Key, putKey bool, ) *roachpb.Transaction { - txn := newTransaction("test", key, pri, enginepb.SERIALIZABLE, store.Clock()) + txn := newTransaction("test", key, pri, store.Clock()) var ba roachpb.BatchRequest bt, header := beginTxnArgs(key, txn) @@ -99,9 +98,9 @@ func TestContendedIntent(t *testing.T) { span := roachpb.Span{Key: key} origTxn := beginTransaction(t, store, 1, key, true /* putKey */) - roTxn1 := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.Clock()) - roTxn2 := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.Clock()) - roTxn3 := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.Clock()) + roTxn1 := newTransaction("test", key, 1, store.Clock()) + roTxn2 := newTransaction("test", key, 1, store.Clock()) + roTxn3 := newTransaction("test", key, 1, store.Clock()) rwTxn1 := beginTransaction(t, store, 1, roachpb.Key("b"), true /* putKey */) rwTxn2 := beginTransaction(t, store, 1, roachpb.Key("c"), true /* putKey */) diff --git a/pkg/storage/replica.go b/pkg/storage/replica.go index ce9a10ad3d44..028101246a0a 100644 --- a/pkg/storage/replica.go +++ b/pkg/storage/replica.go @@ -6198,10 +6198,10 @@ func (r *Replica) evaluateWriteBatch( strippedBa.Txn = nil strippedBa.Requests = ba.Requests[1 : len(ba.Requests)-1] // strip begin/end txn reqs - // If there were no refreshable spans earlier in a serializable - // txn (e.g. earlier gets or scans), then the batch can be retried + // If there were no refreshable spans earlier in the txn + // (e.g. earlier gets or scans), then the batch can be retried // locally in the event of write too old errors. - retryLocally := ba.Txn.IsSerializable() && etArg.NoRefreshSpans + retryLocally := etArg.NoRefreshSpans // If all writes occurred at the intended timestamp, we've succeeded on the fast path. rec := NewReplicaEvalContext(r, spans) @@ -6375,13 +6375,6 @@ func isOnePhaseCommit(ba roachpb.BatchRequest, knobs *StoreTestingKnobs) bool { if retry, _ := batcheval.IsEndTransactionTriggeringRetryError(ba.Txn, *etArg); retry { return false } - if ba.Txn.Isolation == enginepb.SNAPSHOT && ba.Txn.OrigTimestamp != ba.Txn.Timestamp { - // Snapshot transactions that have been pushed are never eligible for - // the 1PC path. Instead, they must go through the slow path when their - // timestamp has been pushed. See comments on Transaction.orig_timestamp - // for the reasons why this is necessary to prevent lost update anomalies. - return false - } return !knobs.DisableOptional1PC || etArg.Require1PC } @@ -6625,35 +6618,32 @@ func evaluateBatch( } } // Set the flag to return a WriteTooOldError with the max timestamp - // encountered evaluating the entire batch on cput and inc requests, - // with serializable isolation. Because both of these requests must - // have their keys refreshed on commit with Transaction.WriteTooOld - // is true, and that refresh will fail, we'd be otherwise guaranteed - // to do a client-side retry. Returning an error allows a - // txn-coord-side retry. - if ba.Txn.IsSerializable() { - switch args.(type) { - case *roachpb.ConditionalPutRequest: - // Conditional puts are an exception. Here, it makes less sense to - // continue because it's likely that the cput will fail on retry (a - // newer value is less likely to match the expected value). It's - // better to return the WriteTooOldError directly, allowing the txn - // coord sender to retry if it can refresh all other spans encountered - // already during the transaction, and then, if the cput results in a - // condition failed error, report that back to the client instead of a - // retryable error. - returnWriteTooOldErr = true - case *roachpb.IncrementRequest: - // Increments are an exception for similar reasons. If we wait until - // commit, we'll need a client-side retry, so we return immediately - // to see if we can do a txn coord sender retry instead. - returnWriteTooOldErr = true - case *roachpb.InitPutRequest: - // Init puts are also an exception. There's no reason to believe they - // will succeed on a retry, so better to short circuit and return the - // write too old error. - returnWriteTooOldErr = true - } + // encountered evaluating the entire batch on cput and inc requests. + // Because both of these requests must have their keys refreshed on + // commit with Transaction.WriteTooOld is true, and that refresh will + // fail, we'd be otherwise guaranteed to do a client-side retry. + // Returning an error allows a txn-coord-side retry. + switch args.(type) { + case *roachpb.ConditionalPutRequest: + // Conditional puts are an exception. Here, it makes less sense to + // continue because it's likely that the cput will fail on retry (a + // newer value is less likely to match the expected value). It's + // better to return the WriteTooOldError directly, allowing the txn + // coord sender to retry if it can refresh all other spans encountered + // already during the transaction, and then, if the cput results in a + // condition failed error, report that back to the client instead of a + // retryable error. + returnWriteTooOldErr = true + case *roachpb.IncrementRequest: + // Increments are an exception for similar reasons. If we wait until + // commit, we'll need a client-side retry, so we return immediately + // to see if we can do a txn coord sender retry instead. + returnWriteTooOldErr = true + case *roachpb.InitPutRequest: + // Init puts are also an exception. There's no reason to believe they + // will succeed on a retry, so better to short circuit and return the + // write too old error. + returnWriteTooOldErr = true } if ba.Txn != nil { ba.Txn.Timestamp.Forward(tErr.ActualTimestamp) @@ -6697,12 +6687,12 @@ func evaluateBatch( if ba.Txn != nil { // If transactional, send out the final transaction entry with the reply. br.Txn = ba.Txn - // If a serializable transaction committed, forward the response + // If the transaction committed, forward the response // timestamp to the commit timestamp in case we were able to // optimize and commit at a higher timestamp without higher-level // retry (i.e. there were no refresh spans and the commit timestamp // wasn't leaked). - if ba.Txn.IsSerializable() && ba.Txn.Status == roachpb.COMMITTED { + if ba.Txn.Status == roachpb.COMMITTED { br.Timestamp.Forward(ba.Txn.Timestamp) } } diff --git a/pkg/storage/replica_test.go b/pkg/storage/replica_test.go index e57e0cbf28da..f044c742b2eb 100644 --- a/pkg/storage/replica_test.go +++ b/pkg/storage/replica_test.go @@ -360,11 +360,7 @@ func (tc *testContext) addBogusReplicaToRangeDesc( } func newTransaction( - name string, - baseKey roachpb.Key, - userPriority roachpb.UserPriority, - isolation enginepb.IsolationType, - clock *hlc.Clock, + name string, baseKey roachpb.Key, userPriority roachpb.UserPriority, clock *hlc.Clock, ) *roachpb.Transaction { var offset int64 var now hlc.Timestamp @@ -372,7 +368,7 @@ func newTransaction( offset = clock.MaxOffset().Nanoseconds() now = clock.Now() } - txn := roachpb.MakeTransaction(name, baseKey, userPriority, isolation, now, offset) + txn := roachpb.MakeTransaction(name, baseKey, userPriority, now, offset) return &txn } @@ -418,38 +414,29 @@ func TestIsOnePhaseCommit(t *testing.T) { isTxn bool isWTO bool isTSOff bool - iso enginepb.IsolationType exp1PC bool }{ - {[]roachpb.RequestUnion{}, false, false, false, enginepb.SERIALIZABLE, false}, - {[]roachpb.RequestUnion{}, true, false, false, enginepb.SERIALIZABLE, false}, - {[]roachpb.RequestUnion{{Value: &roachpb.RequestUnion_Get{Get: &roachpb.GetRequest{}}}}, true, false, false, enginepb.SERIALIZABLE, false}, - {[]roachpb.RequestUnion{{Value: &roachpb.RequestUnion_Put{Put: &roachpb.PutRequest{}}}}, true, false, false, enginepb.SERIALIZABLE, false}, - {txnReqs[0 : len(txnReqs)-1], true, false, false, enginepb.SERIALIZABLE, false}, - {txnReqs[1:], true, false, false, enginepb.SERIALIZABLE, false}, - {txnReqs, true, false, false, enginepb.SERIALIZABLE, true}, - {txnReqs, true, false, false, enginepb.SNAPSHOT, true}, - {txnReqs, true, true, false, enginepb.SERIALIZABLE, false}, - {txnReqs, true, true, false, enginepb.SNAPSHOT, false}, - {txnReqs, true, false, true, enginepb.SERIALIZABLE, false}, - {txnReqs, true, false, true, enginepb.SNAPSHOT, false}, - {txnReqs, true, true, true, enginepb.SERIALIZABLE, false}, - {txnReqs, true, true, true, enginepb.SNAPSHOT, false}, - {txnReqsNoRefresh, true, false, false, enginepb.SERIALIZABLE, true}, - {txnReqsNoRefresh, true, false, false, enginepb.SNAPSHOT, true}, - {txnReqsNoRefresh, true, true, false, enginepb.SERIALIZABLE, true}, - {txnReqsNoRefresh, true, true, false, enginepb.SNAPSHOT, false}, - {txnReqsNoRefresh, true, false, true, enginepb.SERIALIZABLE, true}, - {txnReqsNoRefresh, true, false, true, enginepb.SNAPSHOT, false}, - {txnReqsNoRefresh, true, true, true, enginepb.SERIALIZABLE, true}, - {txnReqsNoRefresh, true, true, true, enginepb.SNAPSHOT, false}, + {[]roachpb.RequestUnion{}, false, false, false, false}, + {[]roachpb.RequestUnion{}, true, false, false, false}, + {[]roachpb.RequestUnion{{Value: &roachpb.RequestUnion_Get{Get: &roachpb.GetRequest{}}}}, true, false, false, false}, + {[]roachpb.RequestUnion{{Value: &roachpb.RequestUnion_Put{Put: &roachpb.PutRequest{}}}}, true, false, false, false}, + {txnReqs[0 : len(txnReqs)-1], true, false, false, false}, + {txnReqs[1:], true, false, false, false}, + {txnReqs, true, false, false, true}, + {txnReqs, true, true, false, false}, + {txnReqs, true, false, true, false}, + {txnReqs, true, true, true, false}, + {txnReqsNoRefresh, true, false, false, true}, + {txnReqsNoRefresh, true, true, false, true}, + {txnReqsNoRefresh, true, false, true, true}, + {txnReqsNoRefresh, true, true, true, true}, } clock := hlc.NewClock(hlc.UnixNano, time.Nanosecond) for i, c := range testCases { ba := roachpb.BatchRequest{Requests: c.bu} if c.isTxn { - ba.Txn = newTransaction("txn", roachpb.Key("a"), 1, c.iso, clock) + ba.Txn = newTransaction("txn", roachpb.Key("a"), 1, clock) if c.isWTO { ba.Txn.WriteTooOld = true } @@ -539,7 +526,7 @@ func TestReplicaReadConsistency(t *testing.T) { // Try a read commmitted read and an inconsistent read, both within a // transaction. - txn := newTransaction("test", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", roachpb.Key("a"), 1, tc.Clock()) assignSeqNumsForReqs(txn, &gArgs) if _, err := tc.SendWrappedWith(roachpb.Header{ @@ -1395,7 +1382,7 @@ func TestReplicaNoGossipConfig(t *testing.T) { // Write some arbitrary data in the system span (up to, but not including MaxReservedID+1) key := keys.MakeTablePrefix(keys.MaxReservedDescID) - txn := newTransaction("test", key, 1 /* userPriority */, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1 /* userPriority */, tc.Clock()) h := roachpb.Header{Txn: txn} req1 := putArgs(key, []byte("foo")) req2, _ := endTxnArgs(txn, true /* commit */) @@ -1441,7 +1428,7 @@ func TestReplicaNoGossipFromNonLeader(t *testing.T) { // Write some arbitrary data in the system span (up to, but not including MaxReservedID+1) key := keys.MakeTablePrefix(keys.MaxReservedDescID) - txn := newTransaction("test", key, 1 /* userPriority */, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1 /* userPriority */, tc.Clock()) req1 := putArgs(key, nil) assignSeqNumsForReqs(txn, &req1) @@ -2679,7 +2666,7 @@ func TestReplicaCommandQueueCancellationLocal(t *testing.T) { defer leaktest.AfterTest(t)() now := hlc.Timestamp{WallTime: cmdQCancelTestTimestamp} - txn := roachpb.MakeTransaction("txn", roachpb.Key("foobar"), 0, enginepb.SERIALIZABLE, now, 0) + txn := roachpb.MakeTransaction("txn", roachpb.Key("foobar"), 0, now, 0) intentKey := roachpb.Key("baz") newBa := func(withTxn bool) *roachpb.BatchRequest { @@ -3405,7 +3392,7 @@ func TestReplicaCommandQueuePrereqDebugSummary(t *testing.T) { defer leaktest.AfterTest(t)() var ba1, ba2, ba3 roachpb.BatchRequest - txn := newTransaction("test", []byte("k"), 1, enginepb.SERIALIZABLE, nil) + txn := newTransaction("test", []byte("k"), 1, nil) bt, _ := beginTxnArgs([]byte("k"), txn) put := putArgs([]byte("k"), []byte("v")) et, _ := endTxnArgs(txn, true) @@ -3552,7 +3539,7 @@ func TestConditionalPutUpdatesTSCacheOnError(t *testing.T) { // Try a transactional put at a lower timestamp and ensure it is pushed. var ba roachpb.BatchRequest - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) txn.OrigTimestamp, txn.Timestamp = makeTS(1, 0), makeTS(1, 0) pArgs := putArgs(key, []byte("value")) ba.Header = roachpb.Header{Txn: txn} @@ -3661,7 +3648,7 @@ func TestReplicaNoTSCacheUpdateOnFailure(t *testing.T) { key := roachpb.Key(fmt.Sprintf("key-%d", i)) // Start by laying down an intent to trip up future read or write to same key. - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) pArgs := putArgs(key, []byte("value")) assignSeqNumsForReqs(txn, &pArgs) @@ -3709,7 +3696,7 @@ func TestReplicaNoTimestampIncrementWithinTxn(t *testing.T) { // Test for both read & write attempts. key := roachpb.Key("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) // Start with a read to warm the timestamp cache. gArgs := getArgs(key) @@ -3774,7 +3761,7 @@ func TestReplicaAbortSpanReadError(t *testing.T) { tc.Start(t, stopper) k := []byte("a") - txn := newTransaction("test", k, 10, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", k, 10, tc.Clock()) args := incrementArgs(k, 1) assignSeqNumsForReqs(txn, &args) @@ -3811,7 +3798,7 @@ func TestReplicaAbortSpanStoredTxnRetryError(t *testing.T) { key := []byte("a") { - txn := newTransaction("test", key, 10, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 10, tc.Clock()) txn.Sequence = int32(1) entry := roachpb.AbortSpanEntry{ Key: txn.Key, @@ -3834,7 +3821,7 @@ func TestReplicaAbortSpanStoredTxnRetryError(t *testing.T) { // Try the same again, this time verifying that the Put will actually // populate the cache appropriately. - txn := newTransaction("test", key, 10, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 10, tc.Clock()) txn.Sequence = 321 args := incrementArgs(key, 1) try := func() *roachpb.Error { @@ -3880,7 +3867,7 @@ func TestReplicaAbortSpanOnlyWithIntent(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - txn := newTransaction("test", []byte("test"), 10, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", []byte("test"), 10, tc.Clock()) txn.Sequence = 100 entry := roachpb.AbortSpanEntry{ Key: txn.Key, @@ -3913,7 +3900,7 @@ func TestEndTransactionDeadline(t *testing.T) { // 4 cases: no deadline, past deadline, equal deadline, future deadline. for i := 0; i < 4; i++ { key := roachpb.Key("key: " + strconv.Itoa(i)) - txn := newTransaction("txn: "+strconv.Itoa(i), key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("txn: "+strconv.Itoa(i), key, 1, tc.Clock()) put := putArgs(key, key) assignSeqNumsForReqs(txn, &put) @@ -3972,10 +3959,8 @@ func TestEndTransactionDeadline(t *testing.T) { } } -// Test that, when a pushed Snapshot txn would get a "deadline exceeded" error, -// a Serializable one would get a serializable restart instead. In other words, -// for Serializable transactions, regular push retriable errors take precedence -// over the deadline check. +// Test that regular push retriable errors take precedence over the deadline +// check. func TestSerializableDeadline(t *testing.T) { defer leaktest.AfterTest(t)() tc := testContext{} @@ -3983,73 +3968,44 @@ func TestSerializableDeadline(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - const expectedTransactionStatusError int = 1 - const expectedTransactionRestartError int = 2 + key := roachpb.Key("key") + // Start our txn. It will be pushed next. + txn := newTransaction("test txn", key, roachpb.MinUserPriority, tc.Clock()) + beginTxn, header := beginTxnArgs(key, txn) + if _, pErr := tc.SendWrappedWith(header, &beginTxn); pErr != nil { + t.Fatal(pErr.GoError()) + } - tests := []struct { - isoLevel enginepb.IsolationType - expectedErrType int - expectedErrMsg string - }{{ - isoLevel: enginepb.SNAPSHOT, - expectedErrType: expectedTransactionStatusError, - expectedErrMsg: "TransactionStatusError: transaction deadline exceeded", - }, { - isoLevel: enginepb.SERIALIZABLE, - expectedErrType: expectedTransactionRestartError, - expectedErrMsg: "TransactionRetryError: retry txn \\(RETRY_SERIALIZABLE\\)", - }} - for i, test := range tests { - t.Run(test.isoLevel.String(), func(t *testing.T) { - key := roachpb.Key("key: " + strconv.Itoa(i)) - // Start our txn. It will be pushed next. - txn := newTransaction("test txn", key, roachpb.MinUserPriority, - test.isoLevel, tc.Clock()) - beginTxn, header := beginTxnArgs(key, txn) - if _, pErr := tc.SendWrappedWith(header, &beginTxn); pErr != nil { - t.Fatal(pErr.GoError()) - } - - tc.manualClock.Increment(100) - pusher := newTransaction( - "test pusher", key, roachpb.MaxUserPriority, - enginepb.SERIALIZABLE, tc.Clock()) - pushReq := pushTxnArgs(pusher, txn, roachpb.PUSH_TIMESTAMP) - pushReq.Now = tc.Clock().Now() - resp, pErr := tc.SendWrapped(&pushReq) - if pErr != nil { - t.Fatal(pErr) - } - updatedPushee := resp.(*roachpb.PushTxnResponse).PusheeTxn - if updatedPushee.Status != roachpb.PENDING { - t.Fatalf("expected pushee to still be alive, but got %+v", updatedPushee) - } - - // Send an EndTransaction with a deadline below the point where the txn - // has been pushed. - etArgs, etHeader := endTxnArgs(txn, true /* commit */) - deadline := updatedPushee.Timestamp - deadline.Logical-- - etArgs.Deadline = &deadline - _, pErr = tc.SendWrappedWith(etHeader, &etArgs) - if pErr == nil { - t.Fatalf("expected %q, got: nil", test.expectedErrMsg) - } - err := pErr.GoError() - if test.expectedErrType == expectedTransactionStatusError { - if _, ok := err.(*roachpb.TransactionStatusError); !ok || - !testutils.IsError(err, test.expectedErrMsg) { - t.Fatalf("expected %q, got: %s (%T)", test.expectedErrMsg, - err, err) - } - } else { - if _, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok || - !testutils.IsError(err, test.expectedErrMsg) { - t.Fatalf("expected %q, got: %s (%T)", test.expectedErrMsg, - err, pErr.GetDetail()) - } - } - }) + tc.manualClock.Increment(100) + pusher := newTransaction( + "test pusher", key, roachpb.MaxUserPriority, tc.Clock()) + pushReq := pushTxnArgs(pusher, txn, roachpb.PUSH_TIMESTAMP) + pushReq.Now = tc.Clock().Now() + resp, pErr := tc.SendWrapped(&pushReq) + if pErr != nil { + t.Fatal(pErr) + } + updatedPushee := resp.(*roachpb.PushTxnResponse).PusheeTxn + if updatedPushee.Status != roachpb.PENDING { + t.Fatalf("expected pushee to still be alive, but got %+v", updatedPushee) + } + + // Send an EndTransaction with a deadline below the point where the txn + // has been pushed. + etArgs, etHeader := endTxnArgs(txn, true /* commit */) + deadline := updatedPushee.Timestamp + deadline.Logical-- + etArgs.Deadline = &deadline + _, pErr = tc.SendWrappedWith(etHeader, &etArgs) + const expectedErrMsg = "TransactionRetryError: retry txn \\(RETRY_SERIALIZABLE\\)" + if pErr == nil { + t.Fatalf("expected %q, got: nil", expectedErrMsg) + } + err := pErr.GoError() + if _, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok || + !testutils.IsError(err, expectedErrMsg) { + t.Fatalf("expected %q, got: %s (%T)", expectedErrMsg, + err, pErr.GetDetail()) } } @@ -4076,7 +4032,7 @@ func TestEndTransactionTxnSpanGCThreshold(t *testing.T) { // This pushee should never be allowed to write a txn record because it // will be aborted before it even tries. - pushee := newTransaction("foo", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pushee := newTransaction("foo", key, 1, tc.Clock()) pushReq := pushTxnArgs(pusher, pushee, roachpb.PUSH_TOUCH) pushReq.Now = tc.Clock().Now() resp, pErr := tc.SendWrapped(&pushReq) @@ -4133,7 +4089,7 @@ func TestEndTransactionTxnSpanGCThreshold(t *testing.T) { // be prevented from writing its record. // See #9522. { - txn := newTransaction("foo", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("foo", key, 1, tc.Clock()) beginArgs, header := beginTxnArgs(key, txn) if _, pErr := tc.SendWrappedWith(header, &beginArgs); pErr != nil { t.Fatal(pErr) @@ -4152,7 +4108,7 @@ func TestEndTransactionDeadline_1PC(t *testing.T) { tc.Start(t, stopper) key := roachpb.Key("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) bt, _ := beginTxnArgs(key, txn) put := putArgs(key, []byte("value")) et, etH := endTxnArgs(txn, true) @@ -4184,42 +4140,26 @@ func Test1PCTransactionWriteTimestamp(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - for _, iso := range []enginepb.IsolationType{enginepb.SNAPSHOT, enginepb.SERIALIZABLE} { - t.Run(iso.String(), func(t *testing.T) { - key := roachpb.Key(iso.String()) - txn := newTransaction("test", key, 1, iso, tc.Clock()) - bt, _ := beginTxnArgs(key, txn) - put := putArgs(key, []byte("value")) - et, etH := endTxnArgs(txn, true) + key := roachpb.Key("key") + txn := newTransaction("test", key, 1, tc.Clock()) + bt, _ := beginTxnArgs(key, txn) + put := putArgs(key, []byte("value")) + et, etH := endTxnArgs(txn, true) - // Update the timestamp cache for the key being written. - gArgs := getArgs(key) - if _, pErr := tc.SendWrapped(&gArgs); pErr != nil { - t.Fatal(pErr) - } + // Update the timestamp cache for the key being written. + gArgs := getArgs(key) + if _, pErr := tc.SendWrapped(&gArgs); pErr != nil { + t.Fatal(pErr) + } - // Now verify that the write triggers a retry for SERIALIZABLE and - // writes at the higher timestamp for SNAPSHOT. - var ba roachpb.BatchRequest - ba.Header = etH - ba.Add(&bt, &put, &et) - assignSeqNumsForReqs(txn, &bt, &put, &et) - br, pErr := tc.Sender().Send(context.Background(), ba) - if iso == enginepb.SNAPSHOT { - if pErr != nil { - t.Fatal(pErr) - } - if !txn.OrigTimestamp.Less(br.Txn.Timestamp) { - t.Errorf( - "expected result timestamp %s > txn orig timestamp %s", br.Txn.Timestamp, txn.OrigTimestamp, - ) - } - } else { - if _, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok { - t.Errorf("expected retry error; got %s", pErr) - } - } - }) + // Now verify that the write triggers a retry. + var ba roachpb.BatchRequest + ba.Header = etH + ba.Add(&bt, &put, &et) + assignSeqNumsForReqs(txn, &bt, &put, &et) + _, pErr := tc.Sender().Send(context.Background(), ba) + if _, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok { + t.Errorf("expected retry error; got %s", pErr) } } @@ -4233,7 +4173,7 @@ func TestEndTransactionWithMalformedSplitTrigger(t *testing.T) { tc.Start(t, stopper) key := roachpb.Key("foo") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) pArgs := putArgs(key, []byte("only here to make this a rw transaction")) assignSeqNumsForReqs(txn, &pArgs) if _, pErr := maybeWrapWithBeginTransaction(context.Background(), tc.Sender(), roachpb.Header{ @@ -4281,7 +4221,7 @@ func TestEndTransactionBeforeHeartbeat(t *testing.T) { key := []byte("a") for _, commit := range []bool{true, false} { - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) _, btH := beginTxnArgs(key, txn) put := putArgs(key, key) assignSeqNumsForReqs(txn, &put) @@ -4336,7 +4276,7 @@ func TestEndTransactionAfterHeartbeat(t *testing.T) { key := roachpb.Key("a") for _, commit := range []bool{true, false} { - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) _, btH := beginTxnArgs(key, txn) put := putArgs(key, key) assignSeqNumsForReqs(txn, &put) @@ -4395,19 +4335,16 @@ func TestEndTransactionWithPushedTimestamp(t *testing.T) { tc.Start(t, stopper) testCases := []struct { - commit bool - isolation enginepb.IsolationType - expErr bool + commit bool + expErr bool }{ - {true, enginepb.SERIALIZABLE, true}, - {true, enginepb.SNAPSHOT, false}, - {false, enginepb.SERIALIZABLE, false}, - {false, enginepb.SNAPSHOT, false}, + {true, true}, + {false, false}, } key := roachpb.Key("a") for i, test := range testCases { - pushee := newTransaction("pushee", key, 1, test.isolation, tc.Clock()) - pusher := newTransaction("pusher", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pushee := newTransaction("pushee", key, 1, tc.Clock()) + pusher := newTransaction("pusher", key, 1, tc.Clock()) pushee.Priority = roachpb.MinTxnPriority pusher.Priority = roachpb.MaxTxnPriority // pusher will win _, btH := beginTxnArgs(key, pushee) @@ -4460,7 +4397,7 @@ func TestEndTransactionWithIncrementedEpoch(t *testing.T) { tc.Start(t, stopper) key := []byte("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) _, btH := beginTxnArgs(key, txn) put := putArgs(key, key) assignSeqNumsForReqs(txn, &put) @@ -4510,7 +4447,7 @@ func TestEndTransactionWithErrors(t *testing.T) { tc.Start(t, stopper) regressTS := tc.Clock().Now() - txn := newTransaction("test", roachpb.Key(""), 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", roachpb.Key(""), 1, tc.Clock()) doesNotExist := roachpb.TransactionStatus(-1) @@ -4571,7 +4508,7 @@ func TestEndTransactionRollbackAbortedTransaction(t *testing.T) { tc.Start(t, stopper) key := []byte("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) _, btH := beginTxnArgs(key, txn) put := putArgs(key, key) assignSeqNumsForReqs(txn, &put) @@ -4585,7 +4522,7 @@ func TestEndTransactionRollbackAbortedTransaction(t *testing.T) { txn.Writing = true // Abort the transaction by pushing it with maximum priority. - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", key, 1, tc.Clock()) pusher.Priority = roachpb.MaxTxnPriority pushArgs := pushTxnArgs(pusher, btH.Txn, roachpb.PUSH_ABORT) if _, pErr := tc.SendWrapped(&pushArgs); pErr != nil { @@ -4660,7 +4597,7 @@ func TestRaftRetryProtectionInTxn(t *testing.T) { tc.StartWithStoreConfig(t, stopper, cfg) key := roachpb.Key("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) // Send a batch with begin txn, put & end txn. var ba roachpb.BatchRequest @@ -4765,93 +4702,87 @@ func TestRaftRetryCantCommitIntents(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - testCases := []enginepb.IsolationType{enginepb.SERIALIZABLE, enginepb.SNAPSHOT} - - for i, iso := range testCases { - t.Run(iso.String(), func(t *testing.T) { - key := roachpb.Key(fmt.Sprintf("a-%d", i)) - keyB := roachpb.Key(fmt.Sprintf("b-%d", i)) - txn := newTransaction("test", key, 1, iso, tc.Clock()) + key := roachpb.Key("a") + keyB := roachpb.Key("b") + txn := newTransaction("test", key, 1, tc.Clock()) - // Send a batch with put to key. - var ba roachpb.BatchRequest - bt, btH := beginTxnArgs(key, txn) - put := putArgs(key, []byte("value")) - ba.Header = btH - ba.Add(&bt) - ba.Add(&put) - assignSeqNumsForReqs(txn, &bt, &put) - if err := ba.SetActiveTimestamp(tc.Clock().Now); err != nil { - t.Fatal(err) - } - br, pErr := tc.Sender().Send(context.Background(), ba) - if pErr != nil { - t.Fatalf("unexpected error: %s", pErr) - } + // Send a batch with put to key. + var ba roachpb.BatchRequest + bt, btH := beginTxnArgs(key, txn) + put := putArgs(key, []byte("value")) + ba.Header = btH + ba.Add(&bt) + ba.Add(&put) + assignSeqNumsForReqs(txn, &bt, &put) + if err := ba.SetActiveTimestamp(tc.Clock().Now); err != nil { + t.Fatal(err) + } + br, pErr := tc.Sender().Send(context.Background(), ba) + if pErr != nil { + t.Fatalf("unexpected error: %s", pErr) + } - // Send a put for keyB. - var ba2 roachpb.BatchRequest - putB := putArgs(keyB, []byte("value")) - putTxn := br.Txn.Clone() - ba2.Header = roachpb.Header{Txn: &putTxn} - ba2.Add(&putB) - assignSeqNumsForReqs(&putTxn, &putB) - br, pErr = tc.Sender().Send(context.Background(), ba2) - if pErr != nil { - t.Fatalf("unexpected error: %s", pErr) - } + // Send a put for keyB. + var ba2 roachpb.BatchRequest + putB := putArgs(keyB, []byte("value")) + putTxn := br.Txn.Clone() + ba2.Header = roachpb.Header{Txn: &putTxn} + ba2.Add(&putB) + assignSeqNumsForReqs(&putTxn, &putB) + br, pErr = tc.Sender().Send(context.Background(), ba2) + if pErr != nil { + t.Fatalf("unexpected error: %s", pErr) + } - // EndTransaction. - etTxn := br.Txn.Clone() - et, etH := endTxnArgs(&etTxn, true) - et.IntentSpans = []roachpb.Span{{Key: key, EndKey: nil}, {Key: keyB, EndKey: nil}} - assignSeqNumsForReqs(&etTxn, &et) - if _, pErr := tc.SendWrappedWith(etH, &et); pErr != nil { - t.Fatalf("unexpected error: %s", pErr) - } + // EndTransaction. + etTxn := br.Txn.Clone() + et, etH := endTxnArgs(&etTxn, true) + et.IntentSpans = []roachpb.Span{{Key: key, EndKey: nil}, {Key: keyB, EndKey: nil}} + assignSeqNumsForReqs(&etTxn, &et) + if _, pErr := tc.SendWrappedWith(etH, &et); pErr != nil { + t.Fatalf("unexpected error: %s", pErr) + } - // Verify txn record is cleaned. - var readTxn roachpb.Transaction - txnKey := keys.TransactionKey(txn.Key, txn.ID) - ok, err := engine.MVCCGetProto(context.Background(), tc.repl.store.Engine(), txnKey, hlc.Timestamp{}, true /* consistent */, nil /* txn */, &readTxn) - if err != nil || ok { - t.Errorf("expected transaction record to be cleared (%t): %s", ok, err) - } + // Verify txn record is cleaned. + var readTxn roachpb.Transaction + txnKey := keys.TransactionKey(txn.Key, txn.ID) + ok, err := engine.MVCCGetProto(context.Background(), tc.repl.store.Engine(), txnKey, hlc.Timestamp{}, true /* consistent */, nil /* txn */, &readTxn) + if err != nil || ok { + t.Errorf("expected transaction record to be cleared (%t): %s", ok, err) + } - // Now replay begin & put. BeginTransaction should fail with a - // TransactionAbortedError. - _, pErr = tc.Sender().Send(context.Background(), ba) - expErr := "TransactionAbortedError(ABORT_REASON_ALREADY_COMMITTED_OR_ROLLED_BACK_POSSIBLE_REPLAY)" - if !testutils.IsPError(pErr, regexp.QuoteMeta(expErr)) { - t.Errorf("expected %s; got %v", expErr, pErr) - } + // Now replay begin & put. BeginTransaction should fail with a + // TransactionAbortedError. + _, pErr = tc.Sender().Send(context.Background(), ba) + expErr := "TransactionAbortedError(ABORT_REASON_ALREADY_COMMITTED_OR_ROLLED_BACK_POSSIBLE_REPLAY)" + if !testutils.IsPError(pErr, regexp.QuoteMeta(expErr)) { + t.Errorf("expected %s; got %v", expErr, pErr) + } - // Intent should not have been created. - gArgs := getArgs(key) - if _, pErr = tc.SendWrapped(&gArgs); pErr != nil { - t.Errorf("unexpected error reading key: %s", pErr) - } + // Intent should not have been created. + gArgs := getArgs(key) + if _, pErr = tc.SendWrapped(&gArgs); pErr != nil { + t.Errorf("unexpected error reading key: %s", pErr) + } - // Send a put for keyB; this currently succeeds as there's nothing to detect - // the retry. - if _, pErr = tc.SendWrappedWith(roachpb.Header{Txn: &putTxn}, &putB); pErr != nil { - t.Error(pErr) - } + // Send a put for keyB; this currently succeeds as there's nothing to detect + // the retry. + if _, pErr = tc.SendWrappedWith(roachpb.Header{Txn: &putTxn}, &putB); pErr != nil { + t.Error(pErr) + } - // EndTransaction should fail with a txn not found error. - _, pErr = tc.SendWrappedWith(etH, &et) - if tse, ok := pErr.GetDetail().(*roachpb.TransactionStatusError); !ok || - tse.Reason != roachpb.TransactionStatusError_REASON_TXN_NOT_FOUND { - t.Fatalf("expected TransactionStatusError with REASON_TXN_NOT_FOUND, found %v", pErr) - } + // EndTransaction should fail with a txn not found error. + _, pErr = tc.SendWrappedWith(etH, &et) + if tse, ok := pErr.GetDetail().(*roachpb.TransactionStatusError); !ok || + tse.Reason != roachpb.TransactionStatusError_REASON_TXN_NOT_FOUND { + t.Fatalf("expected TransactionStatusError with REASON_TXN_NOT_FOUND, found %v", pErr) + } - // Expect that keyB intent did not get written! - gArgs = getArgs(keyB) - _, pErr = tc.SendWrapped(&gArgs) - if _, ok := pErr.GetDetail().(*roachpb.WriteIntentError); !ok { - t.Errorf("expected WriteIntentError, got: %v", pErr) - } - }) + // Expect that keyB intent did not get written! + gArgs = getArgs(keyB) + _, pErr = tc.SendWrapped(&gArgs) + if _, ok := pErr.GetDetail().(*roachpb.WriteIntentError); !ok { + t.Errorf("expected WriteIntentError, got: %v", pErr) } } @@ -4866,7 +4797,7 @@ func TestDuplicateBeginTransaction(t *testing.T) { tc.Start(t, stopper) key := roachpb.Key("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) bt, btH := beginTxnArgs(key, txn) var ba roachpb.BatchRequest ba.Header = btH @@ -4921,7 +4852,7 @@ func TestEndTransactionLocalGC(t *testing.T) { // Intent inside and outside. {[]roachpb.Span{{Key: roachpb.Key("a")}, {Key: splitKey.AsRawKey()}}, false}, } { - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) _, btH := beginTxnArgs(key, txn) put := putArgs(putKey, key) assignSeqNumsForReqs(txn, &put) @@ -4956,7 +4887,7 @@ func setupResolutionTest( // Split the range and create an intent at splitKey and key. newRepl := splitTestRange(tc.store, splitKey, splitKey, t) - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) // This increment is not required, but testing feels safer when zero // values are unexpected. txn.Epoch++ @@ -5153,7 +5084,7 @@ func TestEndTransactionDirectGC_1PC(t *testing.T) { tc.Start(t, stopper) key := roachpb.Key("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) bt, _ := beginTxnArgs(key, txn) put := putArgs(key, []byte("value")) et, etH := endTxnArgs(txn, commit) @@ -5235,7 +5166,7 @@ func TestReplicaTransactionRequires1PC(t *testing.T) { // Create the 1PC batch. var ba roachpb.BatchRequest - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) bt, _ := beginTxnArgs(key, txn) put := putArgs(key, []byte("value")) et, etH := endTxnArgs(txn, true) @@ -5274,7 +5205,7 @@ func TestReplicaEndTransactionWithRequire1PC(t *testing.T) { tc.Start(t, stopper) key := roachpb.Key("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) bt, btH := beginTxnArgs(key, txn) put := putArgs(key, []byte("value")) var ba roachpb.BatchRequest @@ -5317,7 +5248,7 @@ func TestReplicaResolveIntentNoWait(t *testing.T) { tc.StartWithStoreConfig(t, stopper, tsc) splitKey := roachpb.RKey("aa") setupResolutionTest(t, tc, roachpb.Key("a") /* irrelevant */, splitKey, true /* commit */) - txn := newTransaction("name", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("name", key, 1, tc.Clock()) txn.Status = roachpb.COMMITTED if pErr := tc.store.intentResolver.resolveIntents(context.Background(), []roachpb.Intent{{ @@ -5343,18 +5274,18 @@ func TestAbortSpanPoisonOnResolve(t *testing.T) { defer leaktest.AfterTest(t)() key := roachpb.Key("a") - // Isolation of the pushee and whether we're going to abort it. + // Whether we're going to abort the pushee. // Run the actual meat of the test, which pushes the pushee and // checks whether we get the correct behavior as it touches the // Range again. - run := func(abort bool, iso enginepb.IsolationType) { + run := func(abort bool) { tc := testContext{} stopper := stop.NewStopper() defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) - pushee := newTransaction("test", key, 1, iso, tc.Clock()) + pusher := newTransaction("test", key, 1, tc.Clock()) + pushee := newTransaction("test", key, 1, tc.Clock()) pusher.Priority = roachpb.MaxTxnPriority pushee.Priority = roachpb.MinTxnPriority // pusher will win @@ -5399,7 +5330,7 @@ func TestAbortSpanPoisonOnResolve(t *testing.T) { } assert = func(pErr *roachpb.Error) error { if _, ok := pErr.GetDetail().(*roachpb.TransactionAbortedError); !ok { - return errors.Errorf("abort=%t, iso=%s: expected txn abort, got %s", abort, iso, pErr) + return errors.Errorf("abort=%t: expected txn abort, got %s", abort, pErr) } return nil } @@ -5407,7 +5338,7 @@ func TestAbortSpanPoisonOnResolve(t *testing.T) { // Verify we're not poisoned. assert = func(pErr *roachpb.Error) error { if pErr != nil { - return errors.Errorf("abort=%t, iso=%s: unexpected: %s", abort, iso, pErr) + return errors.Errorf("abort=%t: unexpected: %s", abort, pErr) } return nil } @@ -5451,8 +5382,7 @@ func TestAbortSpanPoisonOnResolve(t *testing.T) { } for _, abort := range []bool{false, true} { - run(abort, enginepb.SERIALIZABLE) - run(abort, enginepb.SNAPSHOT) + run(abort) } } @@ -5506,8 +5436,8 @@ func TestPushTxnBadKey(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - pusher := newTransaction("test", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) - pushee := newTransaction("test", roachpb.Key("b"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", roachpb.Key("a"), 1, tc.Clock()) + pushee := newTransaction("test", roachpb.Key("b"), 1, tc.Clock()) args := pushTxnArgs(pusher, pushee, roachpb.PUSH_ABORT) args.Key = pusher.Key @@ -5534,8 +5464,8 @@ func TestPushTxnAlreadyCommittedOrAborted(t *testing.T) { for i, status := range []roachpb.TransactionStatus{roachpb.COMMITTED, roachpb.ABORTED} { key := roachpb.Key(fmt.Sprintf("key-%d", i)) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", key, 1, tc.Clock()) + pushee := newTransaction("test", key, 1, tc.Clock()) // Begin the pushee's transaction. _, btH := beginTxnArgs(key, pushee) @@ -5591,8 +5521,8 @@ func TestPushTxnUpgradeExistingTxn(t *testing.T) { for i, test := range testCases { key := roachpb.Key(fmt.Sprintf("key-%d", i)) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", key, 1, tc.Clock()) + pushee := newTransaction("test", key, 1, tc.Clock()) pushee.Epoch = 12345 pusher.Priority = roachpb.MaxTxnPriority // Pusher will win pusher.Writing = true // expected when a txn is heartbeat @@ -5639,7 +5569,7 @@ func TestPushTxnQueryPusheeHasNewerVersion(t *testing.T) { tc.Start(t, stopper) key := roachpb.Key("key") - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pushee := newTransaction("test", key, 1, tc.Clock()) pushee.Priority = 1 pushee.Epoch = 12345 pushee.Sequence = 2 @@ -5647,7 +5577,7 @@ func TestPushTxnQueryPusheeHasNewerVersion(t *testing.T) { pushee.Timestamp = ts pushee.LastHeartbeat = ts - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", key, 1, tc.Clock()) pusher.Priority = 2 _, btH := beginTxnArgs(key, pushee) @@ -5711,8 +5641,8 @@ func TestPushTxnHeartbeatTimeout(t *testing.T) { for i, test := range testCases { key := roachpb.Key(fmt.Sprintf("key-%d", i)) - pushee := newTransaction(fmt.Sprintf("test-%d", i), key, 1, enginepb.SERIALIZABLE, tc.Clock()) - pusher := newTransaction("pusher", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pushee := newTransaction(fmt.Sprintf("test-%d", i), key, 1, tc.Clock()) + pusher := newTransaction("pusher", key, 1, tc.Clock()) // First, establish "start" of existing pushee's txn via BeginTransaction. if test.heartbeat != (hlc.Timestamp{}) { @@ -5761,7 +5691,7 @@ func TestResolveIntentPushTxnReplyTxn(t *testing.T) { b := tc.engine.NewBatch() defer b.Close() - txn := newTransaction("test", roachpb.Key("test"), 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", roachpb.Key("test"), 1, tc.Clock()) txnPushee := txn.Clone() pa := pushTxnArgs(txn, &txnPushee, roachpb.PUSH_ABORT) var ms enginepb.MVCCStats @@ -5835,8 +5765,8 @@ func TestPushTxnPriorities(t *testing.T) { for i, test := range testCases { key := roachpb.Key(fmt.Sprintf("key-%d", i)) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", key, 1, tc.Clock()) + pushee := newTransaction("test", key, 1, tc.Clock()) pusher.Priority = test.pusherPriority pushee.Priority = test.pusheePriority pusher.Timestamp = test.pusherTS @@ -5880,8 +5810,8 @@ func TestPushTxnPushTimestamp(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - pusher := newTransaction("test", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) - pushee := newTransaction("test", roachpb.Key("b"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", roachpb.Key("a"), 1, tc.Clock()) + pushee := newTransaction("test", roachpb.Key("b"), 1, tc.Clock()) pusher.Priority = roachpb.MaxTxnPriority pushee.Priority = roachpb.MinTxnPriority // pusher will win now := tc.Clock().Now() @@ -5926,8 +5856,8 @@ func TestPushTxnPushTimestampAlreadyPushed(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - pusher := newTransaction("test", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) - pushee := newTransaction("test", roachpb.Key("b"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("test", roachpb.Key("a"), 1, tc.Clock()) + pushee := newTransaction("test", roachpb.Key("b"), 1, tc.Clock()) now := tc.Clock().Now() pusher.Timestamp = now.Add(50, 0) pushee.Timestamp = now.Add(50, 1) @@ -5971,8 +5901,8 @@ func TestPushTxnSerializableRestart(t *testing.T) { tc.Start(t, stopper) key := roachpb.Key("a") - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + pushee := newTransaction("test", key, 1, tc.Clock()) + pusher := newTransaction("test", key, 1, tc.Clock()) pushee.Priority = roachpb.MinTxnPriority pusher.Priority = roachpb.MaxTxnPriority // pusher will win @@ -6033,139 +5963,129 @@ func TestPushTxnSerializableRestart(t *testing.T) { func TestQueryIntentRequest(t *testing.T) { defer leaktest.AfterTest(t)() - for _, iso := range []enginepb.IsolationType{enginepb.SNAPSHOT, enginepb.SERIALIZABLE} { - t.Run(iso.String(), func(t *testing.T) { - for _, behavior := range []roachpb.QueryIntentRequest_IfMissingBehavior{ - roachpb.QueryIntentRequest_DO_NOTHING, - roachpb.QueryIntentRequest_RETURN_ERROR, - roachpb.QueryIntentRequest_PREVENT, - } { - if iso == enginepb.SNAPSHOT && behavior == roachpb.QueryIntentRequest_PREVENT { - // Cannot prevent SNAPSHOT transaction with QueryIntent. - continue - } - t.Run(fmt.Sprintf("behavior=%s", behavior), func(t *testing.T) { + for _, behavior := range []roachpb.QueryIntentRequest_IfMissingBehavior{ + roachpb.QueryIntentRequest_DO_NOTHING, + roachpb.QueryIntentRequest_RETURN_ERROR, + roachpb.QueryIntentRequest_PREVENT, + } { + t.Run(fmt.Sprintf("behavior=%s", behavior), func(t *testing.T) { - tc := testContext{} - stopper := stop.NewStopper() - defer stopper.Stop(context.TODO()) - tc.Start(t, stopper) + tc := testContext{} + stopper := stop.NewStopper() + defer stopper.Stop(context.TODO()) + tc.Start(t, stopper) - key1 := roachpb.Key("a") - key2 := roachpb.Key("b") - txn := newTransaction("test", key1, 1, iso, tc.Clock()) - txn2 := newTransaction("test2", key2, 1, iso, tc.Clock()) + key1 := roachpb.Key("a") + key2 := roachpb.Key("b") + txn := newTransaction("test", key1, 1, tc.Clock()) + txn2 := newTransaction("test2", key2, 1, tc.Clock()) - pArgs := putArgs(key1, []byte("value1")) - assignSeqNumsForReqs(txn, &pArgs) - if _, pErr := tc.SendWrappedWith(roachpb.Header{Txn: txn}, &pArgs); pErr != nil { - t.Fatal(pErr) - } + pArgs := putArgs(key1, []byte("value1")) + assignSeqNumsForReqs(txn, &pArgs) + if _, pErr := tc.SendWrappedWith(roachpb.Header{Txn: txn}, &pArgs); pErr != nil { + t.Fatal(pErr) + } - queryIntent := func( - key []byte, - txnMeta enginepb.TxnMeta, - baTxn *roachpb.Transaction, - expectIntent bool, - ) { - t.Helper() - qiArgs := queryIntentArgs(key, txnMeta, behavior) - qiRes, pErr := tc.SendWrappedWith(roachpb.Header{Txn: baTxn}, &qiArgs) - if behavior == roachpb.QueryIntentRequest_RETURN_ERROR && !expectIntent { - ownIntent := baTxn != nil && baTxn.ID == txnMeta.ID - if ownIntent && txnMeta.Timestamp.Less(txn.Timestamp) { - if _, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok { - t.Fatalf("expected TransactionRetryError, found %v %v", txnMeta, pErr) - } - } else { - if _, ok := pErr.GetDetail().(*roachpb.IntentMissingError); !ok { - t.Fatalf("expected IntentMissingError, found %v", pErr) - } - } - } else { - if pErr != nil { - t.Fatal(pErr) - } - if e, a := expectIntent, qiRes.(*roachpb.QueryIntentResponse).FoundIntent; e != a { - t.Fatalf("expected FoundIntent=%t but FoundIntent=%t", e, a) - } + queryIntent := func( + key []byte, + txnMeta enginepb.TxnMeta, + baTxn *roachpb.Transaction, + expectIntent bool, + ) { + t.Helper() + qiArgs := queryIntentArgs(key, txnMeta, behavior) + qiRes, pErr := tc.SendWrappedWith(roachpb.Header{Txn: baTxn}, &qiArgs) + if behavior == roachpb.QueryIntentRequest_RETURN_ERROR && !expectIntent { + ownIntent := baTxn != nil && baTxn.ID == txnMeta.ID + if ownIntent && txnMeta.Timestamp.Less(txn.Timestamp) { + if _, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok { + t.Fatalf("expected TransactionRetryError, found %v %v", txnMeta, pErr) + } + } else { + if _, ok := pErr.GetDetail().(*roachpb.IntentMissingError); !ok { + t.Fatalf("expected IntentMissingError, found %v", pErr) } } - - for _, baTxn := range []*roachpb.Transaction{nil, txn, txn2} { - // Query the intent with the correct txn meta. Should see intent regardless - // of whether we're inside the txn or not. - queryIntent(key1, txn.TxnMeta, baTxn, true) - - // Query an intent on a different key for the same transaction. Should not - // see an intent. - queryIntent(key2, txn.TxnMeta, baTxn, false) - - // Query an intent on the same key for a different transaction. Should not - // see an intent. - diffIDMeta := txn.TxnMeta - diffIDMeta.ID = txn2.ID - queryIntent(key1, diffIDMeta, baTxn, false) - - // Query the intent with a larger epoch. Should not see an intent. - largerEpochMeta := txn.TxnMeta - largerEpochMeta.Epoch++ - queryIntent(key1, largerEpochMeta, baTxn, false) - - // Query the intent with a smaller epoch. Should not see an intent. - smallerEpochMeta := txn.TxnMeta - smallerEpochMeta.Epoch-- - queryIntent(key1, smallerEpochMeta, baTxn, false) - - // Query the intent with a larger timestamp. Should see an intent. - // See the comment on QueryIntentRequest.Txn for an explanation of why - // the request behaves like this. - largerTSMeta := txn.TxnMeta - largerTSMeta.Timestamp = largerTSMeta.Timestamp.Next() - queryIntent(key1, largerTSMeta, baTxn, true) - - // Query the intent with a smaller timestamp. Should not see an intent - // if transaction is serializable. Should see an intent if the transaction - // is SNAPSHOT. - smallerTSMeta := txn.TxnMeta - smallerTSMeta.Timestamp = smallerTSMeta.Timestamp.Prev() - queryIntent(key1, smallerTSMeta, baTxn, iso == enginepb.SNAPSHOT) - - // Query the intent with a larger sequence number. Should not see an intent. - largerSeqMeta := txn.TxnMeta - largerSeqMeta.Sequence++ - queryIntent(key1, largerSeqMeta, baTxn, false) - - // Query the intent with a smaller sequence number. Should see an intent. - // See the comment on QueryIntentRequest.Txn for an explanation of why - // the request behaves like this. - smallerSeqMeta := txn.TxnMeta - smallerSeqMeta.Sequence-- - queryIntent(key1, smallerSeqMeta, baTxn, true) - } - - // Perform a write at key2. Depending on the behavior of the queryIntent - // that queried that key, this write should have different results. - pArgs2 := putArgs(key2, []byte("value2")) - assignSeqNumsForReqs(txn, &pArgs2) - ba := roachpb.BatchRequest{} - ba.Header = roachpb.Header{Txn: txn} - ba.Add(&pArgs2) - br, pErr := tc.Sender().Send(context.Background(), ba) + } else { if pErr != nil { t.Fatal(pErr) } - tsBumped := br.Txn.Timestamp != br.Txn.OrigTimestamp - if behavior == roachpb.QueryIntentRequest_PREVENT { - if !tsBumped { - t.Fatalf("transaction timestamp not bumped: %v", br.Txn) - } - } else { - if tsBumped { - t.Fatalf("unexpected transaction timestamp bumped: %v", br.Txn) - } + if e, a := expectIntent, qiRes.(*roachpb.QueryIntentResponse).FoundIntent; e != a { + t.Fatalf("expected FoundIntent=%t but FoundIntent=%t", e, a) } - }) + } + } + + for _, baTxn := range []*roachpb.Transaction{nil, txn, txn2} { + // Query the intent with the correct txn meta. Should see intent regardless + // of whether we're inside the txn or not. + queryIntent(key1, txn.TxnMeta, baTxn, true) + + // Query an intent on a different key for the same transaction. Should not + // see an intent. + queryIntent(key2, txn.TxnMeta, baTxn, false) + + // Query an intent on the same key for a different transaction. Should not + // see an intent. + diffIDMeta := txn.TxnMeta + diffIDMeta.ID = txn2.ID + queryIntent(key1, diffIDMeta, baTxn, false) + + // Query the intent with a larger epoch. Should not see an intent. + largerEpochMeta := txn.TxnMeta + largerEpochMeta.Epoch++ + queryIntent(key1, largerEpochMeta, baTxn, false) + + // Query the intent with a smaller epoch. Should not see an intent. + smallerEpochMeta := txn.TxnMeta + smallerEpochMeta.Epoch-- + queryIntent(key1, smallerEpochMeta, baTxn, false) + + // Query the intent with a larger timestamp. Should see an intent. + // See the comment on QueryIntentRequest.Txn for an explanation of why + // the request behaves like this. + largerTSMeta := txn.TxnMeta + largerTSMeta.Timestamp = largerTSMeta.Timestamp.Next() + queryIntent(key1, largerTSMeta, baTxn, true) + + // Query the intent with a smaller timestamp. Should not see an intent. + smallerTSMeta := txn.TxnMeta + smallerTSMeta.Timestamp = smallerTSMeta.Timestamp.Prev() + queryIntent(key1, smallerTSMeta, baTxn, false) + + // Query the intent with a larger sequence number. Should not see an intent. + largerSeqMeta := txn.TxnMeta + largerSeqMeta.Sequence++ + queryIntent(key1, largerSeqMeta, baTxn, false) + + // Query the intent with a smaller sequence number. Should see an intent. + // See the comment on QueryIntentRequest.Txn for an explanation of why + // the request behaves like this. + smallerSeqMeta := txn.TxnMeta + smallerSeqMeta.Sequence-- + queryIntent(key1, smallerSeqMeta, baTxn, true) + } + + // Perform a write at key2. Depending on the behavior of the queryIntent + // that queried that key, this write should have different results. + pArgs2 := putArgs(key2, []byte("value2")) + assignSeqNumsForReqs(txn, &pArgs2) + ba := roachpb.BatchRequest{} + ba.Header = roachpb.Header{Txn: txn} + ba.Add(&pArgs2) + br, pErr := tc.Sender().Send(context.Background(), ba) + if pErr != nil { + t.Fatal(pErr) + } + tsBumped := br.Txn.Timestamp != br.Txn.OrigTimestamp + if behavior == roachpb.QueryIntentRequest_PREVENT { + if !tsBumped { + t.Fatalf("transaction timestamp not bumped: %v", br.Txn) + } + } else { + if tsBumped { + t.Fatalf("unexpected transaction timestamp bumped: %v", br.Txn) + } } }) } @@ -6180,7 +6100,7 @@ func TestReplicaResolveIntentRange(t *testing.T) { tc.Start(t, stopper) keys := []roachpb.Key{roachpb.Key("a"), roachpb.Key("b")} - txn := newTransaction("test", keys[0], 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", keys[0], 1, tc.Clock()) // Put two values transactionally. for _, key := range keys { @@ -6281,7 +6201,7 @@ func TestRangeStatsComputation(t *testing.T) { if err != nil { t.Fatal(err) } - txn := newTransaction("test", pArgs.Key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", pArgs.Key, 1, tc.Clock()) txn.Priority = 123 // So we don't have random values messing with the byte counts on encoding txn.ID = uuid @@ -6739,7 +6659,7 @@ func TestReplicaDanglingMetaIntent(t *testing.T) { if err != nil { t.Fatal(err) } - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) // Officially begin the transaction. If not for this, the intent resolution // machinery would simply remove the intent we write below, see #3020. // We send directly to Replica throughout this test, so there's no danger @@ -6820,7 +6740,7 @@ func TestReplicaLookupUseReverseScan(t *testing.T) { } { - txn := newTransaction("test", roachpb.Key{}, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", roachpb.Key{}, 1, tc.Clock()) for _, r := range testRanges { // Write the new descriptor as an intent. data, err := protoutil.Marshal(&r) @@ -6863,7 +6783,7 @@ func TestReplicaLookupUseReverseScan(t *testing.T) { } // Write the new descriptors as intents. - txn := newTransaction("test", roachpb.Key{}, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", roachpb.Key{}, 1, tc.Clock()) for _, r := range []roachpb.RangeDescriptor{splitRangeLHS, splitRangeRHS} { // Write the new descriptor as an intent. data, err := protoutil.Marshal(&r) @@ -7125,7 +7045,7 @@ func TestReplicaLoadSystemConfigSpanIntent(t *testing.T) { // Create a transaction and write an intent to the system // config span. key := keys.SystemConfigSpan.Key - _, btH := beginTxnArgs(key, newTransaction("test", key, 1, enginepb.SERIALIZABLE, repl.store.Clock())) + _, btH := beginTxnArgs(key, newTransaction("test", key, 1, repl.store.Clock())) btH.Txn.Priority = roachpb.MinTxnPriority // low so it can be pushed put := putArgs(key, []byte("foo")) assignSeqNumsForReqs(btH.Txn, &put) @@ -7136,7 +7056,7 @@ func TestReplicaLoadSystemConfigSpanIntent(t *testing.T) { // Abort the transaction so that the async intent resolution caused // by loading the system config span doesn't waste any time in // clearing the intent. - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, repl.store.Clock()) + pusher := newTransaction("test", key, 1, repl.store.Clock()) pusher.Priority = roachpb.MaxTxnPriority // will push successfully pushArgs := pushTxnArgs(pusher, btH.Txn, roachpb.PUSH_ABORT) if _, pErr := tc.SendWrapped(&pushArgs); pErr != nil { @@ -8529,7 +8449,7 @@ func TestAmbiguousResultErrorOnRetry(t *testing.T) { { ba1PCTxn.RangeID = 1 key := roachpb.Key("1pc") - txn := newTransaction("1pc", key, -1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("1pc", key, -1, tc.Clock()) bt, _ := beginTxnArgs(key, txn) put := putArgs(key, []byte("value")) et, etH := endTxnArgs(txn, true) @@ -8724,7 +8644,7 @@ func TestFailureToProcessCommandClearsLocalResult(t *testing.T) { tc.StartWithStoreConfig(t, stopper, cfg) key := roachpb.Key("a") - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) bt, btH := beginTxnArgs(key, txn) assignSeqNumsForReqs(txn, &bt) put := putArgs(key, []byte("value")) @@ -8872,7 +8792,7 @@ func TestReplicaTimestampCacheBumpNotLost(t *testing.T) { ctx := tc.store.AnnotateCtx(context.TODO()) key := keys.LocalMax - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) minNewTS := func() hlc.Timestamp { var ba roachpb.BatchRequest @@ -8929,7 +8849,7 @@ func TestReplicaEvaluationNotTxnMutation(t *testing.T) { ctx := tc.repl.AnnotateCtx(context.TODO()) key := keys.LocalMax - txn := newTransaction("test", key, 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("test", key, 1, tc.Clock()) var ba roachpb.BatchRequest ba.Txn = txn @@ -9282,7 +9202,6 @@ func TestNoopRequestsNotProposed(t *testing.T) { "name", rh.Key, roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, cfg.Clock, ) @@ -9530,9 +9449,7 @@ func TestErrorInRaftApplicationClearsIntents(t *testing.T) { t.Fatal(err) } - txn := newTransaction("test", key, roachpb.NormalUserPriority, - enginepb.SERIALIZABLE, s.Clock(), - ) + txn := newTransaction("test", key, roachpb.NormalUserPriority, s.Clock()) btArgs, _ := beginTxnArgs(key, txn) var ba roachpb.BatchRequest ba.Header.Txn = txn @@ -10127,7 +10044,7 @@ func TestReplicaLocalRetries(t *testing.T) { newTxn := func(key string, ts hlc.Timestamp) *roachpb.Transaction { txn := roachpb.MakeTransaction( - "test", roachpb.Key(key), roachpb.NormalUserPriority, enginepb.SERIALIZABLE, ts, 0, + "test", roachpb.Key(key), roachpb.NormalUserPriority, ts, 0, ) return &txn } @@ -10467,58 +10384,54 @@ func TestReplicaPushed1PC(t *testing.T) { defer stopper.Stop(context.TODO()) tc.Start(t, stopper) - for _, isolation := range []enginepb.IsolationType{enginepb.SERIALIZABLE, enginepb.SNAPSHOT} { - t.Run(isolation.String(), func(t *testing.T) { - ctx := context.Background() - k := roachpb.Key(isolation.String()) - - // Start a transaction and assign its OrigTimestamp. - ts1 := tc.Clock().Now() - txn := roachpb.MakeTransaction("test", k, roachpb.NormalUserPriority, isolation, ts1, 0) - - // Write a value outside the transaction. - tc.manualClock.Increment(10) - ts2 := tc.Clock().Now() - if err := engine.MVCCPut(ctx, tc.engine, nil, k, ts2, roachpb.MakeValueFromString("one"), nil); err != nil { - t.Fatalf("writing interfering value: %s", err) - } - - // Push the transaction's timestamp. In real-world situations, - // the only thing that can push a read-only transaction's - // timestamp is ReadWithinUncertaintyIntervalError, but - // synthesizing one of those in this single-node test harness is - // tricky. - tc.manualClock.Increment(10) - ts3 := tc.Clock().Now() - txn.Timestamp.Forward(ts3) - - // Execute the write phase of the transaction as a single batch, - // which must return a WRITE_TOO_OLD TransactionRetryError. - // - // TODO(bdarnell): When this test was written, in SNAPSHOT - // isolation we would attempt to execute the transaction on the - // 1PC path, see a timestamp mismatch, and then then throw the - // 1PC results away and re-execute it on the regular path (which - // would generate the WRITE_TOO_OLD error). We have added earlier - // timestamp checks for a small performance improvement, but - // this difference is difficult to observe in a test. If we had - // more detailed metrics we could assert that the 1PC path was - // not even attempted here. - var ba roachpb.BatchRequest - bt, h := beginTxnArgs(txn.Key, &txn) - ba.Header = h - put := putArgs(k, []byte("two")) - et, _ := endTxnArgs(&txn, true) - ba.Add(&bt, &put, &et) - assignSeqNumsForReqs(&txn, &bt, &put, &et) - if br, pErr := tc.Sender().Send(ctx, ba); pErr == nil { - t.Errorf("did not get expected error. resp=%s", br) - } else if trErr, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok { - t.Errorf("expected TransactionRetryError, got %s", pErr) - } else if trErr.Reason != roachpb.RETRY_WRITE_TOO_OLD { - t.Errorf("expected RETRY_WRITE_TOO_OLD, got %s", trErr) - } - }) + ctx := context.Background() + k := roachpb.Key("key") + + // Start a transaction and assign its OrigTimestamp. + ts1 := tc.Clock().Now() + txn := roachpb.MakeTransaction("test", k, roachpb.NormalUserPriority, ts1, 0) + + // Write a value outside the transaction. + tc.manualClock.Increment(10) + ts2 := tc.Clock().Now() + if err := engine.MVCCPut(ctx, tc.engine, nil, k, ts2, roachpb.MakeValueFromString("one"), nil); err != nil { + t.Fatalf("writing interfering value: %s", err) + } + + // Push the transaction's timestamp. In real-world situations, + // the only thing that can push a read-only transaction's + // timestamp is ReadWithinUncertaintyIntervalError, but + // synthesizing one of those in this single-node test harness is + // tricky. + tc.manualClock.Increment(10) + ts3 := tc.Clock().Now() + txn.Timestamp.Forward(ts3) + + // Execute the write phase of the transaction as a single batch, + // which must return a WRITE_TOO_OLD TransactionRetryError. + // + // TODO(bdarnell): When this test was written, in SNAPSHOT + // isolation we would attempt to execute the transaction on the + // 1PC path, see a timestamp mismatch, and then then throw the + // 1PC results away and re-execute it on the regular path (which + // would generate the WRITE_TOO_OLD error). We have added earlier + // timestamp checks for a small performance improvement, but + // this difference is difficult to observe in a test. If we had + // more detailed metrics we could assert that the 1PC path was + // not even attempted here. + var ba roachpb.BatchRequest + bt, h := beginTxnArgs(txn.Key, &txn) + ba.Header = h + put := putArgs(k, []byte("two")) + et, _ := endTxnArgs(&txn, true) + ba.Add(&bt, &put, &et) + assignSeqNumsForReqs(&txn, &bt, &put, &et) + if br, pErr := tc.Sender().Send(ctx, ba); pErr == nil { + t.Errorf("did not get expected error. resp=%s", br) + } else if trErr, ok := pErr.GetDetail().(*roachpb.TransactionRetryError); !ok { + t.Errorf("expected TransactionRetryError, got %s", pErr) + } else if trErr.Reason != roachpb.RETRY_WRITE_TOO_OLD { + t.Errorf("expected RETRY_WRITE_TOO_OLD, got %s", trErr) } } @@ -10915,7 +10828,7 @@ func TestRollbackMissingTxnRecordNoError(t *testing.T) { key := roachpb.Key("bogus key") txn := roachpb.MakeTransaction("test", key, - roachpb.NormalUserPriority, enginepb.SERIALIZABLE, + roachpb.NormalUserPriority, tc.Clock().Now(), tc.Clock().MaxOffset().Nanoseconds()) res, pErr := client.SendWrappedWith(ctx, tc.Sender(), roachpb.Header{ diff --git a/pkg/storage/store_test.go b/pkg/storage/store_test.go index 870134042fb9..102bbefc1dec 100644 --- a/pkg/storage/store_test.go +++ b/pkg/storage/store_test.go @@ -1015,7 +1015,7 @@ func TestStoreObservedTimestamp(t *testing.T) { stopper := stop.NewStopper() defer stopper.Stop(context.TODO()) store := createTestStoreWithConfig(t, stopper, &cfg) - txn := newTransaction("test", test.key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + txn := newTransaction("test", test.key, 1, store.cfg.Clock) txn.MaxTimestamp = hlc.MaxTimestamp pArgs := putArgs(test.key, []byte("value")) h := roachpb.Header{ @@ -1082,7 +1082,7 @@ func TestStoreAnnotateNow(t *testing.T) { var txn *roachpb.Transaction pArgs := putArgs(test.key, []byte("value")) if useTxn { - txn = newTransaction("test", test.key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + txn = newTransaction("test", test.key, 1, store.cfg.Clock) txn.MaxTimestamp = hlc.MaxTimestamp assignSeqNumsForReqs(txn, &pArgs) } @@ -1436,8 +1436,8 @@ func TestStoreResolveWriteIntent(t *testing.T) { for i, resolvable := range []bool{true, false} { key := roachpb.Key(fmt.Sprintf("key-%d", i)) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + pusher := newTransaction("test", key, 1, store.cfg.Clock) + pushee := newTransaction("test", key, 1, store.cfg.Clock) if resolvable { pushee.Priority = roachpb.MinTxnPriority pusher.Priority = roachpb.MaxTxnPriority // Pusher will win. @@ -1504,8 +1504,8 @@ func TestStoreResolveWriteIntentRollback(t *testing.T) { store, _ := createTestStore(t, stopper) key := roachpb.Key("a") - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + pusher := newTransaction("test", key, 1, store.cfg.Clock) + pushee := newTransaction("test", key, 1, store.cfg.Clock) pushee.Priority = roachpb.MinTxnPriority pusher.Priority = roachpb.MaxTxnPriority // Pusher will win. @@ -1539,25 +1539,12 @@ func TestStoreResolveWriteIntentPushOnRead(t *testing.T) { defer stopper.Stop(context.TODO()) store := createTestStoreWithConfig(t, stopper, &storeCfg) - testCases := []struct { - resolvable bool - pusheeIso enginepb.IsolationType - }{ - // Resolvable is true, so we can read, but SERIALIZABLE means we can't commit. - {true, enginepb.SERIALIZABLE}, - // Pushee is SNAPSHOT, meaning we can commit. - {true, enginepb.SNAPSHOT}, - // Resolvable is false and SERIALIZABLE so can't read. - {false, enginepb.SERIALIZABLE}, - // Resolvable is false, but SNAPSHOT means we can push it anyway, so can read. - {false, enginepb.SNAPSHOT}, - } - for i, test := range testCases { + for i, resolvable := range []bool{true, false} { key := roachpb.Key(fmt.Sprintf("key-%d", i)) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) - pushee := newTransaction("test", key, 1, test.pusheeIso, store.cfg.Clock) + pusher := newTransaction("test", key, 1, store.cfg.Clock) + pushee := newTransaction("test", key, 1, store.cfg.Clock) - if test.resolvable { + if resolvable { pushee.Priority = roachpb.MinTxnPriority pusher.Priority = roachpb.MaxTxnPriority // Pusher will win. } else { @@ -1589,7 +1576,7 @@ func TestStoreResolveWriteIntentPushOnRead(t *testing.T) { gArgs := getArgs(key) assignSeqNumsForReqs(pusher, &gArgs) firstReply, pErr := client.SendWrappedWith(context.Background(), store.TestSender(), roachpb.Header{Txn: pusher}, &gArgs) - if test.resolvable { + if resolvable { if pErr != nil { t.Errorf("%d: expected read to succeed: %s", i, pErr) } else if replyBytes, err := firstReply.(*roachpb.GetResponse).Value.GetBytes(); err != nil { @@ -1604,105 +1591,23 @@ func TestStoreResolveWriteIntentPushOnRead(t *testing.T) { // Otherwise, verify commit fails with TransactionRetryError. etArgs, h := endTxnArgs(pushee, true) assignSeqNumsForReqs(pushee, &etArgs) - reply, cErr := client.SendWrappedWith(context.Background(), store.TestSender(), h, &etArgs) - - minExpTS := pusher.Timestamp - minExpTS.Logical++ - if test.pusheeIso == enginepb.SNAPSHOT { - if cErr != nil { - t.Fatalf("unexpected error on commit: %s", cErr) - } - etReply := reply.(*roachpb.EndTransactionResponse) - if etReply.Txn.Status != roachpb.COMMITTED || etReply.Txn.Timestamp.Less(minExpTS) { - t.Errorf("txn commit didn't yield expected status (COMMITTED) or timestamp %s: %s", - minExpTS, etReply.Txn) - } - } else { - if _, ok := cErr.GetDetail().(*roachpb.TransactionRetryError); !ok { - t.Errorf("expected transaction retry error; got %s", cErr) - } + _, cErr := client.SendWrappedWith(context.Background(), store.TestSender(), h, &etArgs) + if _, ok := cErr.GetDetail().(*roachpb.TransactionRetryError); !ok { + t.Errorf("expected transaction retry error; got %s", cErr) } } else { - // If isolation of pushee is SNAPSHOT, we can always push, so - // even a non-resolvable read will succeed. Otherwise, verify we - // receive a transaction retry error (because we max out retries). - if test.pusheeIso == enginepb.SNAPSHOT { - if pErr != nil { - t.Errorf("expected read to succeed: %s", pErr) - } else if replyBytes, err := firstReply.(*roachpb.GetResponse).Value.GetBytes(); err != nil { - t.Fatal(err) - } else if !bytes.Equal(replyBytes, []byte("value1")) { - t.Errorf("expected bytes to be %q, got %q", "value1", replyBytes) - } - } else { - if pErr == nil { - t.Errorf("expected read to fail") - } - if _, ok := pErr.GetDetail().(*roachpb.TransactionPushError); !ok { - t.Errorf("iso=%s; expected transaction push error; got %T", test.pusheeIso, pErr.GetDetail()) - } + // Verify we receive a transaction retry error (because we max out + // retries). + if pErr == nil { + t.Errorf("expected read to fail") + } + if _, ok := pErr.GetDetail().(*roachpb.TransactionPushError); !ok { + t.Errorf("expected transaction push error; got %T", pErr.GetDetail()) } } } } -// TestStoreResolveWriteIntentSnapshotIsolation verifies that the -// timestamp can always be pushed if txn has snapshot isolation. -func TestStoreResolveWriteIntentSnapshotIsolation(t *testing.T) { - defer leaktest.AfterTest(t)() - stopper := stop.NewStopper() - defer stopper.Stop(context.TODO()) - store, _ := createTestStore(t, stopper) - - key := roachpb.Key("a") - - // First, write original value. - args := putArgs(key, []byte("value1")) - ts := store.cfg.Clock.Now() - if _, pErr := client.SendWrappedWith(context.Background(), store.TestSender(), roachpb.Header{Timestamp: ts}, &args); pErr != nil { - t.Fatal(pErr) - } - - // Lay down intent using the pushee's txn. - pushee := newTransaction("test", key, 1, enginepb.SNAPSHOT, store.cfg.Clock) - h := roachpb.Header{Txn: pushee} - args.Value.SetBytes([]byte("value2")) - assignSeqNumsForReqs(pushee, &args) - if _, pErr := maybeWrapWithBeginTransaction(context.Background(), store.TestSender(), h, &args); pErr != nil { - t.Fatal(pErr) - } - - // Now, try to read value using the pusher's txn. - gArgs := getArgs(key) - pusher := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) - h.Txn = pusher - assignSeqNumsForReqs(pusher, &gArgs) - if reply, pErr := client.SendWrappedWith(context.Background(), store.TestSender(), h, &gArgs); pErr != nil { - t.Errorf("expected read to succeed: %s", pErr) - } else if replyBytes, err := reply.(*roachpb.GetResponse).Value.GetBytes(); err != nil { - t.Fatal(err) - } else if !bytes.Equal(replyBytes, []byte("value1")) { - t.Errorf("expected bytes to be %q, got %q", "value0", replyBytes) - } - - // Finally, try to end the pushee's transaction; since it's got - // SNAPSHOT isolation, the end should work, but verify the txn - // commit timestamp is equal to gArgs.Timestamp + 1. - etArgs, h := endTxnArgs(pushee, true) - assignSeqNumsForReqs(pushee, &etArgs) - reply, pErr := client.SendWrappedWith(context.Background(), store.TestSender(), h, &etArgs) - if pErr != nil { - t.Fatal(pErr) - } - etReply := reply.(*roachpb.EndTransactionResponse) - minExpTS := pusher.Timestamp - minExpTS.Logical++ - if etReply.Txn.Status != roachpb.COMMITTED || etReply.Txn.Timestamp.Less(minExpTS) { - t.Errorf("txn commit didn't yield expected status (COMMITTED) or timestamp %s: %s", - minExpTS, etReply.Txn) - } -} - // TestStoreResolveWriteIntentNoTxn verifies that reads and writes // which are not part of a transaction can push intents. func TestStoreResolveWriteIntentNoTxn(t *testing.T) { @@ -1712,7 +1617,7 @@ func TestStoreResolveWriteIntentNoTxn(t *testing.T) { store, _ := createTestStore(t, stopper) key := roachpb.Key("a") - pushee := newTransaction("test", key, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + pushee := newTransaction("test", key, 1, store.cfg.Clock) // First, lay down intent from pushee. args := putArgs(key, []byte("value1")) @@ -1831,8 +1736,8 @@ func TestStoreReadInconsistent(t *testing.T) { priority = -1 } args.Value.SetBytes([]byte("value2")) - txnA := newTransaction("testA", keyA, priority, enginepb.SERIALIZABLE, store.cfg.Clock) - txnB := newTransaction("testB", keyB, priority, enginepb.SERIALIZABLE, store.cfg.Clock) + txnA := newTransaction("testA", keyA, priority, store.cfg.Clock) + txnB := newTransaction("testB", keyB, priority, store.cfg.Clock) for _, txn := range []*roachpb.Transaction{txnA, txnB} { args.Key = txn.Key assignSeqNumsForReqs(txn, &args) @@ -2133,7 +2038,7 @@ func TestStoreScanIntents(t *testing.T) { if test.canPush { priority = roachpb.MinUserPriority } - txn = newTransaction(fmt.Sprintf("test-%d", i), key, priority, enginepb.SERIALIZABLE, store.cfg.Clock) + txn = newTransaction(fmt.Sprintf("test-%d", i), key, priority, store.cfg.Clock) } args := putArgs(key, []byte(fmt.Sprintf("value%02d", j))) assignSeqNumsForReqs(txn, &args) @@ -2224,7 +2129,7 @@ func TestStoreScanInconsistentResolvesIntents(t *testing.T) { store := createTestStoreWithConfig(t, stopper, &cfg) // Lay down 10 intents to scan over. - txn := newTransaction("test", roachpb.Key("foo"), 1, enginepb.SERIALIZABLE, store.cfg.Clock) + txn := newTransaction("test", roachpb.Key("foo"), 1, store.cfg.Clock) keys := []roachpb.Key{} for j := 0; j < 10; j++ { key := roachpb.Key(fmt.Sprintf("key%02d", j)) @@ -2275,7 +2180,7 @@ func TestStoreScanIntentsFromTwoTxns(t *testing.T) { // Lay down two intents from two txns to scan over. key1 := roachpb.Key("bar") - txn1 := newTransaction("test1", key1, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + txn1 := newTransaction("test1", key1, 1, store.cfg.Clock) args := putArgs(key1, []byte("value1")) assignSeqNumsForReqs(txn1, &args) if _, pErr := maybeWrapWithBeginTransaction(context.Background(), store.TestSender(), roachpb.Header{Txn: txn1}, &args); pErr != nil { @@ -2284,7 +2189,7 @@ func TestStoreScanIntentsFromTwoTxns(t *testing.T) { txn1.Writing = true key2 := roachpb.Key("foo") - txn2 := newTransaction("test2", key2, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + txn2 := newTransaction("test2", key2, 1, store.cfg.Clock) args = putArgs(key2, []byte("value2")) assignSeqNumsForReqs(txn2, &args) if _, pErr := maybeWrapWithBeginTransaction(context.Background(), store.TestSender(), roachpb.Header{Txn: txn2}, &args); pErr != nil { @@ -2331,7 +2236,7 @@ func TestStoreScanMultipleIntents(t *testing.T) { // Lay down ten intents from a single txn. key1 := roachpb.Key("key00") key10 := roachpb.Key("key09") - txn := newTransaction("test", key1, 1, enginepb.SERIALIZABLE, store.cfg.Clock) + txn := newTransaction("test", key1, 1, store.cfg.Clock) txn.Writing = true ba := roachpb.BatchRequest{} for i := 0; i < 10; i++ { @@ -2377,7 +2282,7 @@ func TestStoreBadRequests(t *testing.T) { defer stopper.Stop(context.TODO()) store, _ := createTestStore(t, stopper) - txn := newTransaction("test", roachpb.Key("a"), 1 /* priority */, enginepb.SERIALIZABLE, store.cfg.Clock) + txn := newTransaction("test", roachpb.Key("a"), 1 /* priority */, store.cfg.Clock) args1 := getArgs(roachpb.Key("a")) args1.EndKey = roachpb.Key("b") diff --git a/pkg/storage/txn_wait_queue_test.go b/pkg/storage/txn_wait_queue_test.go index 3b7f0f79828a..00ba0e40999c 100644 --- a/pkg/storage/txn_wait_queue_test.go +++ b/pkg/storage/txn_wait_queue_test.go @@ -26,7 +26,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/keys" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/engine" - "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" "github.com/cockroachdb/cockroach/pkg/storage/storagebase" "github.com/cockroachdb/cockroach/pkg/storage/txnwait" "github.com/cockroachdb/cockroach/pkg/testutils" @@ -45,7 +44,7 @@ func writeTxnRecord(ctx context.Context, tc *testContext, txn *roachpb.Transacti // createTxnForPushQueue creates a txn struct and writes a "fake" // transaction record for it to the underlying engine. func createTxnForPushQueue(ctx context.Context, tc *testContext) (*roachpb.Transaction, error) { - txn := newTransaction("txn", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + txn := newTransaction("txn", roachpb.Key("a"), 1, tc.Clock()) return txn, writeTxnRecord(ctx, tc, txn) } @@ -77,7 +76,7 @@ func TestTxnWaitQueueEnableDisable(t *testing.T) { t.Fatalf("expected pendingTxn to be in txns map after enqueue") } - pusher := newTransaction("pusher", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("pusher", roachpb.Key("a"), 1, tc.Clock()) req := roachpb.PushTxnRequest{ PushType: roachpb.PUSH_ABORT, PusherTxn: *pusher, @@ -142,7 +141,7 @@ func TestTxnWaitQueueCancel(t *testing.T) { if err != nil { t.Fatal(err) } - pusher := newTransaction("pusher", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("pusher", roachpb.Key("a"), 1, tc.Clock()) req := roachpb.PushTxnRequest{ PushType: roachpb.PUSH_ABORT, PusherTxn: *pusher, @@ -196,8 +195,8 @@ func TestTxnWaitQueueUpdateTxn(t *testing.T) { if err != nil { t.Fatal(err) } - pusher1 := newTransaction("pusher1", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) - pusher2 := newTransaction("pusher2", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher1 := newTransaction("pusher1", roachpb.Key("a"), 1, tc.Clock()) + pusher2 := newTransaction("pusher2", roachpb.Key("a"), 1, tc.Clock()) req1 := roachpb.PushTxnRequest{ PushType: roachpb.PUSH_ABORT, PusherTxn: *pusher1, @@ -281,7 +280,7 @@ func TestTxnWaitQueueTxnSilentlyCompletes(t *testing.T) { if err != nil { t.Fatal(err) } - pusher := newTransaction("pusher", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("pusher", roachpb.Key("a"), 1, tc.Clock()) req := &roachpb.PushTxnRequest{ PushType: roachpb.PUSH_ABORT, PusherTxn: *pusher, @@ -333,7 +332,7 @@ func TestTxnWaitQueueUpdateNotPushedTxn(t *testing.T) { if err != nil { t.Fatal(err) } - pusher := newTransaction("pusher", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher := newTransaction("pusher", roachpb.Key("a"), 1, tc.Clock()) req := roachpb.PushTxnRequest{ PushType: roachpb.PUSH_ABORT, PusherTxn: *pusher, @@ -379,7 +378,7 @@ func TestTxnWaitQueuePusheeExpires(t *testing.T) { manual := hlc.NewManualClock(123) clock := hlc.NewClock(manual.UnixNano, time.Nanosecond) - txn := newTransaction("txn", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, clock) + txn := newTransaction("txn", roachpb.Key("a"), 1, clock) // Move the clock forward so that when the PushTxn is sent, the txn appears // expired. manual.Set(txnwait.TxnExpiration(txn).WallTime) @@ -397,8 +396,8 @@ func TestTxnWaitQueuePusheeExpires(t *testing.T) { defer stopper.Stop(context.TODO()) tc.StartWithStoreConfig(t, stopper, tsc) - pusher1 := newTransaction("pusher1", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) - pusher2 := newTransaction("pusher2", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher1 := newTransaction("pusher1", roachpb.Key("a"), 1, tc.Clock()) + pusher2 := newTransaction("pusher2", roachpb.Key("a"), 1, tc.Clock()) req1 := roachpb.PushTxnRequest{ PushType: roachpb.PUSH_ABORT, PusherTxn: *pusher1, @@ -478,7 +477,7 @@ func TestTxnWaitQueuePusherUpdate(t *testing.T) { t.Fatal(err) } } else { - pusher = newTransaction("pusher", roachpb.Key("a"), 1, enginepb.SERIALIZABLE, tc.Clock()) + pusher = newTransaction("pusher", roachpb.Key("a"), 1, tc.Clock()) } req := roachpb.PushTxnRequest{ @@ -617,7 +616,7 @@ func TestTxnWaitQueueDependencyCycleWithPriorityInversion(t *testing.T) { // Create txnA with a lower priority so it won't think it could push // txnB without updating its priority. - txnA := newTransaction("txn", roachpb.Key("a"), -1, enginepb.SERIALIZABLE, tc.Clock()) + txnA := newTransaction("txn", roachpb.Key("a"), -1, tc.Clock()) // However, write an "updated" txnA with higher priority, which it // will need to read via a QueryTxn request in order to realize it // can in fact break the deadlock. @@ -629,7 +628,7 @@ func TestTxnWaitQueueDependencyCycleWithPriorityInversion(t *testing.T) { // Create txnB with priority=2, so txnA won't think it can push, but // when we set up txnB as the pusher, the request will include txnA's // updated priority, making txnB think it can't break a deadlock. - txnB := newTransaction("txn", roachpb.Key("a"), -2, enginepb.SERIALIZABLE, tc.Clock()) + txnB := newTransaction("txn", roachpb.Key("a"), -2, tc.Clock()) if err := writeTxnRecord(context.Background(), &tc, txnB); err != nil { t.Fatal(err) }