Skip to content

Recover a dropped table

A destructive migration moves a dropped table aside with its rows intact, keeping it recoverable for 30 days before a background job removes it for good.

A destructive migration parks what it removes instead of dropping it: a table moves aside with its rows intact, a dropped column is renamed in place, and either is preserved for 30 days before a background job drops it for good.

1. Check what is preserved

tide parkedtideout
KIND     OBJECT                          RECOVERABLE FOR    STATE
table    atlantis.consumer_cart          22d                recoverable
column   atlantis.consumer_order.notes   6d                 recoverable

The console’s Parked page shows the same objects, with the date each one was parked. An object under 7 days from reaping is highlighted. tide parked --all includes objects already reaped — those rows are gone, and only a platform backup restore brings them back.

The window is an absolute instant fixed when the object is parked; changing the retention setting later does not move it.

2. Restore it

Re-add the entity or field to the .atl file exactly as it was — git revert the commit that dropped it — then:

tide plan
tide apply

The apply moves the parked object back: the entity exists again, with its API, its generated types, and the rows it held when it was dropped.

A restored field comes back as it was declared when it was dropped. The restore is additive: the column comes back with its rows. If the declaration changed since, the plan lists each difference after the restore as its own change: a new type, not null, unique, check, reference or default. Each difference is classed and gated as it would be on any other column.

Conditions on the restore:

  • The window must still be open. Re-declaring after the reaper has run creates a fresh, empty object; the rows are gone, and only a platform backup restore brings them back.
  • A restored table must be declared as it was dropped. tide apply refuses a different column name, type or check. A changed default, unique or reference is not applied: the table keeps the parked ones. Restore the table with its original declaration, then change it in a second apply.
  • A parked column must keep the type it was dropped with, and schema history must record its declaration. Otherwise tide plan refuses the restore and names the problem: change the column back, or give the field another name.

Rows inserted while a column was parked

Rows inserted while a NOT NULL column with no default was parked have no value for it, so restoring it fails. tide rehearse reports this before the apply. Declare a backfill for those rows:

customer_name text not null backfill "'unknown'"

tide apply --backfill restores the parked column with every value it held, and fills only the rows without one. A default does not fill them, because it applies only to rows inserted later. tide rehearse runs the migration without the backfill, so it still reports the failure after you declare one.

Verify

A query through the generated client returns the pre-drop rows, and the object no longer appears in tide parked.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close