华为云鲲鹏+openGauss性能调优:15个关键参数让TPS翻倍
🔧 华为云鲲鹏+openGauss性能调优:15个关键参数让TPS翻倍
📝 文章摘要:同样的 openGauss,默认参数下跑在鲲鹏服务器上甚至不如 MySQL 5.7,但经过正确调优后复杂查询性能提升 60%+。本文基于实际生产环境的压测数据,总结了 15 个最关键的性能调优参数(NUMA 绑核、大页配置、WAL 优化、并行度设置等),每个参数都给出了推荐值、原理说明和调优前后的对比数据。这是一份可以直接抄的调优作业。
⏱ 预计阅读时间:16 分钟(全文约 4,500 字)
🎯 背景:默认参数跑不出鲲鹏的潜力
openGauss 默认参数是为通用 x86 服务器设计的,装到鲲鹏(ARM64)上后,默认配置大约只能发挥 40% 的性能。
我们在第一次压测中,openGauss 默认配置跑了 Sysbench OLTP 读写测试:
| 指标 | MySQL 5.7(x86) | openGauss 默认(鲲鹏) | 差距 |
|---|---|---|---|
| TPS | 8,500 | 5,200 | -39% |
| QPS | 32,000 | 21,000 | -34% |
| P99 延迟(写入) | 45ms | 68ms | +51% |
这个结果让团队有点慌 —— 说好的国产数据库超越 MySQL 呢?
经过两周的参数调优和鲲鹏亲和优化,最终结果是这样的:
| 指标 | MySQL 5.7(x86) | openGauss 调优后(鲲鹏) | 提升 |
|---|---|---|---|
| TPS | 8,500 | 9,800 | +15% |
| QPS | 32,000 | 52,000 | +63% |
| P99 延迟(写入) | 45ms | 38ms | -16% |
下面把这 15 个参数分成 5 类,逐个拆解。
一、内存参数(4 个)

1. shared_buffers — 共享缓冲区
# 默认:32MB → 调优:8GB(物理内存的 25%)
shared_buffers = 8GB
原理:openGauss 的数据读写首先要经过 shared_buffers,太小会导致频繁的磁盘 I/O。在鲲鹏上,建议设为物理内存的 25%,比 PostgreSQL 的推荐值(25%)相同,但不建议超过 32GB(再大收益递减)。
调优前后对比:
# 默认 32MB
pgbench -c 64 -j 8 -T 300 -P 5
# tps = 5200
# 调优 8GB
pgbench -c 64 -j 8 -T 300 -P 5
# tps = 7800 ↑ 50%
2. work_mem — 会话工作内存
# 默认:4MB → 调优:32MB ~ 128MB(按连接数调整)
work_mem = 64MB
原理:每个查询的排序、哈希操作都会用这个内存。调太大了可能导致 OOM(2000 连接 × 64MB = 128GB),调太小了排序走磁盘。
计算公式:work_mem = (物理内存 × 10%) / max_connections
我们连接数 400 左右,64MB 够用。如果你连接数超过 1000,建议降到 16MB 以下。
3. maintenance_work_mem — 维护工作内存
# 默认:64MB → 调优:2GB
maintenance_work_mem = 2GB
VACUUM、CREATE INDEX、ALTER TABLE ADD FOREIGN KEY 等维护操作会用这个参数。调大后 VACUUM 速度快 3-4 倍,对鲲鹏这种多核架构尤其明显。
4. wal_buffers — WAL 缓冲区
# 默认:512KB → 调优:64MB
wal_buffers = 64MB
WAL 写满后会触发刷盘,太小导致频繁 fsync。在鲲鹏上,大 WAL buffer + 大事务写入场景下性能提升显著。
二、NUMA 亲和参数(3 个)
5. numa_distribute_mode
# 默认:none → 调优:all
numa_distribute_mode = 'all'
这是 openGauss 在鲲鹏上最重要的参数,没有之一。
鲲鹏处理器是 NUMA(Non-Uniform Memory Access)架构,CPU 访问本地内存快,访问远端内存慢。默认情况下,openGauss 不知道 NUMA 拓扑,所有内存分配都在一个 NUMA 节点上。
开启后,openGauss 会把内存和线程均匀分布到所有 NUMA 节点上:
# 查看 NUMA 拓扑
numactl --hardware
# available: 4 nodes (0-3)
# node 0 cpus: 0-15
# node 0 size: 16384 MB
# node 1 cpus: 16-31
# node 1 size: 16384 MB
# 调优后性能提升
# TPS: 7800 → 9200 ↑ 18%
6. enable_nestloop
# 默认:on → 调优:off
enable_nestloop = off
原理:嵌套循环连接(Nest Loop)适合小表驱动大表,但鲲鹏上的优化器统计信息不准时容易选错。关掉后强制走 Hash Join,对 OLTP 场景更友好。
-- 调优前(nestloop 生效)
EXPLAIN
(ANALYZE, BUFFERS)
SELECT *
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE u.status = 'active';
-- 执行计划:Nest Loop (cost=... rows=... actual time=0.035..523.456)
-- 逐行扫描,耗时 523ms
-- 调优后(nestloop 关闭)
-- 执行计划:Hash Join (cost=... rows=... actual time=0.035..12.345)
-- 哈希匹配,耗时 12ms
7. enable_seqscan
# 默认:on → 调优:off
enable_seqscan = off
风险提示:这个参数是把双刃剑。关掉后强制走索引扫描,对 OLTP 是好事,但如果表没有合适的索引,反而更慢。建议先关掉,如果发现慢查询再单独加索引。
-- 检查是否有全表扫描
SELECT query, calls, total_time / calls AS avg_ms
FROM pg_stat_statements
WHERE query LIKE '%Seq Scan%'
ORDER BY avg_ms DESC LIMIT 10;
三、WAL 与写入优化(3 个)
8. checkpoint_timeout & max_wal_size
# 默认:checkpoint_timeout = 5min, max_wal_size = 1GB
# 调优:checkpoint_timeout = 15min, max_wal_size = 64GB
checkpoint_timeout = 15min
max_wal_size = 64GB
原因:checkpoint 触发的瞬间大量脏页写盘,导致性能抖动。拉大间隔后:
# 调优前,每 5 分钟一次 200ms 的延迟尖刺
# 调优后,15 分钟一次,延迟尖刺降低到 80ms
需要确保磁盘有足够空间(max_wal_size × 2 用于 WAL 轮转)。
9. commit_delay
# 默认:0 → 调优:100(微秒)
commit_delay = 100
commit_siblings = 5
原理:让事务提交时等待最多 100 微秒,攒够一批后再一起刷盘。对高并发写入场景(如订单创建)效果明显:
# commit_delay = 0:TPS = 9200
# commit_delay = 100:TPS = 9800 ↑ 6.5%
10. wal_compression
# 默认:off → 调优:on
wal_compression = on
压缩 WAL 日志可以减少 I/O 量,CPU 开销很小(鲲鹏上有硬件压缩加速)。我们实测 WAL 写入量减少约 40%。
四、查询并行度参数(3 个)
11. query_dop
# 默认:1 → 调优:2 ~ 4(按 CPU 核数)
query_dop = 2
这是 openGauss 专有参数,控制查询并行度。鲲鹏 64 核以上建议设为 4,32 核建议 2。
# query_dop = 1:复杂查询 2.8s
# query_dop = 2:复杂查询 1.6s ↑ 43%
# query_dop = 4:复杂查询 1.1s ↑ 61%(64 核场景)
12. parallel_tuple_cost & parallel_setup_cost
# 调优:降低并行开销,让优化器更倾向于选择并行执行计划
parallel_tuple_cost = 0.01 # 默认 0.1
parallel_setup_cost = 100 # 默认 1000
这两个参数告诉优化器"并行执行的开销没那么大"。调低后,优化器会更积极地选择并行计划。
13. effective_cache_size
# 默认:4GB → 调优:24GB(物理内存的 75%)
effective_cache_size = 24GB
这个参数不是真的分配内存,而是告诉优化器"系统有多少缓存可以用来做索引扫描评估"。值越大,优化器越倾向于走索引扫描。
五、操作系统级参数(2 个)
14. Huge Pages(大页)
# 查看当前大页配置
cat /proc/meminfo | grep HugePages
# 配置大页(以 2MB 大页为例,分配 4096 个 = 8GB)
echo 4096 > /proc/sys/vm/nr_hugepages
# openEuler 上持久化配置
echo 'vm.nr_hugepages=4096' >> /etc/sysctl.conf
sysctl -p
# 配置 openGauss 使用大页
# postgresql.conf
huge_pages = on # 默认 try,改为 on 强制使用
大页为什么重要:默认 4KB 小页,TLB(页表缓存)覆盖率低。大页(2MB)减少了页表项数量,TLB 命中率大幅提升。在鲲鹏上,大页带来的性能提升比 x86 更明显。
# 大页开启前后对比
# 小页:TPS = 9200
# 大页:TPS = 9800 ↑ 6.5%
15. CPU 频率与隔离
# 查看 CPU 频率策略
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 默认可能是 ondemand 或 powersave,改为 performance
# 所有核设置为 performance 模式
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance > $cpu
done
# 隔离 openGauss 进程到专用 CPU 核(避免被其他进程干扰)
# 安装 numactl
yum install -y numactl
# 启动 openGauss 时绑定到 CPU 0-31
numactl --physcpubind=0-31 --membind=0 gs_om -t start
📊 完整调优参数清单
把以下配置追加到 postgresql.conf 中,重启生效:
# === 内存参数 ===
shared_buffers = 8GB # 物理内存 25%
work_mem = 64MB # 按 max_connections 计算
maintenance_work_mem = 2GB # VACUUM/索引维护
wal_buffers = 64MB # WAL 缓冲区
# === NUMA 亲和 ===
numa_distribute_mode = 'all' # 鲲鹏 NUMA 亲和(最关键)
enable_nestloop = off # 强制走 Hash Join
enable_seqscan = off # 强制走索引(OLTP 场景)
# === WAL 优化 ===
checkpoint_timeout = 15min # 减少 checkpoint 频率
max_wal_size = 64GB # WAL 上限
commit_delay = 100 # 批量提交微优化
commit_siblings = 5
wal_compression = on # WAL 压缩
# === 并行度 ===
query_dop = 2 # 查询并行度(64 核设 4)
parallel_tuple_cost = 0.01 # 降低并行代价
parallel_setup_cost = 100
effective_cache_size = 24GB # 告诉优化器缓存大小
# === 大页 ===
huge_pages = on # 使用 2MB 大页
调优效果汇总

💥 踩坑汇总
踩坑 1:shared_buffers 设太大导致 OOM
第一次我们设了 16GB(50% 物理内存),结果 + VACUUM 时触发了 swap。因为 openGauss 还有一大块内存被 page cache 占用。25% 是安全线,千万别贪。
踩坑 2:NUMA 绑核后性能反而下降
在 4 路鲲鹏上开启 numa_distribute_mode 后,某个复杂查询反而慢了。原因是跨 NUMA 节点的数据访问增加了。解决方案:对大表做 分区 + 分区亲和,让数据尽量在本节点。
踩坑 3:关掉 enable_seqscan 后部分查询报错
更新到 openGauss 5.0.1 后,某条 SQL 的索引因版本升级失效了,关掉 seqscan 后查询直接报错。加上了一个 DROP INDEX ... CREATE INDEX 才恢复。所以 enable_seqscan = off 前,先跑一遍慢查询日志确保所有表有合适的索引。
❓ 常见问题
Q1:这些参数在 x86 服务器上也适用吗?
大部分适用(shared_buffers、work_mem、WAL 参数),但 numa_distribute_mode 和 enable_nestloop/seqscan 在 x86 上效果不如鲲鹏明显。x86 的 NUMA 效应较弱,默认配置就够。
Q2:调整参数需要重启吗?
shared_buffers、huge_pages、numa_distribute_mode 需要重启。work_mem、enable_seqscan、query_dop 只需要 reload:
gs_guc reload -D $PGDATA -c "work_mem=64MB"
Q3:调完这些参数后 VACUUM 还会影响性能吗?
maintenance_work_mem 调大后 VACUUM 本身更快,但 VACUUM 仍然会扫描全表。建议搭配 autovacuum 参数一起调:
autovacuum_max_workers = 4 # 默认 3
autovacuum_naptime = 30s # 默认 1min
autovacuum_vacuum_scale_factor = 0.01 # 默认 0.2(1% 脏页就触发)
Q4:有没有一键调优脚本?
openGauss 自带了一个性能诊断工具,可以给出参数建议:
gs_checkperf -i pmk -U omm
但它给出的建议偏保守。上面的参数是我们线上验证过的,建议直接采用。
📝 总结
openGauss 在鲲鹏上的调优,核心就是三件事:让内存更大、让计算更亲和、让写入更高效。
15 个参数中,如果让我只选 3 个最重要的:
shared_buffers— 最基础的,不改它什么都别谈numa_distribute_mode = 'all'— 鲲鹏上独家优势,必须开enable_nestloop = off+enable_seqscan = off— OLTP 场景闭眼关
调完这些,TPS 从 5,200 提升到 9,800,复杂查询性能比 MySQL 快 50%+。信创数据库不是不能打,是默认参数没给对。
下一篇文章讲慢查询诊断 —— 用 WDR 报告精准定位瓶颈。
💬 互动:你们在国产数据库调优时,最有效的参数是哪个?欢迎评论区分享你的调优经验。
- 点赞
- 收藏
- 关注作者
评论(0)