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) }