Skip to content

PostgreSQL 升级后验证

PostgreSQL 升级完成后,必须进行全面的验证,以确保数据库系统的正常运行、数据完整性、性能表现和安全可靠性。本文将详细介绍 PostgreSQL 升级后的验证步骤、方法和最佳实践。

验证前准备

验证计划制定

  • 明确验证范围:确定需要验证的功能、模块和性能指标
  • 制定验证用例:编写详细的验证用例,包括输入、预期输出和验证方法
  • 准备验证工具:准备好所需的验证工具,如 psql、pgAdmin、监控工具等
  • 安排验证人员:确定负责各个验证环节的人员及其职责
  • 设定验证时间:合理安排验证时间,确保在业务低峰期完成验证

验证环境准备

  • 隔离测试环境:如果可能,在隔离的测试环境中先进行验证
  • 备份验证数据:验证前对升级后的数据库进行备份,以便出现问题时恢复
  • 准备测试数据:准备好用于验证的测试数据,包括正常数据和边界数据
  • 配置监控系统:确保监控系统正常运行,能够实时监控验证过程

基本功能验证

服务状态验证

  • 检查数据库进程

    bash
    ps aux | grep postgres
  • 检查服务状态

    bash
    # PostgreSQL 10+
    pg_ctl -D /path/to/data status
    
    # 系统服务方式
    systemctl status postgresql@15-main
  • 验证版本信息

    sql
    SELECT version();
    -- 预期输出应显示目标 PostgreSQL 版本

连接验证

  • 本地连接验证

    bash
    psql -h localhost -p 5432 -U postgres -c "SELECT 1;"
  • 远程连接验证

    bash
    psql -h <remote_host> -p 5432 -U postgres -c "SELECT 1;"
  • 应用连接验证

    • 使用应用程序自带的连接测试工具
    • 执行简单的应用操作,验证连接是否正常

核心功能验证

  • 数据库创建与删除

    sql
    CREATE DATABASE test_db;
    DROP DATABASE test_db;
  • 表创建与数据操作

    sql
    CREATE TABLE test_table (id serial PRIMARY KEY, name varchar(50));
    INSERT INTO test_table (name) VALUES ('test');
    UPDATE test_table SET name = 'updated' WHERE id = 1;
    DELETE FROM test_table WHERE id = 1;
    DROP TABLE test_table;
  • 索引功能验证

    sql
    CREATE TABLE test_index (id serial PRIMARY KEY, name varchar(50));
    CREATE INDEX idx_test_name ON test_index(name);
    INSERT INTO test_index (name) VALUES ('test1'), ('test2');
    SELECT * FROM test_index WHERE name = 'test1';
    DROP TABLE test_index;
  • 事务功能验证

    sql
    BEGIN;
    CREATE TABLE test_transaction (id serial PRIMARY KEY, value int);
    INSERT INTO test_transaction (value) VALUES (100);
    ROLLBACK;
    
    -- 验证表是否被回滚
    SELECT * FROM pg_tables WHERE tablename = 'test_transaction';

数据完整性验证

数据量验证

  • 数据库数量验证

    sql
    SELECT COUNT(*) FROM pg_database;
    -- 与升级前的数据库数量对比
  • 表数量验证

    sql
    -- 统计所有数据库中的表数量
    SELECT datname, COUNT(*) AS table_count
    FROM pg_stat_user_tables
    JOIN pg_database ON pg_stat_user_tables.datid = pg_database.oid
    GROUP BY datname;
    -- 与升级前的表数量对比
  • 数据行数量验证

    sql
    -- 对关键表进行行数验证
    SELECT COUNT(*) FROM important_table;
    -- 与升级前的行数对比

数据内容验证

  • 随机抽样验证

    sql
    -- 对关键表进行随机抽样检查
    SELECT * FROM important_table TABLESAMPLE SYSTEM(0.1);
    -- 手动检查抽样数据是否正确
  • 校验和验证

    sql
    -- 启用数据页校验和(如果未启用)
    -- 注意:启用校验和需要重启数据库
    ALTER SYSTEM SET data_checksums = on;
    
    -- 运行校验和检查
    -- 注意:此命令会锁定表
    SELECT pg_checksum_verify('important_table'::regclass);
  • 主键唯一性验证

    sql
    -- 检查主键是否唯一
    SELECT id, COUNT(*) 
    FROM important_table 
    GROUP BY id 
    HAVING COUNT(*) > 1;
    -- 预期结果应为空

约束与索引验证

  • 检查约束完整性

    sql
    -- 检查所有表的约束
    SELECT conrelid::regclass AS table_name, conname, contype
    FROM pg_constraint
    WHERE conrelid IN (SELECT oid FROM pg_class WHERE relnamespace = 'public'::regnamespace);
    -- 与升级前的约束对比
  • 检查索引状态

    sql
    -- 检查所有索引的状态
    SELECT indexrelid::regclass AS index_name, indrelid::regclass AS table_name, indisvalid
    FROM pg_index
    WHERE indrelid IN (SELECT oid FROM pg_class WHERE relnamespace = 'public'::regnamespace);
    -- 确保所有索引的 indisvalid 为 true
  • 验证外键约束

    sql
    -- 检查外键约束是否有效
    SELECT conname, conrelid::regclass AS table_name, confrelid::regclass AS ref_table
    FROM pg_constraint
    WHERE contype = 'f' AND conrelid IN (SELECT oid FROM pg_class WHERE relnamespace = 'public'::regnamespace);

性能验证

基准性能测试

  • 运行 pgbench 测试

    bash
    # 初始化测试数据库
    pgbench -i -s 10 testdb
    
    # 运行基准测试
    pgbench -c 10 -j 2 -t 1000 testdb
  • 与升级前性能对比

    • 记录升级后的 tps(每秒事务数)和延迟
    • 与升级前的基准测试结果对比,确保性能没有明显下降

查询性能验证

  • 运行关键查询

    sql
    -- 执行升级前确定的关键查询
    EXPLAIN ANALYZE SELECT * FROM important_table WHERE condition;
  • 检查执行计划

    • 对比升级前后的执行计划,确保没有出现性能退化
    • 检查是否有新的索引被使用或未被使用
  • 分析慢查询日志

    bash
    tail -f /path/to/log/postgresql-slow.log
    • 检查是否有新的慢查询出现
    • 分析慢查询的原因,如缺少索引、统计信息过期等

系统资源使用验证

  • CPU 使用情况

    bash
    top -p $(pgrep -o postgres)
  • 内存使用情况

    bash
    free -h
  • 磁盘 I/O 情况

    bash
    iostat -xm 1
  • 网络使用情况

    bash
    netstat -i

安全验证

访问控制验证

  • 检查 pg_hba.conf 配置

    bash
    cat /path/to/data/pg_hba.conf
    • 确保访问控制规则正确配置
    • 验证不同用户、IP地址的访问权限
  • 检查用户权限

    sql
    -- 检查用户权限
    SELECT usename, usecreatedb, usesuper, userepl, usebypassrls
    FROM pg_user;
    
    -- 检查对象权限
    SELECT grantee, table_name, privilege_type
    FROM information_schema.role_table_grants
    WHERE table_schema = 'public';

安全配置验证

  • 检查安全相关参数

    sql
    SHOW ssl;
    SHOW ssl_cert_file;
    SHOW ssl_key_file;
    SHOW password_encryption;
    SHOW log_connections;
    SHOW log_disconnections;
  • 验证 SSL 配置

    bash
    openssl s_client -connect localhost:5432 -starttls postgres

审计日志验证

  • 检查审计日志配置

    sql
    SHOW log_statement;
    SHOW log_min_duration_statement;
  • 验证审计日志生成

    bash
    tail -f /path/to/log/postgresql.log | grep -i "statement"

应用兼容性验证

应用功能验证

  • 核心业务功能测试

    • 运行应用程序的核心业务功能,验证其正常运行
    • 测试数据的增删改查操作
    • 测试事务处理和并发操作
  • 应用接口验证

    • 测试应用程序与数据库的接口调用
    • 验证 API 响应时间和正确性

应用性能验证

  • 负载测试

    • 使用负载测试工具模拟真实业务负载
    • 监控应用程序的响应时间和吞吐量
    • 检查数据库的资源使用情况
  • 并发测试

    • 模拟多个用户同时访问应用程序
    • 验证并发操作的正确性和性能

监控系统验证

内置监控验证

  • 检查统计视图

    sql
    -- 检查连接数
    SELECT * FROM pg_stat_activity;
    
    -- 检查锁情况
    SELECT * FROM pg_locks;
    
    -- 检查表统计信息
    SELECT * FROM pg_stat_user_tables;
    
    -- 检查索引统计信息
    SELECT * FROM pg_stat_user_indexes;
  • 检查 pg_stat_statements 扩展

    sql
    -- 确保扩展已安装
    CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
    
    -- 检查扩展功能
    SELECT * FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;

外部监控验证

  • 检查监控系统连接

    • 确保监控系统能够正常连接到升级后的数据库
    • 验证监控指标的收集情况
  • 检查告警配置

    • 验证告警规则是否正常触发
    • 测试告警通知是否正常发送
  • 检查性能仪表盘

    • 验证性能仪表盘显示的数据是否准确
    • 检查是否有异常指标

不同版本的验证重点

PostgreSQL 9.x 升级到 10+ 验证重点

  • 检查新的数据类型:如 identity 列、jsonb 增强等
  • 验证分区表功能:10+ 版本引入了原生分区表
  • 检查逻辑复制功能:10+ 版本支持逻辑复制
  • 验证并行查询:10+ 版本支持并行查询

PostgreSQL 10+ 升级到 12+ 验证重点

  • 检查默认值变更:wal_level 默认值从 minimal 改为 replica
  • 验证物化视图刷新选项:12+ 版本支持并发刷新
  • 检查查询优化器增强:如增量排序、增强的统计信息等
  • 验证新增的系统视图:如 pg_stat_wal、pg_stat_replication_slots 等

PostgreSQL 12+ 升级到 14+ 验证重点

  • 检查新增的数据类型:如 range 类型增强、multirange 类型
  • 验证新增的索引类型:如 BRIN 索引增强、增量排序
  • 检查性能增强:如 JIT 编译增强、并行查询增强
  • 验证新增的管理功能:如 pg_checksums 工具、增强的日志记录等

验证最佳实践

1. 分阶段验证

  • 基础验证:先进行基本功能和服务状态验证
  • 核心验证:然后进行数据完整性和核心业务功能验证
  • 深度验证:最后进行性能、安全和应用兼容性验证

2. 自动化验证

  • 编写验证脚本:将验证步骤编写为脚本,实现自动化验证
  • 使用 CI/CD 工具:集成到 CI/CD 流程中,自动执行验证
  • 利用监控系统:通过监控系统自动收集和分析验证数据

3. 全面覆盖

  • 覆盖所有功能:确保验证覆盖数据库的所有核心功能
  • 覆盖所有场景:包括正常场景、边界场景和异常场景
  • 覆盖所有模块:验证所有业务模块和系统模块

4. 持续监控

  • 验证后持续监控:验证完成后,持续监控数据库运行状态
  • 定期回顾:定期回顾监控数据,确保数据库长期稳定运行
  • 及时调整:根据监控数据,及时调整数据库配置和优化

5. 文档记录

  • 记录验证过程:详细记录验证的每一步操作和结果
  • 记录问题和解决方案:记录验证过程中发现的问题和解决方案
  • 更新验证计划:根据验证结果,更新验证计划和用例

案例分析

案例1:升级后数据完整性问题

背景:从 PostgreSQL 11 升级到 13 后,验证发现某张表的数据行数比升级前少。

验证过程

  1. 运行数据量验证脚本,发现 important_table 的行数比升级前少 100 行
  2. 检查升级日志,发现升级过程中有警告信息
  3. 检查表的约束和索引,发现一个唯一约束失效
  4. 分析原因:升级过程中,由于唯一约束冲突,部分数据未被正确迁移

解决方案

  • 从备份中恢复缺失的数据
  • 修复唯一约束
  • 重新运行数据验证

案例2:升级后性能下降

背景:从 PostgreSQL 12 升级到 14 后,应用程序响应时间明显增加。

验证过程

  1. 运行 pgbench 基准测试,发现 tps 下降了 30%
  2. 检查执行计划,发现多个关键查询的执行计划发生了变化
  3. 检查统计信息,发现统计信息过期
  4. 分析原因:升级后统计信息未更新,导致查询优化器生成了低效的执行计划

解决方案

  • 运行 ANALYZE 更新统计信息
  • 重新生成执行计划
  • 再次运行性能验证,确认性能恢复正常

总结

PostgreSQL 升级后的验证是确保升级成功的关键环节,必须进行全面、深入的验证。验证内容包括基本功能验证、数据完整性验证、性能验证、安全验证和应用兼容性验证。通过分阶段验证、自动化验证和持续监控,可以确保数据库系统的正常运行和长期稳定。

在验证过程中,要注意不同 PostgreSQL 版本的验证重点,制定详细的验证计划和用例,记录验证过程和结果。通过全面的验证,可以及时发现和解决升级过程中出现的问题,确保数据库系统的安全性、可靠性和性能表现。

通过本文的介绍,希望能帮助 DBA 们掌握 PostgreSQL 升级后的验证方法和最佳实践,确保升级工作的成功完成。