forked from cockroachdb/cockroach
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
concurrency,kvserver: limited scans do optimistic latching
Latches for the full spans get inserted up front in the spanlatch.Manager, and the conflict checking happens after evaluation, only over the spans that were actually read. If there is a conflict, the existing inserted latches are waited on, and execution switches to pessimistic latching and locking. The existing cluster setting for optimistic locking is used to gate this behavior. Fixes cockroachdb#9521 Release note (performance improvement): A limited scan now checks for conflicting latches in an optimistic manner, which means it will not conflict with latches that were held in the scan's full spans, but were not in the spans that were scanned until the limit was reached. This behavior can be turned off (along with optimistic locking) by changing the value of the cluster setting kv.concurrency.optimistic_eval_limited_scans.enabled to false.
- Loading branch information
1 parent
6c2e732
commit 8369922
Showing
10 changed files
with
444 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,7 @@ new-request name=req2 txn=txn2 ts=12,1 | |
sequence req=req2 eval-kind=opt | ||
---- | ||
[2] sequence req2: optimistically sequencing request | ||
[2] sequence req2: acquiring latches | ||
[2] sequence req2: optimistically acquiring latches | ||
[2] sequence req2: optimistically scanning lock table for conflicting locks | ||
[2] sequence req2: sequencing complete, returned guard | ||
|
||
|
@@ -56,33 +56,135 @@ check-opt-no-conflicts req=req2 | |
---- | ||
no-conflicts: true | ||
|
||
# Wider span has a conflict. | ||
check-opt-no-conflicts req=req2 | ||
finish req=req2 | ||
---- | ||
[-] finish req2: finishing request | ||
|
||
new-request name=req3 txn=txn2 ts=12,1 | ||
scan key=a endkey=e | ||
---- | ||
|
||
# Optimistic locking for req3 | ||
sequence req=req3 eval-kind=opt | ||
---- | ||
[3] sequence req3: optimistically sequencing request | ||
[3] sequence req3: optimistically acquiring latches | ||
[3] sequence req3: optimistically scanning lock table for conflicting locks | ||
[3] sequence req3: sequencing complete, returned guard | ||
|
||
debug-lock-table | ||
---- | ||
global: num=1 | ||
lock: "d" | ||
holder: txn: 00000001-0000-0000-0000-000000000000, ts: 10.000000000,1, info: unrepl epoch: 0, seqs: [0] | ||
local: num=0 | ||
|
||
# Wider span for req3 has a conflict. | ||
check-opt-no-conflicts req=req3 | ||
scan key=a endkey=e | ||
---- | ||
no-conflicts: false | ||
|
||
# Sequence again -- latches are already held. | ||
sequence req=req2 eval-kind=pess-after-opt | ||
sequence req=req3 eval-kind=pess-after-opt | ||
---- | ||
[3] sequence req2: re-sequencing request after optimistic sequencing failed | ||
[3] sequence req2: scanning lock table for conflicting locks | ||
[3] sequence req2: waiting in lock wait-queues | ||
[3] sequence req2: lock wait-queue event: wait for (distinguished) txn 00000001 holding lock @ key "d" (queuedWriters: 0, queuedReaders: 1) | ||
[3] sequence req2: pushing timestamp of txn 00000001 above 12.000000000,1 | ||
[3] sequence req2: blocked on select in concurrency_test.(*cluster).PushTransaction | ||
[4] sequence req3: re-sequencing request after optimistic sequencing failed | ||
[4] sequence req3: optimistic failed, so waiting for latches | ||
[4] sequence req3: scanning lock table for conflicting locks | ||
[4] sequence req3: waiting in lock wait-queues | ||
[4] sequence req3: lock wait-queue event: wait for (distinguished) txn 00000001 holding lock @ key "d" (queuedWriters: 0, queuedReaders: 1) | ||
[4] sequence req3: pushing timestamp of txn 00000001 above 12.000000000,1 | ||
[4] sequence req3: blocked on select in concurrency_test.(*cluster).PushTransaction | ||
|
||
# Conflicting transaction commits. | ||
on-txn-updated txn=txn1 status=committed | ||
---- | ||
[-] update txn: committing txn1 | ||
[3] sequence req2: resolving intent "d" for txn 00000001 with COMMITTED status | ||
[3] sequence req2: lock wait-queue event: done waiting | ||
[3] sequence req2: conflicted with 00000001-0000-0000-0000-000000000000 on "d" for 1.234s | ||
[3] sequence req2: acquiring latches | ||
[3] sequence req2: scanning lock table for conflicting locks | ||
[3] sequence req2: sequencing complete, returned guard | ||
[4] sequence req3: resolving intent "d" for txn 00000001 with COMMITTED status | ||
[4] sequence req3: lock wait-queue event: done waiting | ||
[4] sequence req3: conflicted with 00000001-0000-0000-0000-000000000000 on "d" for 1.234s | ||
[4] sequence req3: acquiring latches | ||
[4] sequence req3: scanning lock table for conflicting locks | ||
[4] sequence req3: sequencing complete, returned guard | ||
|
||
finish req=req2 | ||
|
||
finish req=req3 | ||
---- | ||
[-] finish req2: finishing request | ||
[-] finish req3: finishing request | ||
|
||
# Another transaction that writes, which will hold latches but not locks. | ||
new-txn name=txn3 ts=10,1 epoch=0 | ||
---- | ||
|
||
new-request name=req4 txn=txn3 ts=10,1 | ||
put key=d value=d | ||
---- | ||
|
||
sequence req=req4 | ||
---- | ||
[5] sequence req4: sequencing request | ||
[5] sequence req4: acquiring latches | ||
[5] sequence req4: scanning lock table for conflicting locks | ||
[5] sequence req4: sequencing complete, returned guard | ||
|
||
debug-lock-table | ||
---- | ||
global: num=0 | ||
local: num=0 | ||
|
||
new-request name=req5 txn=txn2 ts=12,1 | ||
scan key=a endkey=e | ||
---- | ||
|
||
sequence req=req5 eval-kind=opt | ||
---- | ||
[6] sequence req5: optimistically sequencing request | ||
[6] sequence req5: optimistically acquiring latches | ||
[6] sequence req5: optimistically scanning lock table for conflicting locks | ||
[6] sequence req5: sequencing complete, returned guard | ||
|
||
# When checking with a span that does not include the existing latch, there is | ||
# no conflict. | ||
check-opt-no-conflicts req=req5 | ||
scan key=a endkey=c | ||
---- | ||
no-conflicts: true | ||
|
||
finish req=req5 | ||
---- | ||
[-] finish req5: finishing request | ||
|
||
new-request name=req6 txn=txn2 ts=12,1 | ||
scan key=a endkey=e | ||
---- | ||
|
||
sequence req=req6 eval-kind=opt | ||
---- | ||
[7] sequence req6: optimistically sequencing request | ||
[7] sequence req6: optimistically acquiring latches | ||
[7] sequence req6: optimistically scanning lock table for conflicting locks | ||
[7] sequence req6: sequencing complete, returned guard | ||
|
||
# Wider span for req6 has a conflict with the latch held by req4. | ||
check-opt-no-conflicts req=req6 | ||
scan key=a endkey=e | ||
---- | ||
no-conflicts: false | ||
|
||
sequence req=req6 eval-kind=pess-after-opt | ||
---- | ||
[8] sequence req6: re-sequencing request after optimistic sequencing failed | ||
[8] sequence req6: optimistic failed, so waiting for latches | ||
[8] sequence req6: waiting to acquire read latch {a-e}@12.000000000,1, held by write latch [email protected],1 | ||
[8] sequence req6: blocked on select in spanlatch.(*Manager).waitForSignal | ||
|
||
# req4 finishing releases the latch and allows req6 to proceed. | ||
finish req=req4 | ||
---- | ||
[-] finish req4: finishing request | ||
[8] sequence req6: scanning lock table for conflicting locks | ||
[8] sequence req6: sequencing complete, returned guard | ||
|
||
finish req=req6 | ||
---- | ||
[-] finish req6: finishing request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.