Skip to main content
RunBook Academy

PostgreSQLXVI · Observability, Logging and AlertingObservability

The statistics views that matter, and the ones that changed

Intermediate⏱ ~30 minpsql

What you'll learn

  • Name the views that answer operational questions and what each is for
  • Handle the pg_stat_bgwriter split correctly
  • Interpret counters as rates rather than as values
  • Know which numbers are cumulative and when they reset

Prerequisites

Verified against PostgreSQL 18.x · PostgreSQL (comparison targets) 17.11, 16.15 · PostgreSQL (support calendar) 18, 17, 16, 15, 14 supported · pgBackRest 2.59.1 · PgBouncer 1.25.2 · Patroni 4.1.5 · Ubuntu (host baseline) 26.04 LTS · 2026-08-27

Not yet marked complete on this device.

There are dozens of statistics views. A small number answer questions you will actually ask.

The map

ViewAnswers
pg_stat_activityWhat is happening now
pg_stat_databaseCluster-level health: cache, deadlocks, temp files, sessions
pg_stat_all_tablesWhich tables are churned, scanned, vacuumed
pg_stat_all_indexesWhich indexes are used, and which are not
pg_statio_all_tablesWhere physical reads go
pg_stat_checkpointerCheckpoint frequency and cost
pg_stat_bgwriterBackground writer only, since 17
pg_stat_walWAL generation, lesson XII-02
pg_stat_ioI/O by backend type and context, lesson XII-05
pg_stat_replicationStandbys, Part XIV
pg_stat_archiverArchiving, lesson XIII-05
pg_stat_statementsQuery aggregate cost, lesson XVI-05

The split that breaks dashboards

Read-only / Safepg_stat_bgwriter on 18.6, in full
$ SELECT * FROM pg_stat_bgwriter;
-[ RECORD 1 ]----+------------------------------
buffers_clean    | 1354
maxwritten_clean | 9
buffers_alloc    | 61370
stats_reset      | 2026-08-27 22:14:46.039111+00
Read-only / Safepg_stat_checkpointer, where the rest went
$ SELECT * FROM pg_stat_checkpointer;
-[ RECORD 1 ]-------+------------------------------
num_timed           | 4
num_requested       | 2
num_done            | 3
restartpoints_timed | 41
restartpoints_req   | 0
restartpoints_done  | 5
write_time          | 298152
sync_time           | 44
buffers_written     | 13170
slru_written        | 23
stats_reset         | 2026-08-27 22:14:46.039111+00

The restartpoint_* columns are worth noticing: this node was a standby until the promotion in Part XV, and restartpoints are what a standby performs in place of checkpoints. restartpoints_timed 41 against restartpoints_done 5 is the normal pattern — most are skipped because replay has not advanced far enough to make one useful.

pg_stat_database

Read-only / Safethe columns worth alerting on
$ SELECT datname, numbackends, xact_commit, xact_rollback, blks_hit, blks_read,
     round(100.0*blks_hit/NULLIF(blks_hit+blks_read,0),2) AS cache_hit_pct,
     deadlocks, temp_files, pg_size_pretty(temp_bytes) AS temp,
     conflicts, checksum_failures
FROM pg_stat_database WHERE datname='postgres';
 datname  | numbackends | xact_commit | xact_rollback | blks_hit | blks_read | cache_hit_pct | deadlocks | temp_files |  temp   | conflicts | checksum_failures
----------+-------------+-------------+---------------+----------+-----------+---------------+-----------+------------+---------+-----------+-------------------
postgres |           1 |       50559 |             1 |  1447898 |     20762 |         98.59 |         0 |          4 | 9808 kB |         0 |                 0
ColumnAlert when
deadlocksIncreasing at all. Part IX
temp_files / temp_bytesIncreasing. work_mem too small, lesson XI-05
checksum_failuresNon-zero. Ever. Part XVIII
conflictsIncreasing on a standby. Lesson XIV-07
xact_rollbackRising share — application errors
cache_hit_pctFalling, as a trend
Read-only / Safethe session-outcome columns
$ SELECT datname, session_time::int, active_time::int, idle_in_transaction_time::int, sessions, sessions_abandoned, sessions_fatal, sessions_killed FROM pg_stat_database WHERE datname='postgres';
 datname  | session_time | active_time | idle_in_transaction_time | sessions | sessions_abandoned | sessions_fatal | sessions_killed
----------+--------------+-------------+--------------------------+----------+--------------------+----------------+-----------------
postgres |       521821 |      506687 |                    11760 |      271 |                  0 |              0 |               0

sessions_abandoned, sessions_fatal and sessions_killed at zero is what health looks like. Any of them climbing is a real signal: abandoned means clients disconnected without closing, fatal means the server ended them, killed means an administrator did.

idle_in_transaction_time against active_time — 11.8 s against 506.7 s here — is the ratio that surfaces the problem in lesson VII-05 before it becomes bloat.

What to take from this

  • A dozen views answer real questions. Learn those, not all of them.
  • pg_stat_bgwriter has three columns. Checkpoint metrics moved to pg_stat_checkpointer in 17.
  • Alert on deadlocks, temp_files, conflicts, and checksum_failures — the last at any non-zero value.
  • Cache hit ratio is a trend. A page-cache hit counts as a miss.
  • sessions_abandoned / _fatal / _killed climbing is a real signal.
  • Counters are cumulative. Graph rates, and watch stats_reset.
  • A crash discards statistics; the gap looks like quiet.

Cross-course references

  • Observability for Production Sysadmins — Part IX (Exporters) and Part LIX (Database observability) cover turning these views into series, and Part III (Metrics fundamentals) covers why a cumulative counter must be rated rather than graphed raw.
  • Linux for Production Sysadmins — Part XLIV (Central monitoring) covers where the resulting series are stored and who can query them.

Quiz

Knowledge check · 6 questions

  1. Q1. After upgrading to PostgreSQL 18, a checkpoint dashboard shows blank panels rather than errors. What is the likely cause?

  2. Q2. A monitoring system reports a huge negative rate for deadlocks. What most likely happened?

  3. Q3. Why is a 99.9% cache hit ratio not evidence that a cluster is healthy?

  4. Q4. Which pg_stat_database columns warrant an alert when they increase? Select all that apply.

  5. Q5. pg_stat_activity is a snapshot rather than a cumulative view, so a frequently-run 5 ms query is effectively invisible to it.

  6. Q6. Why must cumulative statistics be graphed as rates, and what should a monitoring system do about resets?

Passing score: 75%. Answers are checked in this browser.