Repository navigation
perf: order the expired-lease index like the fetch - #240
Merged
Merged
Conversation
Replace <table>_lease_idx (queue, acquired_at) with <table>_leased_idx (queue, next_attempt_at, id) WHERE acquired_token IS NOT NULL, so the fetch's expired-lease branch stops after `limit` rows instead of sorting every expired lease on the queue. validate_schema() reports a table without the new index and points at the upgrade section. Closes #220
Benchmark gate✅ gate passed
Gated (fails the build): |
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.
Closes #220. Ships in 0.17.0 because it changes the schema; the release is separate.
Why
The fetch's expired-lease branch orders by
(next_attempt_at, id), but the only index over leased rows was<table>_lease_idx (queue, acquired_at). So each fetch read and sorted every expired lease on the queue, and fetch time grew with the number of hung handlers. ADR 0003 left this open until it was measured; the triage on #220 measured it.The change
<table>_leased_idx (queue, next_attempt_at, id) WHERE acquired_token IS NOT NULLreplaces<table>_lease_idx. The expired check (acquired_atolder than the TTL) becomes a filter on an ordered scan that stops afterlimitrows. The fetch SQL is unchanged._leased_idxis 11 characters, shorter than_pending_idxand_timer_id_uq, so the longest accepted table name stays 51 bytes. The length guard now lists the new suffix in place of the old one.validate_schema():_leased_idxis missing, the error message also links to the new upgrade section, the same way the 0.15_pending_idxhint works.Measured
1M ready rows, 50k expired leases spread at random over the backlog, 2k in-flight leases at the head of the queue. Each fetch claims 100 rows inside a transaction that's rolled back. Median of 20 fetches, with the plan from
EXPLAIN (ANALYZE, FORMAT JSON)of the real statement:(queue, acquired_at)_leased_idx_leased_idxreading 100 rows, no Sort_leased_idxreading 100 rows, no SortThe triage table on #220 has more cases (0 to 50k expired, and 20k in flight), and the new index stays at about 1.4 to 1.5 ms across them.
Tests
test_fetch_reads_only_the_rows_it_claims_from_expired_leasesis an invariant test: on 20k rows with 5k expired leases, the fetch reads at most twicelimitrows from the table. With the old index columns it read 4,997. It shares a new_explain_fetchhelper with the existing backlog test, which was extracted from that test unchanged.test_validate_schema_reports_the_pre_0_17_lease_index: a table with the old index and without the new one fails validation with the upgrade link.test_validate_schema_checks_the_leased_index_predicate: a non-partial index, or one with the wrong predicate, is reported.Docs
CONCURRENTLYand a downgrade. If a 0.16 health probe runsvalidate_schema(), it reportsoutbox_lease_idxmissing once the old index is dropped, so the section says to move the drop into a second migration that runs after 0.17 is deployed. The autogenerate output and the index table show the new index.\d outboxlisting shows the new index. It also fixes the staleoutbox_pending_idxline, which was missingidsince 0.15.Verification
postgres:13.ruffandtyare clean, andmkdocs build --strictpasses.just bench-checkpasses and no gated counter moved.