Skip to content

fix(masking): a key rotation's swap takes the view first, as a masked read does - #230

Merged
SauravYadav12 merged 2 commits into
mainfrom
fix/mask-rotate-deadlock
Nov 11, 2026
Merged

SauravYadav12 merged 2 commits into
mainfrom
fix/mask-rotate-deadlock

Conversation

@SauravYadav12

Copy link
Copy Markdown
Collaborator

Fixes a deadlock between fox mask key rotate and a masked account reading during the rotation. It was seen once in the integration suite: the masked reader got 4 deadlock detected errors.

Cause

Each rotated table ends with a swap transaction, rekeyTable's Swap. The swap paused writes on the base table, renamed the old shadow table and then the new one (an exclusive lock on the shadow), and replaced the masked view last (an exclusive lock on the view). A masked read locks the view first, then the base table and the shadow.

A read arriving between the swap's renames and its view replacement held the view and waited for the shadow, while the swap held the shadow and waited for the view. Postgres ended one of them.

Fix

The swap now replaces the view first, pointed at the new shadow under its __next name, and does the renames after. That is the order a read takes its locks in. A view holds its tables by OID, so it keeps reading the new shadow once it's renamed into place. A read arriving mid-swap now waits briefly and reads the new masks.

Tests

  • Reproduced on PostgreSQL 18 with the swap paused at that point and a read arriving during the pause:
    • The old order deadlocked.
    • The new order didn't, and the read returned every row.
    • The view then reads the new shadow under its own name.
  • integration 936/936 and integration-f5 57/57.
  • Go unit tests in both editions. The existing test required the old order; it now checks that the view is replaced first and reads the new shadow.
  • vet for macOS, Linux and Windows.

@vercel

vercel Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
foxbyte-get Ready Ready Preview Nov 11, 2026 5:35pm UTC

… read does

It renamed the shadow, then replaced the view, while a masked read locks
the view, then the shadow: a read arriving between the two deadlocked with
it. The view is now replaced first, reading the new shadow by oid.
@SauravYadav12
SauravYadav12 force-pushed the fix/mask-rotate-deadlock branch from cb8585b to 1a14abd Compare November 11, 2026 17:35
@SauravYadav12
SauravYadav12 merged commit 91f3fa0 into main Nov 11, 2026
8 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant