live02:00WALnewTL 2id item status1 tea paid2 mug paid3 kettle paid4 cups paid4 cups sent5 teapot paid09:10 INSERT id 411:30 INSERT id 513:45 UPDATE id 414:05 DELETE allid item status1 tea paid2 mug paid3 kettle paid4 cups paid4 cups sent5 teapot paid02:00WALWAL
Back row: the live server, the base backup, the WAL archive and a new serverFront: the live orders, the WAL records and the restored ordersMoving blocks: the base backup and the WAL filesAt the back: the live server, the 02:00 base backup, the WAL archive and a new server. In front: the live orders, the WAL records since the backup, and the restored orders. Point-in-time recovery restores the base backup, then replays the archived WAL in order and stops at the target, 14:04:59, just before the 14:05 DELETE. All 5 orders come back; the delete is never replayed. The WAL does not store SQL text: it stores low-level changes to table and index pages. The figure writes each record as the statement that made it, so you can read it.

Taking backups

  1. A backup is a copy of the data from the past that you can go back to. A replica is not one: it repeats every change within moments, mistakes included. Here, a shop keeps its orders in PostgreSQL.

A mistake at 14:05

Recovering to a point in time

What happens

;; step 1/11 · why
backup    a copy of the data from the past
          that you can go back to
replica   a second server that repeats every change
          as it arrives: a mistake reaches it too

table orders
  column id     type integer
  column item   type text
  column status type text

pg_dump writes a database out as SQL: a snapshot
of one moment. To reach ANY moment, PostgreSQL
needs two pieces: a base backup and the WAL.

The WAL does not store SQL text: it stores low-level changes to table and index pages. The figure writes each record as the statement that made it, so you can read it. Real WAL file names, commit times and backup paths will differ. The times here are rounded so the story is easy to follow.