数据库巡检不是走过场的填表,而是要在系统崩盘前找到那个冒烟的零件。很多团队把巡检做成了“检查磁盘空间、看看日志有没有报错”的表面功夫,结果真正出问题的时候,备份不可用、索引碎片拖垮性能、连接池耗尽导致服务雪崩。巡检清单的核心价值在于,用一套可执行的动作,把数据库的健康度量化出来,而不是凭感觉说一句“今天数据库挺正常的”。

下面这份清单,覆盖了从硬件资源、实例状态、备份可靠性、性能基线到安全审计的全维度检查项,每一项都附带具体的检查方法和判定标准,拿来就能直接用。

操作系统与硬件层检查

数据库跑在操作系统之上,底层资源出问题,上层优化都是白费力气。首先看内存使用情况,不要只看free命令显示的剩余内存,更要关注swap的使用量。哪怕swap只用了100MB,也说明某个时刻物理内存不够了,数据库进程可能被OOM Killer盯上。用

cat /proc/sys/vm/swappiness
查看当前值,数据库服务器建议设为10以下,避免内核过早把数据页换出到swap。

CPU负载要看趋势而不是瞬时值。用top或htop看1分钟、5分钟、15分钟的load average,如果15分钟负载持续超过CPU核心数的80%,说明计算资源已经吃紧。同时检查CPU的steal time,在云服务器或虚拟化环境里,如果steal time持续高于5%,说明宿主机资源争抢严重,你的数据库实例实际上拿不到分配的vCPU,这时候找云服务商提工单比优化SQL更管用。

磁盘层面,用iostat -x 1看磁盘的util%和await。util%接近100%就是IO瓶颈,但更要关注await这个指标,它反映了IO请求的平均等待时间。对于SSD,await超过10ms就算异常;对于机械盘,超过30ms需要警惕。还有一个容易被忽略的点是磁盘的读写比例,如果发现写操作占比异常升高,可能是checkpoint过于频繁或者redo log太小导致频繁刷盘。

文件系统层面,检查数据目录、日志目录、临时目录的inode使用率。用df -i查看,inode耗尽比磁盘空间耗尽更隐蔽,表现是磁盘还有空间但无法创建新文件,MySQL会报OS error code 28错误,PostgreSQL会直接拒绝写入。大目录下的小文件数量也要定期清理,比如MySQL的binlog目录、PostgreSQL的pg_wal归档目录。

数据库实例核心状态

数据库进程是否在运行是最基础的检查,但光看进程存在还不够。要验证数据库是否真正可对外提供服务。对于MySQL,执行

SELECT 1;
只是确认连接通道,更好的做法是执行
SELECT @@read_only, @@super_read_only;
确认读写状态是否符合预期。一个经典故障场景是主从切换后,原主库被设置为read_only但应用还在往上面写,结果业务报错。

对于PostgreSQL,用

SELECT pg_is_in_recovery();
判断当前节点是主库还是备库,结合
SELECT pg_current_wal_lsn();
SELECT pg_last_wal_receive_lsn();
来确认WAL的写入和接收位置。

连接数检查不能只看当前连接数是否接近最大连接数上限。要分析连接的状态分布,大量Sleep连接可能是应用没有正确关闭连接池,大量Locked或Waiting连接说明存在锁争用。MySQL里用

SHOW PROCESSLIST;
SELECT * FROM information_schema.processlist WHERE command != 'Sleep';
过滤掉空闲连接后看活跃连接在做什么。PostgreSQL里用
SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
快速统计各状态连接数。

错误日志扫描是每次巡检必须做的动作。不要只看ERROR级别,WARNING里也藏着重要线索。MySQL的error log里如果出现[Warning] Aborted connection,说明有客户端非正常断开,可能是网络问题或连接超时设置不合理。PostgreSQL的日志里如果频繁出现checkpoint starting和checkpoint complete,说明checkpoint间隔太短,需要调整checkpoint相关参数。用脚本把错误日志里的关键错误计数统计出来,和上一次巡检做对比,新出现的错误类型要重点排查。

备份与恢复验证

备份不做恢复验证,就等于没有备份。巡检时不能只看备份任务是否执行成功,必须定期做恢复演练。物理备份要看最近一次全量备份的时间戳和文件大小是否在合理范围内,增量备份或归档日志是否连续,有没有出现断链。逻辑备份要抽查几张核心业务表,看导出的数据行数是否和生产环境一致。

对于MySQL的xtrabackup备份,检查备份目录下的xtrabackup_checkpoints文件,确认backup_type是full-backuped还是incremental,以及from_lsn和to_lsn的连续性。对于PostgreSQL的pg_basebackup或pgBackRest备份,检查备份标签文件和WAL归档的完整性。

恢复时间目标(RTO)和恢复点目标(RPO)不是写在文档里的空话。巡检时要计算当前备份策略下,最坏情况会丢失多少数据,恢复需要多长时间。如果最近一次全量备份是三天前,而归档日志从昨天开始因为磁盘满而中断,那你的RPO实际上已经是24小时而不是文档里写的5分钟。这种差距必须在巡检报告中如实记录并推动解决。

性能基线对比

没有基线的巡检是盲人摸象。至少保留最近30天的关键性能指标数据,每次巡检时和基线做对比。QPS和TPS的波动如果在业务高峰期之外出现异常尖峰,可能是定时任务或爬虫导致的。慢查询数量要按天统计,如果某天突然增多,立刻去慢查询日志里找对应的SQL,用pt-query-digest或pg_stat_statements分析执行计划是否发生了变化。

缓冲池命中率是衡量内存配置是否合理的关键指标。MySQL的InnoDB buffer pool命中率用

SELECT (1 - (SUM(innodb_pages_read) / SUM(innodb_buffer_pool_read_requests))) * 100 AS hit_ratio FROM information_schema.INNODB_BUFFER_POOL_STATS;
计算,低于99%就要考虑增加buffer pool大小或优化SQL减少数据访问量。PostgreSQL的shared buffer命中率通过
SELECT (sum(heap_blks_hit) * 100) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS hit_ratio FROM pg_statio_all_tables;
获取,低于95%需要关注。

锁等待和死锁是性能杀手。MySQL用

SHOW ENGINE INNODB STATUS\G
查看LATEST DETECTED DEADLOCK段落,把死锁涉及的事务和SQL记录下来。PostgreSQL用
SELECT * FROM pg_locks WHERE NOT granted;
查看当前等待中的锁,结合pg_stat_activity找出阻塞链。死锁不可怕,可怕的是死锁频繁发生却没人知道,巡检的目的就是把这种隐蔽的问题暴露出来。

索引使用情况要定期审查。MySQL用

SELECT * FROM sys.schema_unused_indexes;
找出从未使用过的索引,这些索引不仅浪费磁盘空间,还会拖慢写入性能。PostgreSQL用
SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;
做同样的事。同时检查重复索引,比如已经有了(a,b)的联合索引,又单独建了(a)的索引,前者已经覆盖了后者的功能。

数据完整性与一致性

主从复制延迟是分布式架构里绕不开的检查项。MySQL用

SHOW SLAVE STATUS\G
看Seconds_Behind_Master,但这个值不一定准确,更可靠的方法是比对主库和从库上同一张表的checksum,用pt-table-checksum工具定期做数据一致性校验。PostgreSQL用
SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) FROM pg_stat_replication;
查看复制延迟的字节数。

孤立数据和逻辑坏块是静默的数据损坏。MySQL用

CHECK TABLE tablename;
对MyISAM表做检查,InnoDB表虽然不需要常规检查,但可以用
SELECT COUNT(*) FROM tablename;
全表扫描来触发数据页校验。PostgreSQL可以在空闲时段对重要表执行
VACUUM FULL VERBOSE tablename;
,这个过程会扫描所有数据页并修复可见性映射。

自增ID或序列的剩余空间要提前预警。MySQL的自增主键如果用int类型,上限约21亿,用

SELECT MAX(id) FROM tablename;
看当前最大值,如果已经超过15亿,就要规划改bigint的方案了。PostgreSQL的序列用
SELECT * FROM pg_sequences WHERE sequence_name = 'seq_name';
查看last_value和max_value的差距。

安全与权限审计

用户权限最小化原则说起来简单,实际环境里经常出现拥有SUPER权限的应用账号。MySQL用

SELECT user, host FROM mysql.user WHERE Super_priv = 'Y';
列出所有超级权限用户,逐一确认是否必要。PostgreSQL用
SELECT * FROM pg_roles WHERE rolsuper = true;
做同样的事。应用账号只需要SELECT、INSERT、UPDATE、DELETE和EXECUTE权限,DDL权限应该严格限制在运维账号。

密码过期策略和登录失败处理要检查。MySQL 8.0支持

ALTER USER 'username'@'host' PASSWORD EXPIRE INTERVAL 90 DAY;
设置密码过期,用
SELECT user, host, password_last_changed FROM mysql.user;
查看密码最后修改时间。PostgreSQL用
SELECT * FROM pg_shadow;
查看用户密码有效期配置。

网络访问控制要看数据库是否绑定了正确的监听地址。用

netstat -tlnp | grep mysql
netstat -tlnp | grep postgres
确认数据库端口只监听在内网IP或本地回环地址上,如果发现监听在0.0.0.0且没有防火墙规则限制,这就是一个高危漏洞。

审计日志要确认是否开启并正常记录。MySQL的企业审计插件或Percona的审计插件,检查日志文件是否在持续写入,大小是否在可控范围内。PostgreSQL的pgAudit扩展,检查审计日志的轮转策略是否生效,避免日志把磁盘撑满。

定时任务与自动化脚本

数据库服务器上的crontab要定期审查。用

crontab -l -u mysql
crontab -l -u postgres
查看数据库用户下的定时任务,确认每个任务的用途和执行频率。遇到过案例是半年前为了临时修复数据写了个脚本挂在crontab里,后来业务逻辑变了,这个脚本还在每天执行,导致数据被错误覆盖。

数据库内部的事件调度器也要检查。MySQL用

SHOW EVENTS;
查看所有定时事件,确认每个事件的执行状态和最后一次执行时间。PostgreSQL没有内置事件调度器,但很多团队用pg_cron扩展,用
SELECT * FROM cron.job;
查看定时任务列表。

监控告警规则本身也需要巡检。检查告警阈值是否合理,比如磁盘使用率告警设在95%就太晚了,建议设在80%提前预警。检查告警接收人是否还在职,告警通道是否畅通,用一次模拟告警来验证整个链路。很多故障没被及时发现,不是因为监控没配,而是告警被静音了或者接收人离职了邮件没人看。

容量规划与趋势预测

每次巡检都要记录磁盘使用量、数据增长量、连接数峰值等容量相关指标,用表格或图表工具生成趋势线。如果数据量以每月20%的速度增长,而磁盘剩余空间只能支撑3个月,现在就要启动扩容流程,而不是等到磁盘报警再手忙脚乱。

表空间和数据文件的大小要单独统计。MySQL用

SELECT table_schema, SUM(data_length + index_length) / 1024 / 1024 / 1024 AS size_gb FROM information_schema.tables GROUP BY table_schema ORDER BY size_gb DESC;
查看各库大小。PostgreSQL用
SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) FROM pg_database ORDER BY pg_database_size(pg_database.datname) DESC;
查看各库大小。找出增长最快的库和表,和业务方确认增长是否符合预期。

归档日志的清理策略要验证。MySQL的binlog过期时间用

SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';
查看,确认过期时间设置合理且清理机制正常工作。PostgreSQL的WAL归档用pg_archivecleanup或归档脚本管理,检查归档目录下是否有大量未清理的历史文件。

巡检结果输出与闭环

巡检做完不是终点,把发现的问题分级记录并推动解决才算完成闭环。严重级别的问题比如备份失败、主从复制中断、磁盘空间不足,需要立即处理并升级通知。警告级别的问题比如慢查询增多、索引命中率下降、连接数接近上限,纳入本周的优化计划。提示级别的问题比如存在未使用的索引、密码即将过期,列入下个迭代周期处理。

每次巡检报告至少包含三部分内容:本次巡检发现的异常项及处理建议、上次巡检遗留问题的跟进状态、关键性能指标的趋势图。报告要存档,半年后回头看,能清晰地看到数据库的健康度变化轨迹,这对容量规划和架构演进有重要的参考价值。