🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Data Management / Database Administration › PostgreSQL Administration › Lesson 8
TEC-DATA86-03 · Lesson 8 · 12 clock hours · practice

Routine Maintenance: VACUUM, ANALYZE, pg_dump, and Monitoring

Objective. Students perform and schedule routine PostgreSQL maintenance tasks including manual and autovacuum tuning, logical backups with pg_dump, and server health monitoring using built-in views.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

Why Routine Maintenance Matters

PostgreSQL does not silently clean up after itself the way some database engines do. Two core maintenance operations — VACUUM and ANALYZE — must run regularly, either manually or through the built-in autovacuum daemon. Understanding what each one does, how to tune it, and how to monitor the results is a foundational DBA skill that appears on the EDB PostgreSQL CE and Oracle DBA CA exams alike.

Dead Tuples and VACUUM

When you UPDATE or DELETE a row in PostgreSQL, the old row version is not immediately removed. It is marked as dead and left in place until VACUUM reclaims the space. These dead tuples waste disk space, bloat indexes, and slow sequential scans.

`VACUUM` alone reclaims dead tuple space and marks pages as reusable. `VACUUM VERBOSE` prints a detailed report showing how many dead tuples were removed per page, which is useful when you are diagnosing bloat. `VACUUM ANALYZE` does both the cleanup pass and a statistics update in one command — usually the better choice for routine maintenance.

The system view pg_stat_user_tables tracks the column `n_dead_tup` (dead tuple count) per table. Check it before and after a VACUUM run to confirm the operation actually reclaimed tuples.

Autovacuum Tuning

The autovacuum daemon fires automatically when dead tuples exceed a threshold:

> threshold = autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor × reltuples

For a large table, the default scale factor of 0.2 (20 % of rows) means autovacuum may wait until millions of dead tuples accumulate. Lower the scale factor for high-churn tables. You can override server-wide settings at the individual table level with `ALTER TABLE`:

```sql

ALTER TABLE orders

SET (autovacuum_vacuum_scale_factor = 0.05,

autovacuum_vacuum_cost_delay = 2);

```

`autovacuum_vacuum_cost_delay` (in milliseconds) throttles how aggressively autovacuum uses I/O. A lower value lets it run faster; a higher value protects OLTP workloads from I/O contention.

ANALYZE and the Query Planner

`ANALYZE` collects column-level statistics — value distributions, most common values, null fractions — and stores them in `pg_statistic`. The query planner uses these statistics to choose join strategies and index paths. Stale statistics after a large bulk load are a common cause of suddenly poor query plans. Running `VACUUM ANALYZE` after any significant data change is good practice.

Logical Backups: pg_dump and pg_restore

`pg_dump` exports a single database into a self-contained backup. It is a logical backup — it captures SQL-level objects (tables, indexes, sequences, constraints), not raw disk blocks. Three commonly used output formats are:

| Format flag | Description | Restore tool |

|---|---|---|

| (none / plain) | Plain SQL script | psql |

| `-Fc` (custom) | Compressed, selective restore | pg_restore |

| `-Fd` (directory) | One file per object, parallelizable | pg_restore |

Custom format is the most flexible for production use: it supports parallel restore (`-j` flag), selective object restore, and reordering. Directory format adds the benefit of parallel dump (`-j` on pg_dump as well).

To back up and then restore:

```bash

pg_dump -Fc -d inventory_db -f inventory_db.dump

createdb inventory_restore

pg_restore -Fc -d inventory_restore inventory_db.dump

```

Always verify restores. Use `\dt`, `\di`, or count objects in `information_schema.tables` to confirm row and object counts match.

Server Health Monitoring with System Views

PostgreSQL exposes rich runtime statistics through the `pg_stat_*` family of views. Four views every DBA should know:

To catch slow queries, enable `log_min_duration_statement` in `postgresql.conf` (for example, set it to `1000` for queries longer than 1 second). This is PostgreSQL's equivalent of MySQL's slow-query log; note that the parameter is `log_min_duration_statement`, not `long_query_time` — that term belongs to MySQL.

Safety and Data Integrity Notes

Key terms9

Dead tupleAn old row version left in a PostgreSQL table after an UPDATE or DELETE, visible to no current transaction, that VACUUM must reclaim to free space.
VACUUM ANALYZEA combined PostgreSQL command that removes dead tuples and updates planner statistics for a table in a single pass.
autovacuum_vacuum_scale_factorA per-table or server-wide setting that defines the fraction of live rows that must become dead before autovacuum triggers a VACUUM on that table.
pg_dumpThe PostgreSQL command-line utility that creates a logical backup of a single database in plain SQL, custom, or directory format.
pg_restoreThe PostgreSQL utility that reads a custom- or directory-format pg_dump archive and applies it to a target database, supporting selective and parallel restores.
pg_stat_activityA PostgreSQL system view with one row per server backend process, showing current query text, session state, wait events, and process identifiers.
pg_stat_bgwriterA system view that reports cumulative statistics about the background writer and checkpoint processes, including buffer write counts and checkpoint timing.
log_min_duration_statementA postgresql.conf parameter that causes PostgreSQL to log any query whose execution time exceeds the specified number of milliseconds, used for slow-query detection.
idle in transactionA session state shown in pg_stat_activity indicating a connection has opened a transaction but is not executing a query, potentially holding locks and blocking autovacuum.
In class: Run VACUUM VERBOSE and VACUUM ANALYZE on a table with significant dead tuples (generated by a provided UPDATE/DELETE script); compare pg_stat_user_tables dead_tup counts before and after, then adjust autovacuum_vacuum_scale_factor and autovacuum_vacuum_cost_delay for that table using a storage-parameter ALTER TABLE statement. · Use pg_dump in three formats (plain SQL, custom, directory) to back up inventory_db; restore the custom-format backup to a new database named inventory_restore using pg_restore, and verify object counts match using a provided verification query. · Query pg_stat_activity, pg_stat_bgwriter, pg_stat_database, and pg_locks to produce a one-page server health report for a simulated busy server state (generated by pgbench -c 20 in a separate terminal); identify any idle-in-transaction sessions and explain how long_query_time logging would be configured to catch slow queries.
Materials: PostgreSQL 16 VM, pgbench, pg_dump/pg_restore, pg_stat_* system catalog views, health report template, PostgreSQL Documentation Chapters 24 (Routine Database Maintenance) and 25 (Backup and Restore)
Check: Instructor verifies restored database object counts match original using the verification query and reviews the health report for accurate interpretation of at least four monitoring views; pass = zero object-count discrepancy in restore AND health report correctly identifies at least three server metrics.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

PostgreSQL CE — Routine Maintenance
1. A table named `sales` has 500,000 live rows. The server-wide autovacuum_vacuum_threshold is 50 and autovacuum_vacuum_scale_factor is 0.2. Approximately how many dead tuples must accumulate before autovacuum triggers a VACUUM on `sales`?
PostgreSQL CE — Routine Maintenance
2. Which command reclaims dead tuple space in a PostgreSQL table AND refreshes query planner statistics in a single operation?
PostgreSQL CE — Configuration
3. You want to lower autovacuum aggressiveness on only the `orders` table to reduce I/O impact during peak hours. Which statement correctly sets a per-table storage parameter?
PostgreSQL CE — Backup and Restore
4. Which pg_dump format flag produces a compressed, single-file backup that supports selective object restore and parallel restore with pg_restore?
PostgreSQL CE — Backup and Restore
5. After restoring a pg_dump backup to `inventory_restore`, what is the BEST way to verify the restore was complete?
PostgreSQL CE — Monitoring
6. A DBA queries pg_stat_activity and finds several sessions with state = 'idle in transaction' that have been open for over 30 minutes. What is the PRIMARY concern?
PostgreSQL CE — Monitoring
7. In pg_stat_database, the columns blks_hit and blks_read can be used to calculate the buffer cache hit ratio. Which formula is correct?
PostgreSQL CE — Configuration
8. Which postgresql.conf parameter should a DBA set to log all queries that take longer than 2 seconds to execute?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.