fix(backup): stop locked databases from hanging updates - #84826
Open
fangliquanflq wants to merge 2 commits into
Open
fangliquanflq wants to merge 2 commits into
fangliquanflq wants to merge 2 commits into
Conversation
Duplicate of #68868: both bound SQLite snapshot stalls through a progress callback and no-progress deadline while preserving fail-closed WAL-safe backups. |
Contributor
fix(backup): stop locked databases from hanging updates
|
Contributor
Author
|
Thanks for the detailed review. I checked each point against the PR diff, tests, and the version that was salvaged to
No further branch change is needed for these points. |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
hermes update --backupnow stops waiting after a bounded interval when a database underHERMES_HOMEremains locked, instead of hanging indefinitely before the update begins. The backup still uses SQLite's snapshot API for WAL consistency, fails closed for the locked file, removes the partial destination, and lets the existing backup failure handling continue safely.Symptom
When another process holds a persistent write lock on any
*.dbunderHERMES_HOME, the update remains atCreating pre-update backup...with no further output or progress. The reported case required SIGKILL after more than 15 minutes.Impact
Affected users cannot complete
hermes update --backupwhile a database remains locked. Their only available workaround is to disable the pre-update backup, which removes the safety snapshot for the update.Bug Cause
Trigger:
hermes_cli/backup.py:346/_safe_copy_db()whensqlite3.Connection.backup()receives repeatedSQLITE_BUSYorSQLITE_LOCKEDresults.Causal chain:
hermes update --backupincludes a live SQLite database underHERMES_HOMEin the pre-update archive._safe_copy_db()callsConnection.backup()without a deadline, so CPython keeps sleeping and retrying while another process retains the lock.Why it is wrong: The backup path promises to fail closed when it cannot create a consistent snapshot, but an unbounded internal retry prevents it from returning a failure.
Working sibling / contrast: An unlocked database completes through the same SQLite snapshot path and preserves committed WAL data.
--no-backupalso avoids the blocked path, confirming that update execution itself is not the source of the hang.Ruled out: Falling back to copying only the main database file is not safe because it can omit committed WAL data. The fix therefore retains
sqlite3.backup()and bounds only continuous busy or locked periods.Fix
Use incremental SQLite backup progress callbacks with a 10-second continuous-busy deadline and a zero connection busy timeout. Reset the deadline after successful progress, close the destination before cleanup for Windows compatibility, and remove any partial snapshot on failure.
Related Issue
Fixes #84790
Type of Change
Changes Made
hermes_cli/backup.py- bound continuous locked-source waits while preserving WAL-consistent snapshot behavior and fail-closed cleanup.tests/hermes_cli/test_backup.py- cover the timeout, connection configuration, close-before-delete behavior, and normal database copying.How to Test
_safe_copy_db()for that database; verify it returnsFalseafter the bounded wait and leaves no destination file.Result: 3 passed. Real-environment verification also reproduced the prior locked-backup hang and confirmed that the final default deadline returns in approximately 10 seconds with cleanup.
Checklist
Code
fix(scope):,feat(scope):, etc.)Documentation & Housekeeping
cli-config.yaml.exampleupdate: N/A - no configuration keys changedCONTRIBUTING.mdorAGENTS.mdupdate: N/A - no architecture or workflow changedScreenshots / Logs
Not applicable. The focused test result and real-environment timing are documented above.