fix(spider-storage::db): Avoid locking secondary indexes when scanning rows for deletion (fixes #371). - #373
Conversation
WalkthroughThis PR changes MariaDB job-expiry cleanup and dead execution-manager detection to use unlocked candidate selection followed by later confirmation or deletion, and adds concurrency test coverage for the liveness path. ChangesTwo-phase select-confirm-act query rework
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant delete_expired_terminated_jobs
participant run_read_committed_tx
participant get_dead_execution_managers
participant Database
delete_expired_terminated_jobs->>Database: SELECT expired terminated job IDs (no lock)
Database-->>delete_expired_terminated_jobs: candidate IDs
delete_expired_terminated_jobs->>Database: DELETE ... WHERE id IN (...) AND state IN (...)
Database-->>delete_expired_terminated_jobs: rows_affected
get_dead_execution_managers->>run_read_committed_tx: run helper in READ COMMITTED tx
run_read_committed_tx->>Database: set transaction isolation
get_dead_execution_managers->>Database: SELECT stale Alive manager IDs (no lock)
Database-->>get_dead_execution_managers: candidate IDs
get_dead_execution_managers->>Database: SELECT ... FOR UPDATE on chunks
Database-->>get_dead_execution_managers: confirmed IDs
get_dead_execution_managers->>Database: UPDATE confirmed rows to Dead
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/spider-storage/src/db/mariadb.rs`:
- Around line 359-407: The batch deletion loop can livelock in the MariaDB
cleanup path because the non-locking candidate scan can keep returning the same
full batch while `confirmed_ids` stays empty under the default transaction
isolation. Fix the logic in this deletion routine by breaking the loop when
`confirmed_ids` is empty, or by restructuring the `SELECT_CANDIDATES_QUERY` scan
so it runs outside the long-lived transaction and only the confirm/delete work
stays in a short transaction. Keep the existing `select_for_update_query`,
`confirmed_ids`, and `DELETE_BATCH_SIZE` flow, but ensure a full batch with no
confirmations cannot spin forever.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: dcad76fc-e8eb-47a6-a976-0517355b4dcd
📒 Files selected for processing (1)
components/spider-storage/src/db/mariadb.rs
LinZhihao-723
left a comment
There was a problem hiding this comment.
Committed small variable renaming changes.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
components/spider-storage/src/db/mariadb.rs (1)
357-399: 🚀 Performance & Scalability | 🔵 TrivialConsider committing per batch instead of one transaction spanning all batches.
The whole batched loop runs inside a single transaction (
beginat Line 357,commitat Line 401). EveryDELETEtakes row locks that are held until the final commit, so a large cleanup accumulates locks on all deleted rows across all batches — which works against this PR's goal of reducing lock contention. Committing (and re-beginning) per batch would bound lock duration and also refresh the read snapshot each iteration. This is optional and depends on your durability/atomicity expectations for the cleanup.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/spider-storage/src/db/mariadb.rs` around lines 357 - 399, The batched cleanup in the MariaDB delete flow currently holds a single transaction open across all batches, so row locks from each DELETE remain until the final commit. Update the transaction handling in the job-deletion logic around the loop in the MariaDB storage method to commit each batch separately and start a new transaction for the next batch, while preserving the existing candidate selection, delete verification, and deleted_job_ids accumulation behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@components/spider-storage/src/db/mariadb.rs`:
- Around line 357-399: The batched cleanup in the MariaDB delete flow currently
holds a single transaction open across all batches, so row locks from each
DELETE remain until the final commit. Update the transaction handling in the
job-deletion logic around the loop in the MariaDB storage method to commit each
batch separately and start a new transaction for the next batch, while
preserving the existing candidate selection, delete verification, and
deleted_job_ids accumulation behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: c7a7e5a1-3134-45ed-bc93-0a5610639051
📒 Files selected for processing (1)
components/spider-storage/src/db/mariadb.rs
LinZhihao-723
left a comment
There was a problem hiding this comment.
Directly modified the PR title.
- Since the scope of
spider-storageis getting too large now, let's specify which component we touch using the namespace convention (in this case,spider-storage::db).
Description
This PR fixes #371.
This PR avoid deadlock in
delete__expired_terminated_jobsandget_dead_execution_managersby:delete_expired_terminated_jobsdoesn't need to recheck the state according to the program invariants (job in terminated state remains in the state & time only moves forward in db), but we still recheck the state just in case.Checklist
breaking change.
Validation performed
Summary by CodeRabbit
Summary by CodeRabbit