Skip to content

Safety Guarantees

splaxtr edited this page Aug 26, 2026 · 1 revision

Safety Guarantees

What the tool guarantees, what it does not, and the four switches that relax it. The "not guaranteed" half is the more useful one.

Guaranteed

  • The source is never written to. Every statement sent to the source is a SELECT. Rollback is therefore trivial: point your application back at the source and nothing was lost.
  • A failure leaves the target untouched. Truncate, copy, sequence fixup and verification share one transaction; any failure rolls it back and the target is byte-identical to before the run.
  • Success means the data actually moved. A run only succeeds if the plan was non-empty, at least one row was copied, every table's row count matches, and no foreign key has an orphaned child. Any of those failing is a failure, not a warning.
  • Text is preserved exactly. Casing, accents and Turkish characters pass through unchanged.

Not guaranteed

  • A consistent snapshot of a live source. Stop writes before you start — the copy reads table by table.
  • That the target schema is right. A column missing from the target simply doesn't travel, and the run still succeeds — dropped columns are a normal schema-change outcome. Read the report.
  • That your data was correct to begin with. A wrong balance in the source arrives as the same wrong balance in the target, faithfully.
  • Sub-microsecond timestamps. datetime2 (100 ns) is truncated to PostgreSQL's microseconds. Matters only for exact-equality comparisons.

The four escape hatches

All off by default; each exists because a real migration occasionally needs it:

Option What it lets through When it is legitimate
Allow tables missing from target Source tables with no target counterpart The schema genuinely dropped them. Read the list first
Allow schema risk NULLs headed for NOT NULL columns; over-length values You prefer a loud mid-copy failure over an up-front block
Allow collation mismatch A target collation other than the expected one You chose it deliberately and accept the search/sort consequences
Verify only Skips the copy entirely Auditing an earlier migration without touching anything

Turning one on without reading what it reported cancels the reason this tool exists.

Stored credentials

Saved connections live in a JSON file under your local application data directory. Passwords are encrypted with the ASP.NET Core data-protection stack, keyed to your machine — copying the file elsewhere yields unreadable passwords. This protects against the file leaking; it does not protect against someone using your logged-in session, because the app must be able to decrypt them to connect.

Operational prerequisites

  • Suspending constraint triggers requires superuser on PostgreSQL; creating the target database requires CREATEDB.
  • One transaction locks every table being loaded, exclusively, until commit. Nothing else reads them during the run — plan the window.
  • On schemas of a few hundred tables, raise max_locks_per_transaction (512+) or the run can abort late with out of shared memory.

Full text: docs/SAFETY.md.

Clone this wiki locally