Fix the problem that statement being oom-killed within DoneAggressiveLocking causing the transaction still in aggressive locking state (#1355)

* Quick fix the problem that statement being oom-killed within DoneAggressiveLocking causing the transaction still in aggressive locking state

Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>

* Add comments to explain the change

Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>

---------

Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
Co-authored-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
This commit is contained in:
MyonKeminta 2024-05-30 16:20:09 +08:00 committed by GitHub
parent 0cc1c5239d
commit a6335a5aaf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 2 deletions

View File

@ -957,6 +957,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()
@ -976,7 +988,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
@ -985,6 +996,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 {
@ -1009,7 +1030,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.