This chapter covers the core features and capabilities of Database Monitoring Setup.
outage.
You should be comfortable running an exporter, editing Prometheus/Alertmanager
config, and importing a Grafana dashboard. No paid tooling required.
database-monitoring-setup/
├── README.md
├── LICENSE
├── monitoring/
│ ├── prometheus.yml # scrape config: postgres/mysql/node exporters
│ ├── alert.rules.yml # PromQL alerts + recording rules, severities
│ └── alertmanager.yml # severity-based routing, grouping, inhibition
├── dashboards/
│ ├── postgresql-overview.json # importable Grafana dashboard (8 panels)
│ └── mysql-overview.json # importable Grafana dashboard (8 panels)
├── exporters/
│ ├── postgres-exporter-setup.md # least-privilege role + systemd + verify
│ ├── postgres-exporter-queries.yaml# custom queries: lag, activity, locks, bloat
│ └── mysqld-exporter-setup.md # least-privilege user + collectors + verify
├── scripts/
│ ├── pg_healthcheck.sh # one-shot PostgreSQL health probe
│ ├── mysql_healthcheck.sh # one-shot MySQL health probe
│ └── replication_check.sh # replica lag / replication-health gate
├── sql/
│ ├── postgres-metric-queries.sql # cache ratio, lag, bloat, locks, slow queries
│ └── mysql-metric-queries.sql # buffer pool, lag, locks, digests
└── docs/
├── key-metrics-guide.md # what to watch and why; good/alert values
└── alerting-runbook.md # one response section per alert
promtool / amtool (optional) to validate config; psql/mysql clients forthe scripts.
Hostnames (
db01.example.com), subnets, and passwords are placeholders —replace them. Credentials are always passed via env/defaults files, never
hard-coded.
Follow this guide to get Database Monitoring Setup up and running in your environment.
1. Stand up the exporters using exporters/postgres-exporter-setup.md and
exporters/mysqld-exporter-setup.md. Each creates a least-privilege
monitoring role and verifies the metrics endpoint.
2. Install the custom Postgres queries (exporters/postgres-exporter-queries.yaml)
so the replication-lag/activity/bloat series the alerts need exist.
3. Add the scrape jobs — merge monitoring/prometheus.yml (edit the targets),
then validate and reload:
promtool check config monitoring/prometheus.yml
promtool check rules monitoring/alert.rules.yml
curl -X POST http://localhost:9090/-/reload4. Wire up Alertmanager with monitoring/alertmanager.yml (point the
receivers at your paging/chat), then amtool check-config monitoring/alertmanager.yml.
5. Import the dashboards — in Grafana, *Dashboards → Import → Upload JSON*,
pick dashboards/postgresql-overview.json (and the MySQL one), and select your
Prometheus datasource when prompted.
6. Add the health checks to cron (optional) as a belt-and-suspenders probe:
PGHOST=db01.example.com PGUSER=monitor PGDATABASE=app_db ./scripts/pg_healthcheck.sh
./scripts/replication_check.sh --engine mysql --max-lag 30| File | What it does | Notes |
|---|---|---|
monitoring/prometheus.yml | Scrapes postgres/mysql/node exporters; relabels host:port → clean instance | Edit static_configs targets and labels |
monitoring/alert.rules.yml | Recording rules (hit ratio, connection %) + alerts for down, connections, lag, deadlocks, slow queries | Tune expr/for; severities drive routing |
monitoring/alertmanager.yml | Routes page/ticket/info, groups, inhibits downstream alerts when an instance is down | Replace receiver URLs/emails |
dashboards/postgresql-overview.json | Up, connection %, cache ratio, lag, backends-by-state, transactions, deadlocks, size | Datasource + instance are template variables |
dashboards/mysql-overview.json | Up, connection %, buffer pool ratio, replica lag, query mix, threads, slow queries, row ops | Same templating |
exporters/postgres-exporter-setup.md | pg_monitor role, DSN via secrets, systemd unit, troubleshooting | Least privilege — never superuser |
exporters/postgres-exporter-queries.yaml | pg_replication_lag_seconds, pg_stat_activity_count{state}, lock & bloat series | Set PG_EXPORTER_EXTEND_QUERY_PATH |
exporters/mysqld-exporter-setup.md | Monitoring user with PROCESS, REPLICATION CLIENT, SELECT, collectors, troubleshooting | MariaDB field-name notes included |
scripts/pg_healthcheck.sh | Connectivity, connection %, cache ratio, idle-in-tx, longest tx | libpq env vars; exits non-zero on failure |
scripts/mysql_healthcheck.sh | Connectivity, connection %, buffer pool ratio, aborted connects | Uses a defaults file for creds |
scripts/replication_check.sh | Replica lag + thread health gate for either engine | Good for cron + pre-failover checks |
sql/postgres-metric-queries.sql | The raw queries behind every Postgres metric | Run in psql during incidents |
sql/mysql-metric-queries.sql | The raw queries behind every MySQL metric | Run in the mysql client |
docs/key-metrics-guide.md | Why each signal matters, good vs alert values | Read this first |
docs/alerting-runbook.md | Response steps per alert; linked from each rule | Keep open during on-call |
PostgreSQL ──► postgres_exporter ─┐
├─► Prometheus ──► alert.rules.yml ──► Alertmanager ──► page/ticket/info
MySQL ───────► mysqld_exporter ───┘ │
└─► Grafana dashboards (postgresql-overview / mysql-overview)
The recording rules in alert.rules.yml define cache-hit and connection ratios
once, so the dashboards and alerts always agree. Every alert carries a
runbook annotation pointing at the matching section of docs/alerting-runbook.md.
Get the full Database Monitoring Setup and unlock everything.
Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.
Access all interactive tools with complete data, all workload profiles, and the full scenario library.
Downloadable source code, configuration files, and working examples from every chapter.
Free updates for life. Every new chapter, tool, and improvement included.