Skip to main content
RunBook Academy

← All checklists in PostgreSQL

As neededpg-post-maintenance

PostgreSQL Post-Maintenance Verification

19 items ·14 critical ·5 warn ·0 info

How to use this checklist

Immediately after a planned change closes, before anybody stands down.

It exists because three kinds of thing survive a window that appeared to go well: a change that did not take effect, wreckage from something that was cancelled, and a setting somebody altered for the window and has not put back.

Check the effect on a new connection

Three kinds of wreckage

A replication slot with no consumer. It retains WAL indefinitely, and the failure arrives days later as a full volume with no obvious connection to this change.

Settings changed for the window

The ones that are routinely left behind:

SettingWhy it was changedWhat it costs if left
synchronous_standby_namesA standby was being restartedThe durability guarantee, silently
maintenance_work_memTo speed a vacuumMemory, if set with ALTER SYSTEM
vacuum_cost_delayTo remove the throttleI/O impact during normal operation
temp_file_limitAn emergency capMysterious query failures later

Test the negative case if access changed

A change to pg_hba.conf, roles or grants that has only been tested with something that should succeed has not been tested. Loopback trust makes the positive test pass regardless of what the rules say.

Attempt something that should now be refused, from the application’s network path, and confirm the refusal.

Write the record while it is fresh

The change, the old value, the new value, the mechanism, the timings, and the measurement of whether it worked.

The next person to investigate this cluster will find the change and want to know why it was made. This note is the only thing that will tell them, and it is worth ten minutes now rather than an hour of archaeology later.

Where the numbers come from

Every figure is a comparison against the pre-change capture rather than an absolute reading: row counts, object counts, non-default settings, plans for the significant queries, and each standby’s position. A value that looks reasonable and differs from before is the finding this review exists to produce.

Health comes from the application’s monitoring over a period long enough to include its scheduled work, not from the database’s opinion of itself in the ten minutes after the window closed.

Access this needs

A role holding pg_monitor on every affected node and pg_read_all_settings for the parameters the change touched, plus the captured pre-change state from the pre-maintenance review.

A non-privileged connection from the application’s own network path with the real credential and driver, if anything touching access was changed — and a deliberately wrong credential, because a path that has only ever succeeded has not been shown capable of refusing.

Read access to the application’s own monitoring, since database metrics can look perfect while a service is failing.

What the review produces

A dated record naming the reviewer, the change, and the disposition of every item, with the before-and-after comparison attached in full. Record the measured duration of each phase, because the next window is planned from these numbers rather than from an estimate.

Any place where the runbook was wrong goes back into the runbook the same day, while it is still remembered. Anything left undone — a backup not yet retaken, an alert not yet re-enabled, a standby not yet returned to the synchronous set — is assigned an owner and a date before this record is signed.

Sign-off

  • Reviewer: ________________ Date: ___________
  • Change owner: _____________ Date: ___________
  • Service owner: ____________ Date: ___________

Every critical item must pass before the window opens. A failing critical item postpones the window; it is not a risk to carry into it. Record the date, the reviewer, and the name of whoever authorised proceeding with any item unmet.

Critical14 items

  1. psql -c "SELECT name, setting, source, sourcefile FROM pg_settings WHERE name = 'work_mem';"
  2. psql -c "SELECT name, setting FROM pg_settings WHERE pending_restart;"
  3. psql -c "SELECT count(*) FROM pg_stat_activity WHERE wait_event_type = 'Lock' AND state = 'active';"
  4. psql -c "SELECT c.relname, i.indisvalid, i.indisready, pg_size_pretty(pg_relation_size(c.oid)) FROM pg_class c JOIN pg_index i ON i.indexrelid = c.oid WHERE NOT i.indisvalid;"
  5. psql -c "SELECT application_name, state, sync_state FROM pg_stat_replication ORDER BY application_name;"

Warning5 items

  1. psql -c "SELECT slot_name, active, wal_status FROM pg_replication_slots;"