Skip to content

Commit

Permalink
kv: teach kvnemesis about read committed isolation
Browse files Browse the repository at this point in the history
Informs #100170.

This commit teaches kvnemesis to generate read committed isolation
transaction closures. As with snapshot isolation, validation of the
atomicity of read committed transactions is currently disabled, but we
still get coverage from having the transactions in the mix.

Release note: None
  • Loading branch information
nvanbenschoten committed Jun 5, 2023
1 parent 5f80e35 commit 6369846
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 14 deletions.
40 changes: 29 additions & 11 deletions pkg/kv/kvnemesis/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,27 @@ type ClosureTxnConfig struct {
CommitSerializable int
// CommitSnapshot is a snapshot transaction that commits normally.
CommitSnapshot int
// CommitReadCommitted is a read committed transaction that commits normally.
CommitReadCommitted int
// RollbackSerializable is a serializable transaction that encounters an error
// at the end and has to roll back.
RollbackSerializable int
// RollbackSnapshot is a snapshot transaction that encounters an error at the
// end and has to roll back.
RollbackSnapshot int
// RollbackReadCommitted is a read committed transaction that encounters an
// error at the end and has to roll back.
RollbackReadCommitted int
// CommitSerializableInBatch is a serializable transaction that commits via
// the CommitInBatchMethod. This is an important part of the 1pc txn fastpath.
CommitSerializableInBatch int
// CommitSnapshotInBatch is a snapshot transaction that commits via the
// CommitInBatchMethod. This is an important part of the 1pc txn fastpath.
CommitSnapshotInBatch int
// CommitReadCommittedInBatch is a read committed transaction that commits
// via the CommitInBatchMethod. This is an important part of the 1pc txn
// fastpath.
CommitReadCommittedInBatch int

TxnClientOps ClientOperationConfig
TxnBatchOps BatchOperationConfig
Expand Down Expand Up @@ -217,15 +226,18 @@ func newAllOperationsConfig() GeneratorConfig {
DB: clientOpConfig,
Batch: batchOpConfig,
ClosureTxn: ClosureTxnConfig{
CommitSerializable: 3,
CommitSnapshot: 3,
RollbackSerializable: 3,
RollbackSnapshot: 3,
CommitSerializableInBatch: 3,
CommitSnapshotInBatch: 3,
TxnClientOps: clientOpConfig,
TxnBatchOps: batchOpConfig,
CommitBatchOps: clientOpConfig,
CommitSerializable: 2,
CommitSnapshot: 2,
CommitReadCommitted: 2,
RollbackSerializable: 2,
RollbackSnapshot: 2,
RollbackReadCommitted: 2,
CommitSerializableInBatch: 2,
CommitSnapshotInBatch: 2,
CommitReadCommittedInBatch: 2,
TxnClientOps: clientOpConfig,
TxnBatchOps: batchOpConfig,
CommitBatchOps: clientOpConfig,
},
Split: SplitConfig{
SplitNew: 1,
Expand Down Expand Up @@ -862,19 +874,25 @@ func makeRandBatch(c *ClientOperationConfig) opGenFunc {

func (g *generator) registerClosureTxnOps(allowed *[]opGen, c *ClosureTxnConfig) {
const Commit, Rollback = ClosureTxnType_Commit, ClosureTxnType_Rollback
const SSI, SI = isolation.Serializable, isolation.Snapshot
const SSI, SI, RC = isolation.Serializable, isolation.Snapshot, isolation.ReadCommitted
addOpGen(allowed,
makeClosureTxn(Commit, SSI, &c.TxnClientOps, &c.TxnBatchOps, nil /* commitInBatch*/), c.CommitSerializable)
addOpGen(allowed,
makeClosureTxn(Commit, SI, &c.TxnClientOps, &c.TxnBatchOps, nil /* commitInBatch*/), c.CommitSnapshotInBatch)
makeClosureTxn(Commit, SI, &c.TxnClientOps, &c.TxnBatchOps, nil /* commitInBatch*/), c.CommitSnapshot)
addOpGen(allowed,
makeClosureTxn(Commit, RC, &c.TxnClientOps, &c.TxnBatchOps, nil /* commitInBatch*/), c.CommitReadCommitted)
addOpGen(allowed,
makeClosureTxn(Rollback, SSI, &c.TxnClientOps, &c.TxnBatchOps, nil /* commitInBatch*/), c.RollbackSerializable)
addOpGen(allowed,
makeClosureTxn(Rollback, SI, &c.TxnClientOps, &c.TxnBatchOps, nil /* commitInBatch*/), c.RollbackSnapshot)
addOpGen(allowed,
makeClosureTxn(Rollback, RC, &c.TxnClientOps, &c.TxnBatchOps, nil /* commitInBatch*/), c.RollbackReadCommitted)
addOpGen(allowed,
makeClosureTxn(Commit, SSI, &c.TxnClientOps, &c.TxnBatchOps, &c.CommitBatchOps), c.CommitSerializableInBatch)
addOpGen(allowed,
makeClosureTxn(Commit, SI, &c.TxnClientOps, &c.TxnBatchOps, &c.CommitBatchOps), c.CommitSnapshotInBatch)
addOpGen(allowed,
makeClosureTxn(Commit, RC, &c.TxnClientOps, &c.TxnBatchOps, &c.CommitBatchOps), c.CommitReadCommittedInBatch)
}

func makeClosureTxn(
Expand Down
6 changes: 6 additions & 0 deletions pkg/kv/kvnemesis/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ func TestRandStep(t *testing.T) {
counts.ClosureTxn.CommitSerializableInBatch++
case isolation.Snapshot:
counts.ClosureTxn.CommitSnapshotInBatch++
case isolation.ReadCommitted:
counts.ClosureTxn.CommitReadCommittedInBatch++
default:
t.Fatalf("unexpected isolation level %s", o.IsoLevel)
}
Expand All @@ -188,6 +190,8 @@ func TestRandStep(t *testing.T) {
counts.ClosureTxn.CommitSerializable++
case isolation.Snapshot:
counts.ClosureTxn.CommitSnapshot++
case isolation.ReadCommitted:
counts.ClosureTxn.CommitReadCommitted++
default:
t.Fatalf("unexpected isolation level %s", o.IsoLevel)
}
Expand All @@ -197,6 +201,8 @@ func TestRandStep(t *testing.T) {
counts.ClosureTxn.RollbackSerializable++
case isolation.Snapshot:
counts.ClosureTxn.RollbackSnapshot++
case isolation.ReadCommitted:
counts.ClosureTxn.RollbackReadCommitted++
default:
t.Fatalf("unexpected isolation level %s", o.IsoLevel)
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/kv/kvnemesis/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -714,9 +714,10 @@ func (v *validator) processOp(op Operation) {
prevFailures := v.failures
atomicTxnType := fmt.Sprintf(`%s txn`, t.IsoLevel.StringLower())
v.checkAtomic(atomicTxnType, t.Result)
if t.IsoLevel == isolation.Snapshot {
// TODO(nvanbenschoten): for now, we run snapshot transactions in the mix
// but don't validate their results. Doing so is non-trivial. See #100169.
if t.IsoLevel != isolation.Serializable {
// TODO(nvanbenschoten): for now, we run snapshot and read committed
// transactions in the mix but don't validate their results. Doing so
// is non-trivial. See #100169 and #100170
v.failures = prevFailures
}
case *SplitOperation:
Expand Down

0 comments on commit 6369846

Please sign in to comment.