DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
雨云;给项目一台云服务器
RackNerd;$21.99/年 · 1GB KVM

pg_upgrade 后没有 analyze_new_cluster.sh,还需要收集统计吗

升级到 PostgreSQL 14 至 17 后,不再生成 analyze_new_cluster.sh,但仍需按输出收集统计。PostgreSQL 18 的默认统计迁移与后续维护另有区别。

从 PostgreSQL 13 升级到 15,升级完成却找不到以前的 analyze_new_cluster.sh。如果因此跳过统计信息收集,业务查询可能使用缺少统计依据的执行计划。先读升级日志的最后部分,确认它给出的统计更新命令是否已经执行。

PostgreSQL 14 起,pg_upgrade 不再生成这份分析脚本,改为在输出中提示相应命令。脚本没生成并不表示统计步骤取消。跨过 14 直接升级到 15、16 或 17,也会遇到这个变化。

14 至 17,与 18 的统计迁移行为不同

升级到 PostgreSQL 17 及以前的这些主版本时,pg_upgrade 不迁移优化器统计信息。表和数据已经迁移,仍需按升级输出重新收集统计。

PostgreSQL 18 默认迁移大部分优化器统计信息,但并非全部:显式 CREATE STATISTICS 的统计、扩展自定义统计和累计统计等仍有相应补充要求。升级时使用 --no-statistics,又会改变这一前提。因此,“升级后统计全部丢失”不能套到所有版本。

先核对新服务器版本、实际升级工具和升级选项。不要只看系统上默认的 vacuumdb 指向哪里:旧安装的客户端可能还在 PATH 前面,连接参数也可能仍指向旧集群。

按新集群的升级提示完成统计步骤

针对 14 至 17,升级输出会给出类似下面的分阶段分析命令:

vacuumdb --all --analyze-in-stages

这条命令使用当前客户端的默认连接配置,并处理所连接集群中的全部数据库。执行前必须确认客户端属于新版本、主机和端口指向新集群、账号有相应权限;需要明确指定连接参数时,按实际部署补齐。不要直接在另一个终端复制执行,以免分析了旧集群。

--analyze-in-stages 分阶段建立统计,先较快提供基础统计,再逐步提高统计完整度。它仍会读取数据并增加负载,应纳入升级后的维护安排;开始执行、出现第一阶段日志,与整条任务成功结束不同。

PostgreSQL 18 的升级提示则区分缺失统计补充和后续统计更新:

vacuumdb --all --analyze-in-stages --missing-stats-only
vacuumdb --all --analyze-only

这组命令按 18 版说明使用,不要把 --missing-stats-only 原样加到旧版工具上。仍以本轮升级输出及目标版本为准,并核对每一步退出状态与错误日志。--all 覆盖范围广,不能把整集群维护写成某一张表的轻量检查。

查询慢,仍需确认是否由统计缺口造成

从失败或变慢的业务查询对应的表开始检查。下面是只读 SQL 示例,app.orders 需要替换为实际 schema 和表:

SELECT schemaname, tablename, attname, null_frac, n_distinct
FROM pg_stats
WHERE schemaname = 'app' AND tablename = 'orders';

pg_stats 的可见内容受权限等条件影响;空结果本身不能证明整张表从未分析。应结合升级日志、分析任务完成记录以及具体查询的 EXPLAIN 计划判断,比较估算行数、连接顺序和扫描方式是否异常。

诊断时先用不执行查询的 EXPLAIN 查看计划。EXPLAIN ANALYZE 会实际执行语句,涉及更新或删除时尤其需要确认测试环境和事务安排,不能当成只读查看。

统计更新结束后,再比较有代表性的相同查询、参数和负载。若计划与耗时没有改善,继续检查数据分布、索引、版本间优化器行为及其他升级后处理,不能因为刚升级就把所有慢查询归为“缺 ANALYZE”。

保留旧、新配置和升级输出,暂缓清理旧集群与备份。重新收集统计不等于完成所有升级验收,也不能用重新生成脚本来恢复旧版本的数据;数据库回退仍受本轮升级模式与新集群是否已启动等条件限制。