开发者
资源
【openGauss实战】从PostgreSQL迁到openGauss,踩坑半年的经验总结
【openGauss实战】从PostgreSQL迁到openGauss,踩坑半年的经验总结
原创
发表于06/17
2880

【openGauss实战】从PostgreSQL迁到openGauss,踩坑半年的经验总结

【openGauss 实战】从 PostgreSQL 迁到 openGauss,踩坑半年的经验总结

发布版块:鲲鹏社区 - openGauss 版块 适配版本:openGauss 5.0.0 + 鲲鹏 920 部署规模:一主两备生产集群

前言

最开始的时候信心满满,觉得不就是个 PostgreSQL 的分支嘛,能有多大区别?结果真正上手才发现,两者的差异比想象中大得多 —— 很多 PG 能用的参数、语法、插件,在 openGauss 里要么不支持,要么行为完全不一样。有的问题查了好几天才找到根因,有的性能调优前后差了好几倍。

今天把这半年的经验全部整理出来,都是生产环境验证过的干货。希望能给后面要做迁移的兄弟们避避坑,少走点弯路。


一、先说说为什么选 openGauss + 鲲鹏

选型的时候我们也对比了好几个国产数据库,最后选 openGauss 主要是三个原因:

第一,PG 生态兼容性最好。大部分 PostgreSQL 的语法、函数、数据类型都能直接用,迁移成本相对最低。业务代码改动量大概在 5% 左右,比其他数据库小很多。

第二,性能确实强。尤其是在鲲鹏平台上,针对 ARM 架构做了深度优化。同样的硬件,TPCH 测试性能比 PG 14 高了 30% 以上,复杂查询性能提升更明显。

第三,高可用和安全特性完善。原生支持一主多备、自动故障切换、全密态加密这些企业级特性,不用像 PG 那样自己折腾 Patroni、pgpool 这些第三方组件。

当然,坑也不少。下面进入正题。


二、迁移前准备:第一个坑就差点劝退

2.1 版本选择千万别乱选

这是第一个,也是最大的坑。

最开始图新鲜,用了最新的开发版,结果各种 bug—— 主备切换失败、内存泄漏、执行计划异常。折腾了快两周,最后还是退回了 5.0.0 企业版,世界终于清净了。

给大家一个建议:

  • 生产环境老老实实用人最多的稳定版,别追新
  • 每个大版本的第一个小版本尽量别用,等出了补丁包再上
  • 升级前一定要在测试环境跑至少一周的压力测试

我们现在用的是 5.0.0 加最新的补丁包,跑了三个多月没出过什么大问题。

2.2 兼容性评估一定要做细

别觉得 PG 能跑的 SQL openGauss 就一定能跑,一定要用官方的兼容性工具扫一遍。我们遇到的不兼容点:

  1. 部分窗口函数行为不一致:特别是 rank ()、dense_rank () 在处理 NULL 值的时候
  2. 部分系统表字段名不一样:比如 pg_stat_activity 里的字段名有变化
  3. 存储过程语法差异:openGauss 的 PL/pgSQL 和 PG 不完全兼容,特别是异常处理部分
  4. 部分扩展不支持:像 pg_stat_statements 虽然有,但功能少了很多
  5. 参数名不一样:很多 PG 的参数在 openGauss 里改名了,或者默认值变了

我们最开始没做仔细的兼容性评估,结果上线前才发现十几个存储过程跑不起来,连夜改代码,差点延期。

血泪教训:兼容性评估一定要做细,每条 SQL、每个存储过程都要测到。


三、安装部署:这些配置一定要改

3.1 操作系统参数调优

openGauss 对系统参数要求很高,默认参数根本跑不起来。这些必须改:

# 文件句柄数
echo "* soft nofile 1024000" >> /etc/security/limits.conf
echo "* hard nofile 1024000" >> /etc/security/limits.conf

# 进程数
echo "* soft nproc unlimited" >> /etc/security/limits.conf
echo "* hard nproc unlimited" >> /etc/security/limits.conf

# 内存参数
echo "vm.swappiness = 1" >> /etc/sysctl.conf
echo "vm.dirty_ratio = 15" >> /etc/sysctl.conf
echo "vm.dirty_background_ratio = 5" >> /etc/sysctl.conf
echo "vm.overcommit_memory = 0" >> /etc/sysctl.conf

# 网络参数
echo "net.ipv4.tcp_max_syn_backlog = 65535" >> /etc/sysctl.conf
echo "net.core.somaxconn = 65535" >> /etc/sysctl.conf
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf

特别是 swappiness,一定要设成 1,不要设 0。我们最开始设成 0,结果数据库在内存使用率高的时候直接被 OOM killer 杀掉了。

3.2 文件系统一定要用 XFS

openGauss 官方推荐用 XFS,不要用 ext4。我们对比过:

  • XFS 的顺序写入性能比 ext4 高 20% 左右
  • 大文件操作时 XFS 更稳定,不会出现 ext4 的 IO 卡顿
  • XFS 支持动态 inode 分配,小文件场景性能更好

格式化的时候一定要加这些参数:

mkfs.xfs -f -d agcount=32 -l size=128m -i size=512 /dev/sdb

挂载参数:

/dev/sdb /data xfs defaults,noatime,nodiratime,allocsize=64m 0 0

3.3 一个巨坑:磁盘预读

鲲鹏服务器默认的磁盘预读值太小,对数据库性能影响很大。一定要改大:

# 临时生效
blockdev --setra 16384 /dev/sdb

# 永久生效,写到/etc/rc.local
echo "blockdev --setra 16384 /dev/sdb" >> /etc/rc.local

我们改完这个参数之后,随机查询性能直接提升了 40%,这个坑 90% 的人都会踩。


四、关键参数配置:90% 的性能问题都在这里

openGauss 的默认参数非常保守,不优化的话性能可能只有优化后的三分之一。这些是我们实测下来的最佳配置:

4.1 内存相关参数

# 共享内存,建议设为物理内存的50%-70%
shared_buffers = 128GB

# 工作内存,根据并发数调整,不要设太大
work_mem = 64MB

# 维护工作内存,建索引、VACUUM用
maintenance_work_mem = 2GB

# 有效缓存大小,建议设为物理内存的80%
effective_cache_size = 200GB

#  WAL缓冲区
wal_buffers = 64MB

这里有个大坑:work_mem 千万不要设太大。我们最开始图性能设成了 256MB,结果高并发的时候,几十个查询同时跑,内存直接爆了,数据库 OOM 重启。

4.2 Checkpoint 相关参数

# Checkpoint超时时间,建议30分钟
checkpoint_timeout = 30min

# 最大WAL大小
max_wal_size = 64GB
min_wal_size = 16GB

# Checkpoint完成目标时间,建议0.9
checkpoint_completion_target = 0.9

openGauss 默认的 checkpoint_timeout 是 5 分钟,太频繁了,会导致大量的随机写。改成 30 分钟之后,写入性能提升了 50%,IO 毛刺也少了很多。

4.3 性能优化开关

# 开启向量化执行,必开!
enable_vectorized_engine = on

# 开启自适应查询优化
enable_adaptive_executor = on

# 开启JIT编译,复杂查询有用
enable_jit = on

# 开启批量嵌套循环
enable_batch_nestloop = on

# 开启哈希连接优化
enable_hashjoin = on

重点说一下向量化执行,这个是 openGauss 的大杀器。开启之后,多表关联、聚合查询这类 OLAP 场景的性能能提升好几倍。我们有个复杂的报表查询,原来要跑 80 多秒,开了向量化之后 12 秒就出结果了。


五、性能调优:从慢如蜗牛到健步如飞

5.1 执行计划的坑

openGauss 的优化器和 PG 不一样,同样的 SQL 可能生成完全不同的执行计划。我们遇到最多的问题:

  1. 统计信息不准:openGauss 的自动统计信息收集阈值比 PG 高,大表经常统计信息过期,导致执行计划选错。

解决方案:

-- 手动收集统计信息
ANALYZE VERBOSE 表名;

-- 调小自动收集阈值
ALTER TABLE 表名 SET (autovacuum_analyze_scale_factor = 0.05);
  1. 选错连接方式:经常把小表的哈希连接改成嵌套循环,性能差 100 倍。

临时解决方案:

-- 强制用哈希连接
SET enable_nestloop = off;

永久解决方案:收集准确的统计信息。

5.2 索引优化

openGauss 的索引和 PG 基本兼容,但有几个注意点:

  1. 不要建太多索引:openGauss 的写入放大比 PG 严重,索引太多写入性能下降很明显
  2. 分区表一定要建本地索引:不要建全局索引,维护成本太高
  3. 高频更新的字段不要建索引:索引膨胀会非常快

5.3 分区表最佳实践

openGauss 的分区表功能比 PG 强很多,但也有坑:

  1. 一定要用间隔分区:自动创建分区,不用自己写脚本
  2. 分区不要太多:单表分区数不要超过一千,太多了元数据操作会很慢
  3. 定期归档老分区:冷数据挪到别的表空间,不要和热数据放一起

我们有张日志表,每天一个分区,存了三年的数据,查询最近一天的日志要 30 多秒。后来把一年前的分区全部归档到另外的表空间,查询速度降到了 200 毫秒以内。


六、高可用配置:这些坑会让你欲哭无泪

6.1 主备同步的坑

openGauss 的主备同步默认是异步的,要开同步复制需要改参数:

# 同步复制
synchronous_commit = on
synchronous_standby_names = 'ANY 1 (备机1,备机2)'

这里有个巨坑:如果所有备机都挂了,主机也会挂起! 因为要等备机确认,但没有备机可以确认。

解决方案:用 'ANY 1' 而不是 'FIRST 1',并且至少配置两台备机。

6.2 自动故障切换

openGauss 原生支持自动故障切换,不用第三方组件,但配置要注意:

# 开启自动故障切换
enable_force_auto_failover = on

# 故障检测超时时间
recovery_time_target = 30s

# 备机升主延迟
primary_lsn_delay = 100MB

我们最开始 recovery_time_target 设的是 10 秒,结果网络一抖动就触发主备切换,业务频繁中断。改成 30 秒之后就稳定了。

6.3 备份恢复

openGauss 的备份工具 gs_probackup 比 PG 的 pg_basebackup 好用太多,但有几个注意点:

  1. 一定要开增量备份:全量备份太占空间了
  2. 定期做恢复测试:备份能不能用,恢复一次才知道
  3. 备份保留策略:不要留太多备份,够恢复就行

我们现在的策略:每天一次增量备份,每周一次全量备份,保留最近四周的备份。


七、我们踩过的十大坑总结

最后给大家总结一下最高频的十个坑,遇到了直接对照解决:

  1. 数据库突然变慢,IO 很高

    • 检查是不是在做 checkpoint
    • 检查统计信息是不是过期了
    • 检查是不是有慢 SQL 在跑
  2. 主备同步延迟大

    • 检查网络带宽够不够
    • 检查备机的 IO 性能
    • 大事务拆成小事务,不要一次性提交太多数据
  3. 连接数占满,连不上数据库

    • 检查应用有没有连接泄漏
    • 检查是不是有长事务持有连接
    • 调大 max_connections,但不要超过 1000
  4. 内存占用持续上涨,最后 OOM

    • work_mem 设太大了,调小
    • 检查是不是有内存泄漏的 SQL
    • 开启内存保护机制
  5. VACUUM 跑几个小时都完不成

    • 大表分批次 VACUUM
    • 调大 maintenance_work_mem
    • 业务低峰期做
  6. 同样的 SQL,有时候快有时候慢

    • 统计信息过期了,重新 ANALYZE
    • 执行计划不稳定,绑定执行计划
    • 检查是不是有锁等待
  7. 插入性能越来越差

    • 索引太多了,删掉没用的索引
    • 表膨胀了,VACUUM FULL 或者 CLUSTER
    • 批量插入,不要单条插
  8. 主备切换后应用连不上

    • 检查 VIP 有没有飘过去
    • 检查防火墙有没有开
    • 应用要有重连机制
  9. 升级后性能下降

    • 重新收集所有表的统计信息
    • 检查参数有没有被重置
    • 对比执行计划有没有变化
  10. 删了大表磁盘空间没释放

    • 要等 VACUUM 完成才会释放
    • 或者直接 TRUNCATE,不要 DELETE
    • 大表直接 DROP,不要删数据

八、最后说几句心里话

迁完这几个核心系统,最大的感受就是:openGauss 确实是目前最成熟、性能最好的国产关系型数据库,尤其是在鲲鹏平台上,性能完全可以替代 PG,甚至在很多场景下更好。

但它毕竟不是 PG,很多细节上的差异,不真正踩过坑是体会不到的。不要想当然地用 PG 的经验来运维 openGauss,那样一定会踩坑。

当然,openGauss 也不是完美的。文档不够详细,很多参数没有说明;小 bug 还是不少,需要经常打补丁;生态和 PG 比还是有差距。但总的来说,对于信创改造来说,openGauss 是目前最好的选择,没有之一。

国产化这条路不好走,但总得有人先走。我们把坑踩了,把经验分享出来,后面的人就能走得更顺一点。

如果大家在使用 openGauss 的过程中有什么问题,欢迎在评论区留言,我会尽量解答。也欢迎大家分享自己的经验,一起把 openGauss 的生态做起来。

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞