Skip to content

PostgreSQL 升级后配置调整

配置文件检查与更新

PostgreSQL 版本升级后,首先需要检查和更新配置文件,确保新版本能够正常运行。

配置文件结构变化

不同版本的 PostgreSQL 可能会对配置文件的结构和参数进行调整,包括:

  • 新增参数:新版本可能引入新的配置参数
  • 废弃参数:旧版本的某些参数可能被废弃
  • 默认值变化:某些参数的默认值可能发生变化
  • 参数类型变化:某些参数的类型或取值范围可能变化

配置文件检查工具

PostgreSQL 提供了 pg_upgrade 工具,在升级过程中会自动检查配置文件并提供建议:

bash
# 使用 pg_upgrade 检查配置文件
pg_upgrade --check \
  --old-datadir=/path/to/old/data \
  --new-datadir=/path/to/new/data \
  --old-bindir=/path/to/old/bin \
  --new-bindir=/path/to/new/bin

手动检查配置文件

除了使用 pg_upgrade 外,还可以手动检查配置文件:

bash
# 比较新旧版本的默认配置文件
# 查找新版本的默认配置文件
default_conf=$(find /path/to/new/bin -name "postgresql.conf.sample")

# 比较新旧配置文件
diff /path/to/old/data/postgresql.conf $default_conf > /tmp/config_diff.txt

# 查看新增和废弃的参数
cat /tmp/config_diff.txt | grep -E "^<|^>"

参数调整与优化

升级后需要根据新版本的特性和硬件环境调整配置参数,确保系统性能最优。

核心参数调整

以下是一些常见的核心参数,在升级后可能需要调整:

内存相关参数

ini
# shared_buffers:建议设置为系统内存的 25% 左右
shared_buffers = 4GB

# work_mem:每个操作的内存分配,根据并发数调整
work_mem = 64MB

# maintenance_work_mem:维护操作的内存分配
maintenance_work_mem = 512MB

# effective_cache_size:系统可用缓存的估计值,建议设置为系统内存的 75% 左右
effective_cache_size = 12GB

# wal_buffers:WAL 缓冲区大小,建议设置为 16MB 或更大
wal_buffers = 16MB

WAL 相关参数

ini
# wal_level:新版本默认值可能变化,如 PostgreSQL 10+ 默认值为 replica
wal_level = replica

# max_wal_size:WAL 文件的最大大小,建议设置为 1GB 或更大
max_wal_size = 2GB

# min_wal_size:WAL 文件的最小大小
min_wal_size = 512MB

# checkpoint_timeout:检查点超时时间,建议设置为 5 分钟
checkpoint_timeout = 5min

# checkpoint_completion_target:检查点完成目标,建议设置为 0.9
checkpoint_completion_target = 0.9

连接相关参数

ini
# max_connections:最大连接数,根据系统资源和应用需求调整
max_connections = 200

# superuser_reserved_connections:为超级用户保留的连接数
superuser_reserved_connections = 3

参数优化建议

  1. 根据硬件调整:根据服务器的 CPU、内存、磁盘等硬件配置调整参数
  2. 根据负载调整:根据应用的读写比例、并发数等负载特征调整参数
  3. 逐步调整:参数调整应逐步进行,每次只调整少量参数,观察效果
  4. 监控验证:调整后通过监控工具验证效果,确保性能提升

兼容性检查与处理

升级后需要检查系统的兼容性,确保应用程序能够正常运行。

数据库对象兼容性

sql
-- 检查无效的数据库对象
SELECT * FROM pg_stat_user_tables WHERE relkind = 'i' AND relisvalid = false;

-- 检查无效的函数
SELECT proname, proargtypes, prosrc FROM pg_proc WHERE proisagg = false AND NOT proisvalid;

-- 检查无效的触发器
SELECT tgname, tgrelid::regclass, tgfoid::regproc FROM pg_trigger WHERE NOT tgisvalid;

-- 检查无效的视图
SELECT viewname, pg_get_viewdef(viewname::regclass) FROM pg_views WHERE schemaname = 'public';

-- 重新验证所有数据库对象
REINDEX SYSTEM;
REINDEX DATABASE app_db;

应用程序兼容性

  1. 驱动程序检查:确保应用程序使用的 PostgreSQL 驱动程序支持新的 PostgreSQL 版本
  2. SQL 语法检查:检查应用程序使用的 SQL 语法是否与新版本兼容
  3. 函数和特性检查:检查应用程序使用的 PostgreSQL 函数和特性是否在新版本中有所变化
  4. 性能测试:运行应用程序的性能测试,确保升级后性能不下降

扩展兼容性

sql
-- 检查扩展版本
SELECT extname, extversion FROM pg_extension;

-- 更新扩展
ALTER EXTENSION pg_stat_statements UPDATE;
ALTER EXTENSION hstore UPDATE;
ALTER EXTENSION pgcrypto UPDATE;

-- 安装缺失的扩展
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS pg_prewarm;

-- 检查扩展兼容性
SELECT * FROM pg_available_extensions WHERE installed_version IS NOT NULL;

性能优化与调优

升级后需要进行性能优化,充分利用新版本的特性和改进。

统计信息更新

sql
-- 分析所有表,更新统计信息
ANALYZE;

-- 分析特定表
ANALYZE users;
ANALYZE orders;

-- 使用 VERBOSE 选项查看分析进度
ANALYZE VERBOSE users;

-- 为表设置更高的统计信息收集目标
ALTER TABLE users ALTER COLUMN email SET STATISTICS 1000;

索引优化

sql
-- 检查索引使用情况
SELECT
    relname AS table_name,
    indexrelname AS index_name,
    idx_scan,
    idx_tup_read,
    idx_tup_fetch,
    pg_size_pretty(pg_relation_size(indexrelid)) AS index_size
FROM pg_stat_user_indexes
ORDER BY idx_scan;

-- 重建索引,减少索引膨胀
REINDEX INDEX idx_users_email;

-- 重建表的所有索引
REINDEX TABLE users;

-- 使用 CONCURRENTLY 选项在线重建索引
REINDEX INDEX CONCURRENTLY idx_users_email;

利用新版本特性

每个 PostgreSQL 版本都会引入新的特性和优化,升级后应考虑利用这些新特性:

  • PostgreSQL 10+:声明式分区、并行查询、逻辑复制
  • PostgreSQL 11+:JIT 编译、分区表增强、存储过程支持
  • PostgreSQL 12+:哈希索引支持 WAL、分区表连接优化、JSON 路径查询
  • PostgreSQL 13+:增量排序、管道式聚合、并行 VACUUM
  • PostgreSQL 14+:预定义角色、逻辑复制增强、B-tree 索引优化

监控配置更新

升级后需要更新监控配置,确保能够监控新版本的所有关键指标。

更新监控指标

新版本可能引入新的监控指标,需要更新监控配置:

  1. 更新 PostgreSQL Exporter:确保使用支持新版本的 PostgreSQL Exporter
  2. 更新 Grafana 仪表板:添加新版本的监控指标
  3. 更新告警规则:调整告警阈值和规则
  4. 更新日志收集:适应新版本的日志格式变化

监控关键指标

以下是升级后需要重点监控的关键指标:

  • 连接数:确保连接数在合理范围内
  • 查询性能:监控慢查询和查询执行时间
  • 资源使用:CPU、内存、磁盘 I/O 使用率
  • WAL 生成:WAL 生成速率和归档状态
  • 复制状态:如果使用复制,监控复制延迟和状态
  • 锁等待:监控锁等待事件和持续时间
  • 死锁:监控死锁事件

安全配置更新

升级后需要更新安全配置,确保系统的安全性。

访问控制更新

ini
# pg_hba.conf:更新访问控制规则
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
host    replication     replicator      192.168.1.0/24          scram-sha-256

密码加密更新

ini
# password_encryption:使用更安全的加密方式,如 scram-sha-256
password_encryption = scram-sha-256

角色权限检查

sql
-- 检查超级用户
SELECT rolname FROM pg_roles WHERE rolsuper = true;

-- 检查有 CREATEDB 权限的角色
SELECT rolname FROM pg_roles WHERE rolcreatedb = true;

-- 检查有 CREATEROLE 权限的角色
SELECT rolname FROM pg_roles WHERE rolcreaterole = true;

-- 检查有 REPLICATION 权限的角色
SELECT rolname FROM pg_roles WHERE rolreplication = true;

备份与恢复配置更新

升级后需要更新备份与恢复配置,确保备份机制仍然有效。

备份策略更新

  1. 更新基础备份脚本:确保脚本兼容新版本
  2. 更新 WAL 归档配置:确保 WAL 归档仍然正常工作
  3. 测试恢复过程:验证升级后的恢复过程是否正常
  4. 更新备份保留策略:根据新版本的 WAL 生成速率调整

恢复测试

bash
#!/bin/bash
# 恢复测试脚本示例

date

echo "1. 停止测试数据库服务"
systemctl stop postgresql-test

BACKUP_DIR="/backup/postgresql/test"
DATA_DIR="/var/lib/postgresql/14/test"
WAL_ARCHIVE="/backup/wal_archive/test"
LOG_FILE="/var/log/postgresql/test/postgresql.log"

# 清理旧数据目录
echo "2. 清理旧数据目录"
mv $DATA_DIR ${DATA_DIR}_old_$(date +%Y%m%d%H%M%S) || true
mkdir -p $DATA_DIR

# 恢复基础备份
echo "3. 恢复基础备份"
cd $DATA_DIR
for file in $BACKUP_DIR/*.tar.gz; do
    echo "Extracting $file"
    tar -xzf "$file"
done

# 配置恢复环境
echo "4. 配置恢复环境"
touch $DATA_DIR/recovery.signal

cat > $DATA_DIR/postgresql.auto.conf << EOF
restore_command = 'cp $WAL_ARCHIVE/%f %p'
recovery_target = 'immediate'
recovery_target_action = 'promote'
recovery_target_timeline = 'latest'
EOF

# 设置权限
chown -R postgres:postgres $DATA_DIR
chmod 700 $DATA_DIR

# 启动测试数据库
echo "5. 启动测试数据库"
systemctl start postgresql-test

# 等待恢复完成
echo "6. 等待恢复完成"
sleep 10

# 验证恢复结果
echo "7. 验证恢复结果"
psql -h localhost -p 5433 -U postgres -c "SELECT version();"
psql -h localhost -p 5433 -U postgres -c "SELECT pg_is_in_recovery();"
psql -h localhost -p 5433 -U postgres -c "SELECT count(*) FROM pg_stat_user_tables;"

# 清理测试数据
echo "8. 清理测试数据"
systemctl stop postgresql-test
rm -rf $DATA_DIR

# 恢复原始数据
echo "9. 恢复原始数据"
mv ${DATA_DIR}_old_$(date +%Y%m%d%H%M%S) $DATA_DIR
systemctl start postgresql-test

echo "Recovery test completed at $(date)"

应用程序迁移与验证

升级后需要迁移应用程序并验证其功能。

应用程序迁移步骤

  1. 预迁移测试:在测试环境中验证应用程序兼容性
  2. 备份应用数据:在迁移前备份应用数据
  3. 停止应用程序:停止应用程序服务
  4. 更新数据库连接配置:更新应用程序的数据库连接配置
  5. 启动应用程序:启动应用程序服务
  6. 功能验证:验证应用程序的核心功能
  7. 性能测试:运行性能测试,确保性能不下降

应用程序验证内容

  1. 连接测试:验证应用程序能够正常连接到数据库
  2. 功能测试:验证应用程序的核心功能正常工作
  3. 数据完整性测试:验证数据完整性和一致性
  4. 性能测试:验证应用程序性能符合要求
  5. 并发测试:验证应用程序在并发环境下的表现

常见问题与解决方案

1. 升级后无法启动数据库

问题:数据库服务无法启动,日志中显示配置错误。

解决方案

  • 检查 postgresql.conf 文件中的参数配置,特别是新增或废弃的参数
  • 检查数据目录的权限和所有者
  • 检查日志文件中的详细错误信息

2. 应用程序连接失败

问题:应用程序无法连接到数据库,显示连接拒绝或认证失败。

解决方案

  • 检查 pg_hba.conf 文件中的访问控制规则
  • 检查数据库的 listen_addresses 参数配置
  • 检查应用程序使用的驱动程序版本
  • 检查数据库用户的密码和认证方式

3. 查询性能下降

问题:升级后查询性能明显下降。

解决方案

  • 更新统计信息,使用 ANALYZE 命令
  • 检查执行计划变化,使用 EXPLAIN ANALYZE 分析
  • 调整内存相关参数,如 work_mem、shared_buffers
  • 重建索引,减少索引膨胀

4. 扩展无法使用

问题:升级后某些扩展无法使用,显示版本不兼容。

解决方案

  • 更新扩展,使用 ALTER EXTENSION extension_name UPDATE 命令
  • 卸载并重新安装扩展
  • 检查扩展是否支持新版本

5. WAL 归档失败

问题:升级后 WAL 归档失败。

解决方案

  • 检查 archive_command 配置是否正确
  • 检查归档目录的权限和空间
  • 检查 WAL 段文件的生成和命名规则

最佳实践

1. 制定详细的升级计划

  • 提前规划升级步骤和回滚策略
  • 分配足够的时间进行升级和验证
  • 通知相关团队和用户

2. 在测试环境中充分测试

  • 在测试环境中模拟升级过程
  • 测试应用程序兼容性和性能
  • 验证备份和恢复过程

3. 逐步升级

  • 对于跨多个大版本的升级,建议逐步升级
  • 每次升级后充分测试,确保稳定

4. 监控和调整

  • 升级后密切监控系统性能和状态
  • 根据监控结果调整配置参数
  • 及时解决出现的问题

5. 文档更新

  • 更新系统文档,记录升级过程和配置变化
  • 记录遇到的问题和解决方案
  • 更新应用程序连接配置文档

常见问题(FAQ)

Q1: 升级后需要重新编译扩展吗?

A1: 是的,升级后通常需要重新编译或更新扩展,因为扩展可能依赖于特定版本的 PostgreSQL 内部结构。可以使用 ALTER EXTENSION extension_name UPDATE 命令更新扩展,或者卸载并重新安装扩展。

Q2: 升级后如何处理废弃的参数?

A2: 对于废弃的参数,应该从配置文件中移除,并使用替代参数。PostgreSQL 通常会在日志中警告使用废弃参数,建议根据警告信息调整配置。

Q3: 升级后如何验证数据完整性?

A3: 可以通过以下方法验证数据完整性:

  1. 执行数据库完整性检查
  2. 验证关键表的数据量和内容
  3. 运行应用程序的功能测试
  4. 执行查询验证数据关系
sql
-- 执行数据库完整性检查
SELECT pg_stat_get_db_corruption_stats();

-- 验证关键表的数据量
SELECT count(*) FROM critical_table;

-- 验证数据关系
SELECT count(*) FROM table1 t1 JOIN table2 t2 ON t1.id = t2.table1_id;

Q4: 升级后如何优化性能?

A4: 升级后优化性能的方法包括:

  1. 更新统计信息,使用 ANALYZE 命令
  2. 调整内存相关参数,如 shared_buffers、work_mem
  3. 重建索引,减少索引膨胀
  4. 利用新版本的特性,如并行查询、JIT 编译等
  5. 调整 WAL 相关参数,如 checkpoint_completion_target

Q5: 升级后如何回滚?

A5: 如果升级过程中出现问题,需要回滚到旧版本,可以按照以下步骤操作:

  1. 停止新版本的数据库服务
  2. 恢复旧版本的数据目录(如果在升级前备份了)
  3. 启动旧版本的数据库服务
  4. 恢复旧版本的配置文件
  5. 验证旧版本的功能

因此,在升级前一定要备份旧版本的数据目录和配置文件,以便在需要时能够快速回滚。

Q6: 升级后如何监控系统状态?

A6: 升级后监控系统状态的方法包括:

  1. 使用 PostgreSQL 的内置统计视图,如 pg_stat_activity、pg_stat_database
  2. 使用命令行工具,如 pg_top、pg_stat
  3. 使用第三方监控工具,如 Prometheus + Grafana
  4. 配置日志收集和分析,如 ELK Stack
  5. 设置告警规则,及时发现异常情况

建议建立全面的监控体系,覆盖系统的各个层面,确保能够及时发现和解决问题。