Ops runbook · RB-014
ops role credentials for booking-prod and can run blctl from the bastion.Do not restore anything until writes are stopped. A restore over live writes produces a database nobody can reason about.
01
psql -h db-primary.internal.brightloom.dev -U ops -c 'select 1'
Expect a connection error or a timeout after 5 s. If it returns 1, this is not the right runbook — go to the connector runbook instead.
02
blctl api set-mode --service booking --mode read-only --reason "INC restore in progress"
Expect mode=read-only acknowledged by 6/6 instances. If fewer than six acknowledge, repeat before continuing.
03
blctl status publish --component booking --state degraded --template restore-in-progress
Expect published: status.brightloom.dev updated.
booking are rejected with a 503 and a retry header.degraded for the booking component.Snapshots run hourly and are verified nightly. Always restore into a new host — never over the existing primary.
01
blctl db snapshots --cluster booking-prod --limit 8 --verified-only
Expect a table of snapshot IDs with timestamps. Note the ID, for example snap-20260724-1400Z.
02
blctl db provision --name db-restore-01 --class primary-equivalent --wait
Expect db-restore-01 ready followed by its internal hostname.
03
pg_restore --host db-restore-01.internal.brightloom.dev --username ops \
--dbname booking --jobs 4 --clean --if-exists \
/snapshots/snap-20260724-1400Z.dump
Expect no output on success and an exit code of 0. Warnings about missing roles are safe to ignore.
04
blctl db verify --host db-restore-01 --suite booking-integrity
Expect 14/14 checks passed. Any failure stops the procedure — escalate rather than improvise.
select count(*) from appointments is within 1% of the pre-incident dashboard value.select max(created_at) from appointments is no older than the snapshot timestamp.Cutover is a DNS-level change and takes up to 90 seconds to propagate internally. Do not skip the soak.
01
blctl db promote --host db-restore-01 --cluster booking-prod --confirm
Expect db-restore-01 is now primary for booking-prod.
02
blctl service restart --service pms-connector --rolling
Expect 6/6 instances healthy within 60 s.
03
blctl watch errors --service booking --window 5m
Expect an error rate at or below 0.1%. Anything higher: roll back.
04
blctl api set-mode --service booking --mode live
blctl smoke booking --clinic test-clinic-001
Expect mode=live and smoke: create, read, cancel all passed.
05
blctl status publish --component booking --state operational --template resolved
Expect published. Post the timeline in the incident channel before you log off.
operational and the incident has a written timeline.Use this only if the soak in phase 3 shows an error rate above 0.1%, or if any integrity check failed. Rolling back is always safer than continuing with a suspect database.
01
blctl db demote --host db-restore-01 --cluster booking-prod --confirmExpect db-restore-01 demoted; no primary assigned.
02
blctl db promote --host db-primary --cluster booking-prod --confirmExpect db-primary is now primary. If this fails, do not retry — escalate.
03
blctl api set-mode --service booking --mode read-only --reason "rollback, escalating"Expect mode=read-only acknowledged by 6/6 instances, then page in order below.