The retention job that deleted depot-3 INC-2541

OpenDatabases · Hard · Recover · about 45 min ·Linux

Lab machine

A private Linux machine with the problem already set up. Sessions last up to 60 minutes.
Ana Costa opened INC-2541 at 07:35SEV-1

Overnight a retention migration was meant to purge old cancelled shipments. This morning every depot-3 parcel from before today is "not found" in tracking. There is a backup from 01:00.

Customer service has forty calls queued before 08:00, all about depot-3 parcels that tracking no longer knows. The depots have been scanning since 06:00, so the database has moved on since the backup.

"There's a full backup from 01:00. Can we just restore it?" (Ivo)

Before restoring anything, work out exactly what the migration removed, what it was supposed to remove, and what has been written since.

Your task

Bring back the shipments the migration deleted by mistake, with their original ids, without losing this morning's scans and without undoing the deletions the retention policy really wanted.

On the machine

  • migrations/0042_purge_cancelled.sql
  • backups/waybill-2026-10-04T0100Z.dump (pg_restore -l lists what it holds)
  • psql -d waybill -c "SELECT depot, status, count(*) FROM shipments GROUP BY 1, 2"

Timeline

01:00Nightly backup of the waybill database.
01:20Retention migration CHG-4475 runs in the deploy window.
07:20Customers read depot-3 tracking numbers that return "not found".
07:35"There's a full backup from 01:00. Can we just restore it?" (Ivo)

Done when

  1. Every shipment the migration deleted by mistake is back, unchanged, with its original id.
  2. The shipments recorded since the 01:00 backup are all still there, unchanged.
  3. The shipments the retention policy meant to purge stay purged.

Hints

Hint 1

Read the migration's WHERE clause the way PostgreSQL does. AND binds tighter than OR.

Hint 2

`pg_restore` can restore into a different, empty database. Nothing forces you to restore over waybill.

Hint 3

With the backup in its own database, compare it with the live table by id.

Hint 4

Write the condition the comment describes, and keep rows that match it out of what you copy back.

Show the solution

Restore the backup into a new database (`createdb recovery && pg_restore -d recovery backups/*.dump`), copy its shipments into the waybill database (for example `\copy` out and into a temporary table), then `INSERT INTO shipments SELECT * FROM restored WHERE id NOT IN (SELECT id FROM shipments) AND NOT (status = 'cancelled' AND (created_at < DATE '2026-07-06' OR depot = 'depot-3'))`.