Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions ddl/migrations/0201_backfill_missing_reward_disbursements.sql
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,33 @@
-- account. Rows whose user record no longer exists are intentionally skipped;
-- they would need on-chain signature replay (via program.Indexer) to recover.

-- CREATE INDEX CONCURRENTLY cannot run inside an explicit transaction, so
-- these statements stay outside the BEGIN/COMMIT below. psql executes each in
-- its own implicit transaction. Both indexes pay off well beyond this
-- migration: the first lets the dedup LEFT JOIN on (challenge_id, specifier)
-- use an index instead of a sequential scan; the second lets the live
-- reward_manager indexer (and this migration's LATERAL lookup) resolve a
-- user's current claimable account in O(log n) rather than scanning the table.
BEGIN;

-- Build both indexes inside the migration transaction (non-CONCURRENTLY) so
-- the writes are atomic with the backfill and not subject to virtualxid waits
-- against concurrent transactions on this DB (notably the legacy Python
-- index_rewards_manager Celery task on discovery-provider, which keeps long
-- challenge_disbursements transactions open and can make CONCURRENTLY hang
-- indefinitely). Regular CREATE INDEX takes a ShareLock on the target table:
-- writes are blocked for the duration of the build, but both target tables
-- have light write load (reward_manager EvaluateAttestations and claimable
-- token creations are sparse on-chain) and the build itself completes in
-- seconds at current row counts.
--
-- Both indexes pay off well beyond this migration: the first lets the dedup
-- LEFT JOIN on (challenge_id, specifier) use an index instead of a sequential
-- scan; the second lets the live reward_manager indexer (and the CTE below)
-- resolve a user's current claimable account in O(log n) rather than scanning
-- the table.

CREATE INDEX CONCURRENTLY IF NOT EXISTS
CREATE INDEX IF NOT EXISTS
sol_reward_disbursements_challenge_specifier_idx
ON sol_reward_disbursements (challenge_id, specifier);

CREATE INDEX CONCURRENTLY IF NOT EXISTS
CREATE INDEX IF NOT EXISTS
sol_claimable_accounts_eth_mint_slot_idx
ON sol_claimable_accounts (ethereum_address, mint, slot DESC);

BEGIN;

-- Skip the on_sol_reward_disbursement trigger for this transaction. The
-- trigger fires per-row to create challenge_reward notifications and a
-- pg_notify announcement for the Python ChallengeEventBus. For a one-shot
Expand Down
Loading