Skip to content

sequences: advance them alone, by a million, and check there is room - #2

Merged
tbarbugli merged 1 commit into
mainfrom
sequences-headroom
Aug 12, 2026
Merged

sequences: advance them alone, by a million, and check there is room#2
tbarbugli merged 1 commit into
mainfrom
sequences-headroom

Conversation

@tbarbugli

Copy link
Copy Markdown
Member

Summary

  • pgmigrate sequences runs the cutover's sequence step on its own, from follow onwards, for a migration that moves traffic before it moves the database. Values are set absolutely, so rerunning it and the cutover after it are both harmless.
  • --sequence-offset defaults to 1,000,000 rather than 1,000. That gap is the only thing between what the source allocates while it is still serving and a key the target has already handed out. The zero fallback inside cutover.Run is gone, so the flag is the only default and --sequence-offset 0 means no gap.
  • Preflight reports sequences short of room: an error when less is left than --sequence-offset, because setval refuses a value past the bound and the cutover would fail at its sequence step, and a warning under 10,000,000 values. Only the sequences the cutover will set are considered, meaning those a selected table owns or draws a column default from.

Test plan

  • gofmt -l ., go vet ./..., go test ./...
  • go test -tags integration ./internal/preflight/ including the new TestPG17SequenceHeadroom, which checks that the error blocks, the warning is acknowledgeable, the recommended ALTER SEQUENCE ... MAXVALUE clears the error, and unselected sequences stay unreported
  • go test -tags integration ./internal/cutover/, with the descending fixture widened so a million-value bump stays in bounds
  • make e2e: data-correctness=ok, migration-e2e=ok, and the report records sequence_offset: 1000000 with order_id_seq set from 1149 to 1001149

Made with Cursor

The cutover's sequence step is now a command of its own, for a migration that
moves traffic before it moves the database. It reads each selected sequence's
next value on the source and sets the target's copy that far past it. Values are
set absolutely rather than advanced, so running it again is harmless and the
cutover redoes it against the source's final values.

The gap it leaves is a million rather than a thousand. That gap is the only thing
between what the source allocates while it is still serving and a key the target
has already handed out, and a thousand of them is a few seconds of a busy table.

A gap that size makes a sequence running out of room a real failure mode, so
preflight reports one now. Less room left than --sequence-offset is an error:
setval refuses a value past the bound, so the cutover would fail at its sequence
step no matter how willing the operator is. Under ten million values left is a
warning, because how much is enough depends on how fast the application allocates
and how long the source keeps serving, which only the operator knows. Only the
sequences the cutover will set are considered, and the headroom arithmetic is
unsigned: sequence bounds span the whole of int64, and subtracting two of them as
signed values overflows and reports a sequence with room to spare as exhausted.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tbarbugli
tbarbugli merged commit 0bb8ed4 into main Aug 12, 2026
1 check passed
@tbarbugli
tbarbugli deleted the sequences-headroom branch August 12, 2026 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant