Fix self-deadlock when acquiring a shared SyncObject latch - #9120
Fix self-deadlock when acquiring a shared SyncObject latch#9120MochalovAlexey wants to merge 1 commit into
Conversation
Detect attempts to acquire SYNC_SHARED when the current thread already owns SYNC_EXCLUSIVE and unwind page-cache latches when propagating the resulting exception from VIO operations.
No memory dump or stack trace ? What Firebird version is affected ?
What about other usages of SyncObject ? Other usages of bdb_sync ? Excuse me, but it looks like desperate attempt to workaround bug instead of properly fix it. |
|
The original hang was observed in a customer environment running our fork of Firebird 3. However, the underlying problem is also present in upstream Firebird 3 and can be reproduced artificially with the debugger. I have attached both the reproducer deadlock.patch and the resulting syncobject_deadlock.txt. To reproduce it, set a breakpoint at: I did not create a PR for upstream Firebird 3 because that version is no longer supported.I was unable to reproduce this issue in Firebird 5 or later versions, but after analyzing the code, I concluded that a similar situation is possible. The concrete incident (on FB3 fork) was a self-deadlock during rollback/savepoint cleanup after an I/O error. This was not a lock-manager deadlock: the thread was waiting on a page-cache SyncObject. The exception is then caught by EXE_looper(): During cleanup, the same thread attempts to read the same pointer page: The root cause is that There is no equivalent handling for a Regarding other uses of SyncObject: the deadlock detection itself is generic, but the latch-unwinding part of the proposed change is specific to page-cache BDBs tracked in tdbb_bdbs. The dedicated SyncObject error is primarily intended to prevent an undiagnosable infinite wait and expose an error. |
It is not clear why
It is much better is to handle this case at |
This fixes a possible engine hang when the current thread tries to acquire
a SYNC_SHARED latch on a SyncObject that it already owns exclusively.
The hang was observed several times in a customer environment, but so far
it has not been possible to reproduce it manually with an unmodified build.
The problematic lock sequence was reproduced only by temporarily modifying
the code and running it in a debugger.
Instead of waiting on itself, SyncObject now detects this condition and
raises a dedicated error. Page-cache latches are unwound when the exception
propagates through VIO record operations, backout and savepoint cleanup.
The fix was originally implemented for the 3v and has been adapted
to the Firebird 5.