Repository navigation
[MSSQL]: Disable Automatic Schema change handling #727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
stevensJourney
merged 29 commits into
main
from
sourcetable-metadata-mssql-capture-recording
Aug 11, 2026
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
286ce2f
feat: source table metadata tracking and MSSQL capture instance tracking
stevensJourney 1f1af1b
fix postgres implementation and tests
stevensJourney 3be44ff
Merge branch 'main' into sourcetable-metadata-mssql-capture-recording
stevensJourney aadcc31
Add more schema change tests
stevensJourney 8f09ba9
Merge branch 'main' into sourcetable-metadata-mssql-capture-recording
stevensJourney f127432
allow updating the source metadata for existing source tables
stevensJourney 3ea4228
remove auto schema change actioning completely
stevensJourney 931c588
more removals
stevensJourney ceb91fd
add test for pinning CDC tables
stevensJourney 0af6be2
fix tests
stevensJourney f5ddebc
cleanup docs
stevensJourney c5e0739
cleanup comments
stevensJourney 1fd2dd6
revert comment change
stevensJourney 4a64493
cleanup
stevensJourney 4833742
prevent source reconcilers from modifying source table candidates. Re…
stevensJourney 49d5584
move findPinnedCaptureInstance to MSSQLSourceTable
stevensJourney 3a1b8ea
update test
stevensJourney 1648271
Add postgres changeset. Cleanup SchemaChangeType. Cleanup error throw…
stevensJourney b12cd2a
more cleanup
stevensJourney 10c2e05
Merge branch 'main' into sourcetable-metadata-mssql-capture-recording
stevensJourney 1648129
Improve MSSQLSource Table capture instance updating
stevensJourney 9cd52dd
update CaptureInstanceMissingError message
stevensJourney f4b37cb
Merge remote-tracking branch 'origin/main' into sourcetable-metadata-…
stevensJourney d695c57
Update changesets. Add agent context for Sync config versus replicati…
stevensJourney 8ef1d1a
prevent resnaphots on table re-creation. Part 1
stevensJourney 48cedb8
Part 2. ensure consistent error reports during restarts when tables a…
stevensJourney c4c1352
cleanup
stevensJourney b96edf7
fix racy test
stevensJourney d23c03b
Merge branch 'main' into sourcetable-metadata-mssql-capture-recording
stevensJourney File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| --- | ||
| '@powersync/service-module-mssql': minor | ||
| --- | ||
|
|
||
| Pin MSSQL source-table bindings to a specific CDC capture instance. | ||
|
|
||
| A source table now persists the object ID of the CDC change table it replicates from, and restores that | ||
| binding across restarts, so a stream always replicates the capture schema it started with. Existing | ||
| bindings without this metadata are backfilled at job startup with the same capture instance the previous | ||
| streaming logic would have selected. | ||
|
|
||
| SQL Server allows two capture instances per table. When a newer one appears, the current replication | ||
| process keeps polling the instance it is bound to and warns. Deploy a new sync config to use the newer | ||
| instance; the active sync config can continue serving clients through the old instance while the new sync | ||
| config snapshots and catches up. Keep the old instance available until the new sync config becomes active. | ||
|
|
||
| If CDC is disabled for a bound table, or its capture instance is removed while the source table and replica | ||
| identity remain unchanged, replication stops with `PSYNC_S1601`. A newly configured table that cannot be | ||
| replicated yet — it does not exist, or CDC has not been enabled for it — stops replication with | ||
| `PSYNC_S1602` rather than being skipped. Dropping, recreating, or otherwise changing the source identity of | ||
| a previously bound table stops replication with `PSYNC_S1603`. |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| --- | ||
| '@powersync/service-module-mssql': minor | ||
| --- | ||
|
|
||
| [Breaking Change] | ||
|
|
||
| Pin the replicated schema at the start of replication for SQL Server connections. | ||
|
|
||
| SQL Server does not deliver schema changes in the replication stream, so they can only be found by | ||
| polling, and a poll is never atomic with a commit. That leaves a gap where checkpoints are committed | ||
| against a schema that has already changed — producing a state the source database was never in, which | ||
| clients cannot detect. PowerSync therefore no longer adopts schema changes automatically. | ||
|
|
||
| The recommended schema-change workflow treats a sync config deployment as the consistency boundary. A | ||
| replication stream keeps the exact table set and CDC capture-instance identities it selected when it | ||
| started; it does not adopt schema or table changes in place. Tables must therefore be listed explicitly | ||
| rather than selected with wildcards. | ||
|
|
||
| What this means when making schema changes: | ||
|
|
||
| - **Add a table:** create the table, enable CDC, add its exact qualified name to the sync config, and | ||
| deploy a new sync config. The new sync config snapshots the table before becoming active. | ||
| - **Change captured columns:** where SQL Server allows a rolling change, apply the DDL and create a second | ||
| capture instance with the desired captured columns. Update explicit sync queries if needed, deploy a | ||
| new sync config, wait for its snapshots to finish and for it to become active, and only then remove the | ||
| old capture instance. | ||
| - **Make an identity-breaking change:** for a primary-key change, identity-column rename, or another | ||
| change that requires CDC to be disabled, disable CDC, apply the DDL, re-enable CDC, update the sync | ||
| config if needed, and deploy a new sync config. The current replication process cannot adopt the | ||
| replacement in place, so this results in downtime. If it observes CDC being disabled first, it stops | ||
| with `PSYNC_S1601` because its capture instance was removed. If it next reconciles after the replica | ||
| identity has changed, it stops with `PSYNC_S1603` instead. Disabling and re-enabling CDC without changing | ||
| the replica identity stops with `PSYNC_S1601`. | ||
| - **Drop a table:** remove it from the sync config, deploy a new sync config and wait for it to become | ||
| active, and only then drop the source table. Dropping the table first stops replication with | ||
| `PSYNC_S1603`; already-replicated data is retained until the new sync config becomes active. | ||
| - **Rename or drop/recreate a table:** update the sync config to express the intended table explicitly, | ||
| ensure the resulting table is CDC-enabled with the expected schema and replica identity, and deploy a | ||
| new sync config. The current replication process stops with `PSYNC_S1603` if its bound table is removed. | ||
| - **No deployment is needed** for changes that do not affect the captured row shape or replica identity, | ||
| such as many index, constraint, or default changes. A non-identity column change also needs no PowerSync | ||
| action if that changed column does not need to be replicated; otherwise use the rolling capture-instance | ||
| workflow above. | ||
|
|
||
| This sequencing keeps the old table or capture instance available while the new sync config snapshots and | ||
| becomes active whenever a rolling transition is possible. If a pinned capture instance or bound table is | ||
| removed first, the current replication process stops and a new sync config must be deployed. | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| '@powersync/service-module-postgres-storage': patch | ||
| --- | ||
|
|
||
| Fix hydration of replica id column type ids in Postgres bucket storage. | ||
|
|
||
| `source_tables.replica_id_columns` is persisted with a `type_oid` key, but the decoding codec declared | ||
| `typeId`, so every `SourceTable` read back from a row lost its column type ids. This affected | ||
| `getSourceTableStatus()` and the tables returned for dropping, and now also the identity comparison | ||
| used by source table reconciliation. The codec matches the persisted key - no data migration is | ||
| needed. |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| --- | ||
| '@powersync/service-module-mongodb-storage': minor | ||
| '@powersync/service-module-postgres-storage': minor | ||
| '@powersync/service-core': minor | ||
| --- | ||
|
|
||
| Add source-owned `SourceTable` reconciliation. | ||
|
|
||
| `resolveTables()` now queries all overlapping persisted candidates and passes them to a | ||
| source-provided reconciler that returns compatible and incompatible tables, can return | ||
| modified compatible copies, and supplies values used for potential new records. Storage persists allowlisted | ||
| source metadata differences but never interprets them. MongoDB v1/v3 and PostgreSQL storage were | ||
| refactored to this candidate-first model (PostgreSQL gains a nullable `source_metadata` JSONB column | ||
| via migration). |
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.