Skip to content

Commit

Permalink
workload/tpcc: add SELECT FOR UPDATE locking for Read Committed
Browse files Browse the repository at this point in the history
Informs cockroachdb#100176.

This commit adds SELECT FOR UPDATE locking in two places to ensure that
the workload avoids anomalies when run under Read Committed isolation.

The first of these is in the NewOrder transaction, when querying the
"stock" table in preparation for updating quantities and order counts
for the items in an order. There are no consistency checks which fail
without this, but the locking is present in benchbase (https://github.com/cmu-db/benchbase/blob/546afa60dae4f8a6b00b84b77c77ff7684e494ad/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/NewOrder.java#L88)
and makes sense to do.

The second of these is in the Delivery transaction, when querying the
"new_order" table to select an order to deliver. The order selected is
processed by the transaction, including updating counters in the
corresponding "customer" row, so it's important to have full isolation.
Without this, consistency checks `3.3.2.10` and `3.3.2.12` (`workload
check tpcc --expensive-checks`) do fail, presumably because a customer's
row is updated twice for a single order.

This use of SELECT FOR UPDATE in the Delivery transaction is an
alternative to a patch like 36709df, which would probably be more
efficient than the approach we have here, but would not exercise the
database in an interesting way. We opt to use SELECT FOR UPDATE.

Release note: None
  • Loading branch information
nvanbenschoten committed Nov 15, 2023
1 parent 87dce3f commit 3cdee20
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 3 deletions.
1 change: 1 addition & 0 deletions pkg/sql/opt/bench/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ var queries = [...]benchQuery{
WHERE no_w_id = $1 AND no_d_id = $2
ORDER BY no_o_id ASC
LIMIT 1
FOR UPDATE
`,
args: []interface{}{10, 100},
},
Expand Down
8 changes: 8 additions & 0 deletions pkg/sql/opt/memo/testdata/stats_quality/tpcc
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,14 @@ SELECT s_quantity, s_ytd, s_order_cnt, s_remote_cnt, s_data, s_dist_05
FROM stock
WHERE (s_i_id, s_w_id) IN ((1000, 4), (900, 4), (1100, 4), (1500, 4), (1400, 4))
ORDER BY s_i_id
FOR UPDATE
----
----
project
├── save-table-name: new_order_04_project_1
├── columns: s_quantity:3(int) s_ytd:14(int) s_order_cnt:15(int) s_remote_cnt:16(int) s_data:17(varchar) s_dist_05:8(char) [hidden: s_i_id:1(int!null)]
├── cardinality: [0 - 5]
├── volatile
├── stats: [rows=4.548552, distinct(1)=4.54855, null(1)=0, distinct(3)=4.43676, null(3)=0, distinct(8)=4.38572, null(8)=0, distinct(14)=0.989418, null(14)=0, distinct(15)=0.989418, null(15)=0, distinct(16)=0.989418, null(16)=0, distinct(17)=4.54833, null(17)=0]
├── key: (1)
├── fd: (1)-->(3,8,14-17)
Expand All @@ -165,7 +167,9 @@ project
│ ├── [/4/1100 - /4/1100]
│ ├── [/4/1400 - /4/1400]
│ └── [/4/1500 - /4/1500]
├── locking: for-update
├── cardinality: [0 - 5]
├── volatile
├── stats: [rows=4.548552, distinct(1)=4.54855, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=4.43676, null(3)=0, distinct(8)=4.38572, null(8)=0, distinct(14)=0.989418, null(14)=0, distinct(15)=0.989418, null(15)=0, distinct(16)=0.989418, null(16)=0, distinct(17)=4.54833, null(17)=0, distinct(1,2)=4.54855, null(1,2)=0]
│ histogram(1)= 0 0.966 0 0.966 0 0.966 0 0.82528 0 0.82528
│ <--- 900 --- 1000 --- 1100 --- 1400 ---- 1500 -
Expand Down Expand Up @@ -489,12 +493,14 @@ FROM new_order
WHERE no_w_id = 7 AND no_d_id = 6
ORDER BY no_o_id ASC
LIMIT 1
FOR UPDATE
----
----
project
├── save-table-name: delivery_01_project_1
├── columns: no_o_id:1(int!null)
├── cardinality: [0 - 1]
├── volatile
├── stats: [rows=1, distinct(1)=0.999675, null(1)=0]
├── key: ()
├── fd: ()-->(1)
Expand All @@ -503,6 +509,8 @@ project
├── columns: no_o_id:1(int!null) no_d_id:2(int!null) no_w_id:3(int!null)
├── constraint: /3/2/1: [/7/6 - /7/6]
├── limit: 1
├── locking: for-update
├── volatile
├── stats: [rows=1, distinct(1)=0.999675, null(1)=0, distinct(2)=0.632308, null(2)=0, distinct(3)=0.632308, null(3)=0]
├── key: ()
└── fd: ()-->(1-3)
Expand Down
8 changes: 8 additions & 0 deletions pkg/sql/opt/xform/testdata/external/tpcc
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,12 @@ SELECT s_quantity, s_ytd, s_order_cnt, s_remote_cnt, s_data, s_dist_05
FROM stock
WHERE (s_i_id, s_w_id) IN ((1000, 4), (900, 4), (1100, 4), (1500, 4), (1400, 4))
ORDER BY s_i_id
FOR UPDATE
----
project
├── columns: s_quantity:3 s_ytd:14 s_order_cnt:15 s_remote_cnt:16 s_data:17 s_dist_05:8 [hidden: s_i_id:1!null]
├── cardinality: [0 - 5]
├── volatile
├── key: (1)
├── fd: (1)-->(3,8,14-17)
├── ordering: +1
Expand All @@ -134,7 +136,9 @@ project
│ ├── [/4/1100 - /4/1100]
│ ├── [/4/1400 - /4/1400]
│ └── [/4/1500 - /4/1500]
├── locking: for-update
├── cardinality: [0 - 5]
├── volatile
├── key: (1)
├── fd: ()-->(2), (1)-->(3,8,14-17)
└── ordering: +1 opt(2) [actual: +1]
Expand Down Expand Up @@ -801,16 +805,20 @@ FROM new_order
WHERE no_w_id = 10 AND no_d_id = 100
ORDER BY no_o_id ASC
LIMIT 1
FOR UPDATE
----
project
├── columns: no_o_id:1!null
├── cardinality: [0 - 1]
├── volatile
├── key: ()
├── fd: ()-->(1)
└── scan new_order
├── columns: no_o_id:1!null no_d_id:2!null no_w_id:3!null
├── constraint: /3/2/1: [/10/100 - /10/100]
├── limit: 1
├── locking: for-update
├── volatile
├── key: ()
└── fd: ()-->(1-3)

Expand Down
4 changes: 4 additions & 0 deletions pkg/sql/opt/xform/testdata/external/tpcc-later-stats
Original file line number Diff line number Diff line change
Expand Up @@ -804,16 +804,20 @@ FROM new_order
WHERE no_w_id = 10 AND no_d_id = 100
ORDER BY no_o_id ASC
LIMIT 1
FOR UPDATE
----
project
├── columns: no_o_id:1!null
├── cardinality: [0 - 1]
├── volatile
├── key: ()
├── fd: ()-->(1)
└── scan new_order
├── columns: no_o_id:1!null no_d_id:2!null no_w_id:3!null
├── constraint: /3/2/1: [/10/100 - /10/100]
├── limit: 1
├── locking: for-update
├── volatile
├── key: ()
└── fd: ()-->(1-3)

Expand Down
8 changes: 8 additions & 0 deletions pkg/sql/opt/xform/testdata/external/tpcc-no-stats
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,12 @@ SELECT s_quantity, s_ytd, s_order_cnt, s_remote_cnt, s_data, s_dist_05
FROM stock
WHERE (s_i_id, s_w_id) IN ((1000, 4), (900, 4), (1100, 4), (1500, 4), (1400, 4))
ORDER BY s_i_id
FOR UPDATE
----
project
├── columns: s_quantity:3 s_ytd:14 s_order_cnt:15 s_remote_cnt:16 s_data:17 s_dist_05:8 [hidden: s_i_id:1!null]
├── cardinality: [0 - 5]
├── volatile
├── key: (1)
├── fd: (1)-->(3,8,14-17)
├── ordering: +1
Expand All @@ -131,7 +133,9 @@ project
│ ├── [/4/1100 - /4/1100]
│ ├── [/4/1400 - /4/1400]
│ └── [/4/1500 - /4/1500]
├── locking: for-update
├── cardinality: [0 - 5]
├── volatile
├── key: (1)
├── fd: ()-->(2), (1)-->(3,8,14-17)
└── ordering: +1 opt(2) [actual: +1]
Expand Down Expand Up @@ -802,16 +806,20 @@ FROM new_order
WHERE no_w_id = 10 AND no_d_id = 100
ORDER BY no_o_id ASC
LIMIT 1
FOR UPDATE
----
project
├── columns: no_o_id:1!null
├── cardinality: [0 - 1]
├── volatile
├── key: ()
├── fd: ()-->(1)
└── scan new_order
├── columns: no_o_id:1!null no_d_id:2!null no_w_id:3!null
├── constraint: /3/2/1: [/10/100 - /10/100]
├── limit: 1
├── locking: for-update
├── volatile
├── key: ()
└── fd: ()-->(1-3)

Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/parser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ func BenchmarkParse(b *testing.B) {
},
{
"tpcc-delivery",
`SELECT no_o_id FROM new_order WHERE no_w_id = $1 AND no_d_id = $2 ORDER BY no_o_id ASC LIMIT 1`,
`SELECT no_o_id FROM new_order WHERE no_w_id = $1 AND no_d_id = $2 ORDER BY no_o_id ASC LIMIT 1 FOR UPDATE`,
},
{
"account",
Expand Down
3 changes: 2 additions & 1 deletion pkg/workload/tpcc/delivery.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ func createDelivery(
FROM new_order
WHERE no_w_id = $1 AND no_d_id = $2
ORDER BY no_o_id ASC
LIMIT 1`,
LIMIT 1
FOR UPDATE`,
)

del.sumAmount = del.sr.Define(`
Expand Down
3 changes: 2 additions & 1 deletion pkg/workload/tpcc/new_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ func (n *newOrder) run(ctx context.Context, wID int) (interface{}, error) {
SELECT s_quantity, s_ytd, s_order_cnt, s_remote_cnt, s_data, s_dist_%02[1]d
FROM stock
WHERE (s_i_id, s_w_id) IN (%[2]s)
ORDER BY s_i_id`,
ORDER BY s_i_id
FOR UPDATE`,
d.dID, strings.Join(stockIDs, ", "),
),
)
Expand Down

0 comments on commit 3cdee20

Please sign in to comment.