Skip to content

Return read errors with VStream schema guidance - #89

Merged
nickvanw merged 1 commit into
mainfrom
fix/vstream-schema-fail-fast
Jun 16, 2026
Merged

nickvanw merged 1 commit into
mainfrom
fix/vstream-schema-fail-fast

Conversation

@nickvanw

@nickvanw nickvanw commented Jun 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • return non-timeout read errors instead of logging a warning and reporting sync success
  • preserve the read-attempt start cursor when row/update serialization callbacks fail, so failed work does not advance state
  • detect Vitess/VStream schema incompatibility errors while building a table replication plan after schema changes
  • add a specific historical re-sync instruction and surface that schema case as gRPC FailedPrecondition
  • add a real PlanetScale integration regression for mid-table DDL requiring historical re-sync

Closes #77.
Supersedes #78 and #87.

Notes

This intentionally does not auto-reset state or perform a historical re-sync. If the VStream schema incompatibility condition is hit, continuing incremental replication cannot make progress safely and the user/operator should trigger a Fivetran historical re-sync. Generic non-timeout read errors now fail the sync as well, preserving the underlying error instead of silently dropping it.

Tests

  • env GOCACHE=/tmp/fivetran-go-build-cache go test ./...
  • env GOCACHE=/tmp/fivetran-go-build-cache DATABASE_HOST=... DATABASE_NAME=... DATABASE_USERNAME=... DATABASE_PASSWORD=... go test -tags=integration ./cmd/internal/server/handlers -run TestIntegrationMidTableDDLRequiresHistoricalResync -count=1 -v
  • env GOCACHE=/tmp/fivetran-go-build-cache DATABASE_HOST=... DATABASE_NAME=... DATABASE_USERNAME=... DATABASE_PASSWORD=... make test-integration-stress

@nickvanw
nickvanw force-pushed the fix/vstream-schema-fail-fast branch from 31fb5dd to 79b18f1 Compare June 16, 2026 05:36
@nickvanw nickvanw changed the title Fail fast on VStream schema incompatibility Return read errors with VStream schema guidance Jun 16, 2026
@nickvanw
nickvanw force-pushed the fix/vstream-schema-fail-fast branch from 79b18f1 to 8069146 Compare June 16, 2026 05:38
@nickvanw
nickvanw force-pushed the fix/vstream-schema-fail-fast branch from 8069146 to 17a8e22 Compare June 16, 2026 05:58
@nickvanw
nickvanw force-pushed the fix/vstream-schema-fail-fast branch from 17a8e22 to 1081465 Compare June 16, 2026 06:12
@nickvanw
nickvanw merged commit c5bbd92 into main Jun 16, 2026
8 checks passed
@nickvanw
nickvanw deleted the fix/vstream-schema-fail-fast branch June 16, 2026 15:24
orware added a commit that referenced this pull request Aug 3, 2026
IsBinlogsExpirationError drops the saved position and lets the next
iteration run a historical sync, so the connection recovers on its own.
The schema-incompatibility path added in #89 returns an error instead, so
a deploy that changes the layout of a replicated table stalls the
connection until someone triggers a historical re-sync by hand. Until
they do, every sync retries from the same position and fails on the same
binlog event. Because a Read() error returns out of the whole Sync
handler rather than skipping the affected table, one table in this state
stalls every table in the connection.

Unlike expired binlogs the operator has a real choice here, since the
data is still readable once the projection is rebuilt, and an automatic
historical sync costs monthly active rows. So this is opt-in via a new
auto_resync_on_schema_change configuration field, defaulting to false,
which preserves the existing behaviour exactly. With it enabled the
cursor is reset and the stream recovers unattended.

The cursor carries SCHEMA_INCOMPATIBILITY_ERROR rather than reusing
BINLOG_EXPIRATION_ERROR, so the two causes stay distinguishable
downstream and an unexpected historical sync remains attributable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

PlanetScale Connector Does Not Automatically Recover From FAILED_PRECONDITION Errors Caused by Mid-Table DDL Changes

2 participants