1. 课程导入与运维自动化全景
PostgreSQL 在生产环境中往往不是“装好就完事”的数据库。随着实例数量增长、业务表持续膨胀、备份窗口被压缩、慢查询和锁等待频繁出现,DBA 与运维工程师每天面对的是大量重复、可预期、但又必须准确执行的任务:备份与恢复演练、VACUUM 与膨胀治理、索引重建、统计信息更新、连接数巡检、复制延迟监控、参数变更与回滚。自动化运维的核心目标,就是把这些任务从“依赖个人记忆和手工敲命令”转变为“可描述、可执行、可观测、可回滚”的工程化流程。
需要先明确一个边界:自动化不等于无人值守,也不等于把所有操作都写成脚本。任务治理关注的是“哪些任务值得自动化、以什么频率执行、失败后如何处置、变更如何审计”。一个典型的判断标准是:如果一个任务每周重复三次以上、步骤固定、结果可验证、失败影响可评估,它就适合进入自动化清单;反之,涉及大版本升级、存储引擎级变更、跨机房切换等高风险操作,更适合做成“半自动化 + 人工确认”的流程。
第一层,可重复——同一任务在任何时间、任何实例上执行结果一致;
第二层,可观测——每次执行都有日志、指标和退出状态;
第三层,可治理——任务有负责人、有审批、有回滚方案、有历史记录。
本课程使用的工具链围绕 PostgreSQL 生态展开,不追求“大而全”,而是选择能直接落地、便于验证的组合。数据库侧以 PostgreSQL 15/16 为主,配合 pg_stat_statements、pg_stat_activity、pg_stat_user_tables 等内置视图;操作系统侧使用 Linux(Ubuntu 22.04 或 Rocky Linux 9 均可),依赖 systemd 管理服务、cron 与 systemd timer 调度任务;脚本层以 Bash 和 Python 为主,Python 使用 psycopg2 或 psycopg 连接数据库;配置管理与编排可选用 Ansible;监控与告警使用 Prometheus + postgres_exporter + Grafana;备份工具使用 pg_basebackup、pg_dump 与 pgBackRest 中的一种或多种组合。
实验环境建议采用“单机多实例 + 容器辅助”的方式搭建,既节省资源,又能模拟真实的多实例管理场景。下面给出一个可复现的初始化示例,假设使用 Ubuntu 22.04,安装 PostgreSQL 16 并创建两个独立实例:
# 安装 PostgreSQL 16(示例,实际以官方源为准)
sudo apt update
sudo apt install -y postgresql-16 postgresql-client-16
# 创建第二个实例的数据目录
sudo mkdir -p /var/lib/postgresql/16/secondary
sudo chown -R postgres:postgres /var/lib/postgresql/16/secondary
# 初始化第二个实例
sudo -u postgres /usr/lib/postgresql/16/bin/initdb \
-D /var/lib/postgresql/16/secondary \
--encoding=UTF8 --locale=C
# 修改端口,避免与主实例冲突
sudo -u postgres sed -i "s/^#port = 5432/port = 5433/" \
/var/lib/postgresql/16/secondary/postgresql.conf
# 启动第二个实例
sudo -u postgres /usr/lib/postgresql/16/bin/pg_ctl \
-D /var/lib/postgresql/16/secondary -l /tmp/pg2.log start
启动后,用 psql -p 5433 -c "select version();" 验证实例可用。此时环境中已有两个独立实例,后续章节中的巡检、备份、参数变更等任务都可以在两个实例上分别执行,便于观察自动化脚本在多目标场景下的行为差异。
为了让后续的自动化任务有统一的观察入口,建议在实验库中预先创建一张任务执行记录表,用于记录每次自动化任务的名称、目标实例、开始时间、结束时间、退出码和简要结果。这张表不是课程要求,但它能让“可观测”这一目标变得具体:
CREATE TABLE ops_task_log (
id bigserial PRIMARY KEY,
task_name text NOT NULL,
target_db text NOT NULL,
started_at timestamptz NOT NULL DEFAULT now(),
finished_at timestamptz,
exit_code int,
message text
);
下面这张图展示了本课程所讨论的自动化运维全景:从任务来源、治理判断、工具链执行,到结果观测与反馈。它不描述某一条具体命令,而是帮助建立“任务—治理—执行—观测”的整体关系,后续章节会分别深入其中的各个环节。
从图中可以看到,任务来源、治理判断、工具链执行和观测反馈构成一个闭环。左侧的任务来源是“输入”,中间的治理判断决定“做不做、怎么做”,右侧的工具链负责“执行”,最右侧的观测与反馈则把执行结果重新送回治理环节。这个闭环的意义在于:自动化不是一次性写完脚本就结束,而是需要根据实际运行数据不断调整任务范围、执行频率和告警阈值。
在实验环境搭建完成后,建议先做一次最小验证:手动执行一条巡检命令,把结果写入 ops_task_log,再用 psql 查询这张表,确认“执行—记录—查询”这条链路是通的。例如:
-- 记录一次巡检任务
INSERT INTO ops_task_log (task_name, target_db, exit_code, message)
VALUES ('daily_check', 'primary:5432', 0, '连接数 42,膨胀率 3.1%');
-- 查看最近任务
SELECT task_name, target_db, started_at, exit_code, message
FROM ops_task_log
ORDER BY started_at DESC
LIMIT 5;
如果这条链路可以稳定运行,后续章节中更复杂的备份、VACUUM、索引重建、参数变更等任务,都可以沿用同样的“执行 + 记录 + 观测”模式。课程后续会逐步展开:如何编写可复用的巡检脚本、如何用 systemd timer 替代 cron 获得更好的日志与依赖管理、如何用 Ansible 批量下发配置、如何用 pgBackRest 做增量备份与恢复演练、如何用 Prometheus 与 Grafana 建立数据库关键指标面板,以及如何在出现复制延迟、锁等待、连接数暴涨时快速定位并处置。
1. 这个任务是否值得自动化?
2. 自动化之后,失败了我能不能第一时间知道?
3. 如果执行结果不符合预期,我能不能回滚或重试?
把这三个问题回答清楚,自动化运维就有了可靠的起点。