Skip to content

Commit 4fa64e3

Browse files
committed
discuss normal locks
Signed-off-by: ekexium <[email protected]>
1 parent 93f799e commit 4fa64e3

File tree

1 file changed

+70
-7
lines changed

1 file changed

+70
-7
lines changed

text/0114-resolved-ts-for-large-transactions.md

+70-7
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ In current TiKV(v8.3), large transactions can block resolve-ts from advancing, b
1414

1515
## Goals
1616

17-
Do not let **large pipelined transactions** block the advance of resolved-ts.
17+
In current phase, our primary goal is to not let **large pipelined transactions** block the advance of resolved-ts. We focus on large pipelined transactions here. It could be adapted for general "large" transactions.
1818

19-
We focus on large pipelined transactions here. It could be adapted for general "large" transactions.
19+
Our ultimate goal is to achieve an unblocked resolved-ts progression. Besides long transactions and their locks, there are other factors that can block the advance of resolved-ts. We will discuss it in the last part of the proposal.
2020

2121
## Assumptions
2222

@@ -28,11 +28,11 @@ This constraint is not a strict limit, but rather serves to manage resource util
2828

2929
The key idea is using `lock.min_commit_ts` to calculate resolved-ts instead of `lock.start_ts`.
3030

31-
A resolved-ts guarantees that all historical events prior to this timestamp are finalized and observable. 'Historical events' in this context refer specifically to write records and rollback records, but explicitly exclude locks. It's important to note that the absence of locks with earlier timestamps is not a requirement for a valid resolved-ts, as long as the status of their corresponding transactions is definitively determined.
31+
A resolved timestamp (resolved-ts) ensures that all historical events before this point are finalized and observable. In this context, 'historical events' specifically mean write and rollback records, excluding locks in the LOCK CF. Importantly, a valid resolved-ts doesn't require the absence of earlier locks, as long as their transactions' status is determined.
3232

3333
### Maintanence of resolved-ts
3434

35-
Key objective: Maximize TiKV nodes' awareness of large pipelined transactions, including:
35+
Key objective: Maximize all TiKV nodes' awareness of large pipelined transactions during their lifetime, i.e. from their first writes to all locks being committed. These info are necessary:
3636

3737
1. start_ts
3838
2. Recent min_commit_ts
@@ -44,6 +44,12 @@ For a large pipelined transaction, its TTL manager is responsible for fetching a
4444

4545
Atomic variables or locks may be needed for synchronization between the TTL manager and the committer.
4646

47+
#### Scaling out TiKVs
48+
49+
When a new TiKV instance is added to the cluster in the middle of a large transaction, its TTL manager must broadcast to it in time. TTL manager gets the list of stores from the region cache. If region cache is unaware of any newly up TiKV, TTL manager may miss it.
50+
51+
To mitigate this, we propose implementing an optional routine in the region cache to periodically fetch all stores.
52+
4753
#### TiKV scheduler - heartbeat
4854

4955
Besides updating TTL, it can also update min_commit_ts of the PK.
@@ -69,26 +75,36 @@ After the successfully commiting all secondary locks of a large transaction, the
6975

7076
Resolver tracks normal locks as usual, but handles locks belonging to large pipelined transactions in a different way. The locks can be identified via the "generation" field.
7177

72-
For a lock belonging to a large pipelined transaction, the resolve only tracks its start_ts. When calculating resolved-ts, the resolver first tries to map the start_ts to its min_commit_ts by querying the txn_status_cache. If not found in cache, fallback to calculate using start_ts.
78+
For locks in large pipelined transactions, the resolver only tracks the start_ts. When calculating resolved-ts, it first attempts to map start_ts to min_commit_ts via the txn_status_cache. To maintain semantics, resolved-ts must be at least min_commit_ts + 1. If the cache lookup fails, it falls back to using start_ts for calculation.
7379

7480
Upon observing a LOCK DELETION, the resolver ceases tracking the corresponding start_ts for large pipelined transactions. This is justified as lock deletion only occurs once a transaction's final state is determined.
7581

82+
### Benefits in resolving locks
83+
84+
Across all lock resolution scenarios—including normal reads, stale reads, flashbacks, and potentially write conflicts—a preliminary txn_status_cache lookup can significantly reduce unnecessary computational overhead introduced by large transactions.
85+
7686
### Compatibility
7787

78-
The key difference is that services can now observe locks. They need to handle the locks.
88+
The key difference is that services can now observe much more locks.
89+
90+
Note that the current implementation still allows encountering locks with timestamps smaller than the resolved timestamp. This proposal doesn't change this behavior, so we don't anticipate correctness issues with this change. The main challenges will be related to performance and availability.
7991

8092
#### Stale read
8193

8294
When it meets a lock, first query the txn_status_cache. When not found in the cache, fallback to leader read.
8395

8496
#### Flashback
8597

86-
*TBD*
98+
1. Compatilibity with CDC: Flashback will write a lock to block resolved-ts during its execution. It does not use pipelined transaction so this lock will be treated as a normal lock.
99+
100+
2. The current and previous (up to v8.3) implementations of Flashback in TiKV rely on an incorrect assumption about resolved-ts guarantees. This misconception can lead to critical issues, such as the potential violation of transaction atomicity, as documented in https://github.com/tikv/tikv/issues/17415.
87101

88102
#### EBS snapshot backups
89103

90104
*TBD*
91105

106+
It depends on Flashback.
107+
92108
#### CDC
93109

94110
Already well documented in [Large Transactions Don't Block Watermark](https://github.com/pingcap/tiflow/blob/master/docs/design/2024-01-22-ticdc-large-txn-not-block-wm.md). Briefly, a refactoring work is needed.
@@ -103,3 +119,50 @@ RPCs: each large transaction sends N more RPCs per second, where N is the number
103119

104120
CPU: the mechanism may consume more CPU, but should be ignorable.
105121

122+
123+
124+
## Possible future improvements
125+
126+
#### Tolerate lagging non-pipelined transactions
127+
128+
To get closer to our ultimate goal: minimize blocking of resolved-ts, we can further consider the case where resolved-ts being blocked by normal transaction locks. Typical causes could be:
129+
130+
- Memory locks from async commit and 1PC. Normal locks are region-partitioned can will not block resolved-ts of other regions. But concurrenty manager is a node-level instance. Memory locks can block every (leader) region in the same TiKV.
131+
- Slow transactions which take too much time committing their locks
132+
- Long-running transactions that may not be large.
133+
- Node failures
134+
135+
136+
137+
Resolved-ts must continuously progress. However, it can't advance autonomously while ignoring locks. Such advancement would require the commit PK operation to either complete before the resolved-ts reaches a certain point or fail. This guarantee is not feasible.
138+
139+
The left approach feasible to prevent resolved-ts blocked by normal transactions are actively pushing their min_commit_ts, similar to what is done to large transactions.
140+
141+
However, locks using async commit cannot be pushed.
142+
143+
To sum up, when a resolver meets a lock whose min_commit_ts still blocks its
144+
145+
- Check the cache
146+
- Found if T.min_commit_ts >= R_TS candidate -> skip the lock
147+
- Else, fallthrough
148+
149+
- 2PC locks, check_txn_status and try to push its min_commit_ts.
150+
- Committed -> return its commit_ts
151+
- Commit_ts > R_TS candidate -> skip the lock
152+
- Commit_ts < R_TS candidate -> block at commit_ts - 1.
153+
- Min commit ts pushed, or min_commit_ts > R_TS candidate -> skip the lock
154+
- Rolled back -> skip the lock
155+
- Else -> block at min_commit_ts - 1
156+
- Async commit locks -> check its status
157+
- Committed, same as 2PC locks
158+
- Rolled back -> skip the lock
159+
- Else if min_commit_ts > R_TS candidate -> skip the lock
160+
- Else -> block at min_commit_ts + 1
161+
162+
Locks belonging to the same transaction can be consolidated.
163+
164+
To mitigate uncontrollable overhead and metastability risks, we limit our check to K transactions per region with the lowest min_commit_ts values. This approach is necessary given the potentially substantial total number of transactions.
165+
166+
#### Reduce write-read conflicts
167+
168+
Read requests typically require a check_txn_status to advance the min_commit_ts. We propose allowing large transactions to set their min_commit_ts to a higher value, potentially exceeding the current TSO. These min_commit_ts values, stored in the txn_status_cache, would enable read requests encountering locks to bypass them via a cache lookup. Large transactions would cease this special min_commit_ts setting once ready for prewrite.

0 commit comments

Comments
 (0)