Skip to content

Commit

Permalink
Fix the problem that statement being oom-killed within DoneAggressive…
Browse files Browse the repository at this point in the history
…Locking causing the transaction still in aggressive locking state (tikv#1355) (tikv#1487)

 

Co-authored-by: MyonKeminta <[email protected]>
  • Loading branch information
MyonKeminta and MyonKeminta authored Nov 8, 2024
1 parent f01fc67 commit 4aab367
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions txnkv/transaction/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,18 @@ func (txn *KVTxn) CancelAggressiveLocking(ctx context.Context) {
if txn.aggressiveLockingContext == nil {
panic("Trying to cancel aggressive locking while it's not started")
}

// Unset `aggressiveLockingContext` in a defer block to ensure it must be executed even it panicked on the half way.
// It's because that if it's panicked by an OOM-kill of TiDB, it can then be recovered and the user can still
// continue using the transaction's state.
// The usage of `defer` can be removed once we have other way to avoid the panicking.
// See: https://github.com/pingcap/tidb/issues/53540#issuecomment-2138089140
// Currently the problem only exists in `DoneAggressiveLocking`, but we do the same to `CancelAggressiveLocking`
// to the two function consistent, and prevent for new panics that might be introduced in the future.
defer func() {
txn.aggressiveLockingContext = nil
}()

txn.cleanupAggressiveLockingRedundantLocks(context.Background())
if txn.aggressiveLockingContext.assignedPrimaryKey {
txn.resetPrimary()
Expand All @@ -754,7 +766,6 @@ func (txn *KVTxn) CancelAggressiveLocking(ctx context.Context) {
txn.asyncPessimisticRollback(context.Background(), keys, forUpdateTS)
txn.lockedCnt -= len(keys)
}
txn.aggressiveLockingContext = nil
}

// DoneAggressiveLocking finishes the current aggressive locking. The locked keys will be moved to the membuffer as if
Expand All @@ -763,6 +774,16 @@ func (txn *KVTxn) DoneAggressiveLocking(ctx context.Context) {
if txn.aggressiveLockingContext == nil {
panic("Trying to finish aggressive locking while it's not started")
}

// Unset `aggressiveLockingContext` in a defer block to ensure it must be executed even it panicked on the half way.
// It's because that if it's panicked by an OOM-kill of TiDB, it can then be recovered and the user can still
// continue using the transaction's state.
// The usage of `defer` can be removed once we have other way to avoid the panicking.
// See: https://github.com/pingcap/tidb/issues/53540#issuecomment-2138089140
defer func() {
txn.aggressiveLockingContext = nil
}()

txn.cleanupAggressiveLockingRedundantLocks(context.Background())

if txn.forUpdateTSChecks == nil {
Expand All @@ -787,7 +808,6 @@ func (txn *KVTxn) DoneAggressiveLocking(ctx context.Context) {
txn.committer.maxLockedWithConflictTS = txn.aggressiveLockingContext.maxLockedWithConflictTS
}
}
txn.aggressiveLockingContext = nil
}

// IsInAggressiveLockingMode checks if the transaction is currently in aggressive locking mode.
Expand Down

0 comments on commit 4aab367

Please sign in to comment.