国产化适配:大厂 PG 内核的信创环境移植与兼容性改造=「鲲鹏 920 + 麒麟 V10 + 原生 PG16」
·
国产化适配:大厂 PG 内核信创环境移植 —— 完整方案
先用大白话把这件事讲清楚,再给你能直接用的完整代码和流程。
---
一、先搞懂到底在干什么(大白话)
"大厂 PG 内核" 指的是基于 PostgreSQL 改的数据库(人大金仓 KingbaseES、瀚高 HighGo、华为 openGauss、阿里 PolarDB、腾讯
TDSQL-PG 等都是 PG 血统)。
"信创环境" 就是把它从 Intel + CentOSs这种"洋环境",搬到国产芯片 + 国产操作系统上跑起来,而且要跑得稳、跑得快。
国产环境无非这几类,移植难度差别很大:
┌─────────────┬───────────────┬─────────────────┬─────────────────┬─────────────────────────────────────────────┐
│ 类别 │ 代表 │ 指令集架构 │ 移植难度 │ 说明 │
├─────────────┼───────────────┼─────────────────┼─────────────────┼─────────────────────────────────────────────┤
│ 鲲鹏 / 飞腾 │ 华为/飞腾 │ ARM64 (aarch64) │ ⭐⭐ 低 │ PG 原生支持好,主要是编译参数和调优 │
├─────────────┼───────────────┼─────────────────┼─────────────────┼─────────────────────────────────────────────┤
│ 海光 / 兆芯 │ Hygon/Zhaoxin │ x86_64 │ ⭐ 最低 │ 几乎等同于 Intel,重点是 RPM 依赖 │
├─────────────┼───────────────┼─────────────────┼─────────────────┼─────────────────────────────────────────────┤
│ 龙芯 │ Loongson │ LoongArch64 │ ⭐⭐⭐⭐ 高 │ 新架构,老版本 PG 要手动移植自旋锁/原子操作 │
├─────────────┼───────────────┼─────────────────┼─────────────────┼─────────────────────────────────────────────┤
│ 申威 │ Sunway │ SW64 │ ⭐⭐⭐⭐⭐ 最高 │ 编译器和工具链都特殊,最难 │
└─────────────┴───────────────┴─────────────────┴─────────────────┴─────────────────────────────────────────────┘
操作系统:麒麟 Kylin V10、统信 UOS、openEuler、中标麒麟(基本都是 RHEL/Debian 系,glibc 版本和依赖包名不一样)。
一句话总结移植的本质:
▎ 90% 的工作量是「让编译器认识新 CPU + 凑齐依赖库 + 跑通回归测试」,只有 10% 是真正改 C 源码里跟 CPU
▎ 强相关的那几个文件(自旋锁、原子操作、内存屏障、CRC 硬件加速)。
下面分别给你这两部分的完整代码。
---
二、完整流程总览(七步法)
①摸底 →确认 CPU架构 + OS + glibc + 编译器版本
②工具链 →装齐 gcc/依赖库,搭隔离的编译环境
③配置 →configure 识别架构 + 正确的 march 参数
④源码移植 →改自旋锁/原子操作/内存屏障/CRC(仅龙芯/申威需要)
⑤编译 →全量编译 + 解决报错
⑥验证 →make check 回归测试 + 性能压测
⑦打包 →做成 RPM/DEB,适配国产 OS
---
三、第①步:摸底(先跑这个脚本)
大白话:移植前必须先知道"敌人"长啥样。下面这个脚本一把梭,把环境信息全打出来。
#!/bin/bash
# detect_env.sh ——信创环境摸底脚本(直接复制运行)
echo "========= CPU 架构 ========="
uname -m # aarch64 / loongarch64 / x86_64 / sw_64
echo "========= CPU 型号 ========="
lscpu | grep -iE "model name|架构|Architecture|BIOS"
cat /proc/cpuinfo | grep -iE "model|cpu" | head -5
echo "========= 操作系统 ========="
cat /etc/os-release | grep -iE "PRETTY_NAME|VERSION"
# 麒麟看这个:
[ -f /etc/kylin-release ] && cat /etc/kylin-release
echo "========= glibc 版本(关键!决定二进制能不能跑)========="
ldd --version | head -1
getconf GNU_LIBC_VERSION
echo "========= 编译器 ========="
gcc --version | head -1
gcc -dumpmachine # 确认目标三元组
echo "========= ARM 是否支持 CRC 硬件加速 ========="
grep -o 'crc32\|asimd\|crc' /proc/cpuinfo | sort -u
echo "========= 关键开发库 ========="
for lib in readline-devel zlib-devel openssl-devel libicu-devel \
flex bison perl-devel python3-devel libxml2-devel; do
rpm -q $lib 2>/dev/null || echo "缺少: $lib"
done
重点看三个东西:
- uname -m →决定走哪条移植路线
- glibc 版本 →这是最隐蔽的坑。麒麟 V10 是 glibc 2.28,如果你拿 glibc 2.34 的环境编译,到目标机器上会报 version
GLIBC_2.34 not found,必须在目标 OS 同款环境里编译。
- ARM 的 crc32 标志 →决定能不能开硬件 CRC 加速(PG 性能关键)。
---
四、第②步:工具链+ 依赖(一键装齐)
大白话:别在物理机上瞎装,用 Docker 拉国产 OS 镜像做隔离编译环境,干净、可复现。
# ===== 麒麟/openEuler ARM64 编译环境(RPM 系)=====
# openEuler 官方有 ARM64/LoongArch 镜像,最省事
docker run -it --name pg-build openeuler/openeuler:22.03-lts-sp1 bash
# 进容器后装齐 PG 编译依赖(一行搞定)
yum install -y gcc gcc-c++ make flex bison \
readline-devel zlib-devel openssl-devel \
libicu-devel libxml2-devel libxslt-devel \
perl-devel python3-devel tcl-devel \
systemd-devel uuid-devel lz4-devel \
perl-IPC-Run perl-Test-Simple # 回归测试要用
# ===== 统信UOS / Deepin(DEB 系)=====
apt-get update && apt-get install -y \
gcc make flex bison \
libreadline-dev zlib1g-dev libssl-dev \
libicu-dev libxml2-dev libxslt1-dev \
perl libperl-dev python3-dev tcl-dev \
libsystemd-dev uuid-dev liblz4-dev
▎ 避坑:libicu-devel(排序规则库)经常被忽略,缺了它中文排序会乱。openssl-devel 国产 OS 里可能是国密版
▎ tongsuo/tassl,要支持国密 SM2/SM3/SM4 时换成它。
---
五、第③步:configure配置(架构识别 + 编译参数)
大白话:configure 是 PG 的"配置向导",它要先认识你的 CPU 才能编译。ARM64 和 x86 PG
都认识,龙芯老版本不认识,得手动告诉它。
5.1 ARM64(鲲鹏/飞腾)——最优编译参数
# ===== 鲲鹏 920 / 飞腾 D2000 最佳编译配置 =====
export CFLAGS="-O2 -march=armv8-a+crc+crypto -mtune=tsv110 -fno-omit-frame-pointer"
# 飞腾用 -mtune=generic 或不写;鲲鹏920用 tsv110
# +crc 是关键:开启 CRC32C 硬件指令,PG 校验和性能翻几倍
./configure \
--prefix=/opt/pg/16 \
--with-icu \
--with-openssl \
--with-llvm=no \
--with-readline \
--with-libxml \
--with-lz4 \
--with-uuid=e2fs \
--with-systemd \
--enable-thread-safety \
CFLAGS="$CFLAGS"
# ===== 海光/兆芯 (x86_64) ——几乎等同 Intel =====
export CFLAGS="-O2 -march=x86-64-v2 -mtune=generic"
# 兆芯老型号可能不支持 v2,保守用 -march=core2 或 nehalem
./configure --prefix=/opt/pg/16 --with-icu --with-openssl ...(同上)
5.2 龙芯 LoongArch64 ——老版本 PG 要打补丁
PostgreSQL 16+ 已原生支持 LoongArch,直接 configure 即可:
export CFLAGS="-O2 -march=loongarch64 -mabi=lp64d"
./configure --prefix=/opt/pg/16 --build=loongarch64-linux-gnu ...
PG 15 及更老版本,configure 不认识龙芯,要手动改 config.guess /
config.sub(用龙芯官方提供的新版替换),并改一个宏,下一节给代码。
---
六、第④步:源码移植关键代码(仅龙芯/申威需要,ARM/x86跳过)
这是真正的硬核移植部分。大白话:CPU
越底层的并发原语(自旋锁、原子操作、内存屏障)越跟指令集绑死,新架构必须手写汇编。下面给龙芯 LoongArch
的完整移植代码(最常见的硬骨头)。
6.1 自旋锁 ——src/include/storage/s_lock.h
大白话:自旋锁是数据库并发的命根子,就是"抢锁抢不到就原地转圈等"。要用龙芯的原子交换指令 amswap.w 实现。
在 s_lock.h 里找到一堆 #if defined(__arm__)... 的地方,新增龙芯分支:
/* ===== LoongArch (龙芯) 自旋锁实现 ===== */
#if defined(__loongarch__) || defined(__loongarch64)
#define HAS_TEST_AND_SET
typedef unsigned int slock_t;
#define TAS(lock) tas(lock)
static __inline__ int
tas(volatile slock_t *lock)
{
int ret;
/* amswap.w:原子地把 1 写进锁,返回锁的旧值。
旧值==0 说明我抢到了;旧值==1 说明别人占着。 */
__asm__ __volatile__(
" amswap_db.w %0, %2, %1 \n" /* _db 带内存屏障,更安全 */
: "=&r"(ret), "+ZB"(*lock)
: "r"((int)1)
: "memory");
return ret;
}
#define S_UNLOCK(lock) \
do { \
__asm__ __volatile__("dbar 0 \n" ::: "memory"); /* 全屏障,确保前面的写都生效 */ \
*((volatile slock_t *) (lock)) = 0; \
} while (0)
#endif /* __loongarch__ */
6.2 原子操作 + 内存屏障 ——src/include/port/atomics/
大白话:好消息是——现代GCC(≥8)对龙芯/ARM的原子操作有内置支持,PG
有个"通用兜底实现"generic-gcc.h,直接用编译器内置的 __atomic_*,不用自己写汇编。
只需在 src/include/port/atomics.h 里确保龙芯走通用路径(通常自动就走了),并在 c.h
里确认内存屏障定义。如果要自己定义屏障,加这个:
/* src/include/port/atomics/arch-loongarch.h(新建此 include,或并入 generic)*/
/* 内存屏障:dbar 指令。0 = 全屏障 */
#define pg_memory_barrier_impl() __asm__ __volatile__ ("dbar 0" ::: "memory")
#define pg_read_barrier_impl() __asm__ __volatile__ ("dbar 0" ::: "memory")
#define pg_write_barrier_impl() __asm__ __volatile__ ("dbar 0" ::: "memory")
/* 其余原子操作(CAS、fetch_add 等)全部交给编译器内置,
即 generic-gcc.h 里的 __atomic_compare_exchange_n / __atomic_fetch_add,
龙芯 GCC 已正确支持,无需手写汇编。 */
然后在 atomics.h 顶部加引用:
#elif defined(__loongarch__) || defined(__loongarch64)
#include "port/atomics/arch-loongarch.h"
▎ 核心理念(最优方案):能让编译器内置 __atomic_* 干的活,绝不手写汇编。只有自旋锁 TAS 因为历史原因 PG
▎ 坚持用内联汇编,其余全走通用路径——这是最省事且最不容易出bug 的做法。
6.3 CRC32C 硬件加速(ARM64 性能关键,强烈建议开)
大白话:PG 每个数据页都要算校验和(CRC32C),ARM64 有专门的硬件指令,开了能快好几倍。PG 自带了实现
src/port/pg_crc32c_armv8.c,只要 configure 时 -march 带了 +crc,它自动启用,无需改码。验证一下:
# 编译后确认硬件 CRC 生效
grep "USE_ARMV8_CRC32C" src/include/pg_config.h
# 输出 #define USE_ARMV8_CRC32C 1 就对了
# 龙芯没有专用 CRC 指令,自动走软件查表实现(pg_crc32c_sb8.c),无需处理
---
七、第⑤⑥步:编译+ 回归测试验证
# ===== 编译(用满所有核心)=====
make -j$(nproc) # 全量编译
make -C contrib -j$(nproc) # 编译扩展插件
make install
make -C contrib install
# ===== 回归测试(最重要的验证!)=====
# 这步跑通,说明移植在功能上没问题
make check 2>&1 | tee regress.log
# 看结果:All N tests passed 就成功
# 失败的 case 会生成 regression.diffs,重点看排序、浮点、时区相关差异
# ===== 大白话:常见失败原因 =====
# 1. 浮点精度差异 →龙芯/ARM 的 IEEE 实现细微差别,通常无害
# 2. 排序顺序不同 →ICU/locale 没装对,回去补 libicu
# 3. 字节序 →PG 支持的国产芯片都是小端,一般没问题
性能压测(用最好的工具 pgbench + sysbench)
# 初始化测试库
/opt/pg/16/bin/initdb -D /data/pgdata --locale=zh_CN.UTF-8
/opt/pg/16/bin/pg_ctl -D /data/pgdata -l log start
/opt/pg/16/bin/createdb bench
# pgbench:PG 官方压测工具(最权威)
/opt/pg/16/bin/pgbench -i -s 100 bench # 装载 1000万行
/opt/pg/16/bin/pgbench -c 64 -j 16 -T 300 -P 5 bench # 64并发压5分钟
# 关注 tps,对比 x86 基线。ARM64 调好参数后通常能到 x86 的 90%~110%
国产环境专属调优(postgresql.conf 关键参数)
# ARM64 核多但单核弱,针对性调优
shared_buffers = 物理内存的25%
huge_pages = try # ARM 大页收益明显,务必开
effective_io_concurrency = 200 # 国产 NVMe SSD 调高
max_worker_processes = CPU核数
max_parallel_workers = CPU核数
wal_compression = lz4 # 国产芯片 IO 常是瓶颈,压缩 WAL 划算
---
八、第⑦步:打包成国产OS 能装的 RPM/DEB
大白话:编译出来的二进制要做成"安装包",才能在客户的麒麟/统信上一键安装。
# ===== 麒麟/openEuler 做 RPM =====
# 用 fpm(最省事的打包神器,一行命令把目录变成 RPM)
gem install fpm
fpm -s dir -t rpm \
-n kingbase-pg16 -v 16.2 \
--iteration 1.kylin.aarch64 \
-a aarch64 \
-d "readline" -d "openssl-libs" -d "libicu" \
--prefix=/opt/pg/16 \
-C /opt/pg/16 .
# 生成 kingbase-pg16-16.2-1.kylin.aarch64.rpm
# 客户机安装
rpm -ivh kingbase-pg16-16.2-1.kylin.aarch64.rpm
---
九、兼容性改造(信创落地常被要求的"软适配")
大白话:信创项目里,客户原来多半用 Oracle,要求 PG 内核"长得像 Oracle"。这块不改 CPU
相关代码,而是装兼容扩展。最优选择:
-- 1. Oracle 语法兼容:装 orafce(开源最成熟)
CREATE EXTENSION orafce;
-- 立刻就能用 Oracle 的函数:
SELECT nvl(null, 'x'), sysdate, to_char(1234.5,'9999.99'), dual;
-- 2. 国密算法(信创强制要求):用 pgcrypto + 国密版 openssl(tongsuo)
CREATE EXTENSION pgcrypto;
-- 编译时 --with-openssl 指向 tongsuo,即可支持 SM2/SM3/SM4
如果是 openGauss/KingbaseES 这类已内置 Oracle 兼容模式的内核,建库时直接指定:
-- KingbaseES / openGauss 建库时开 Oracle 兼容模式
CREATE DATABASE oradb DBCOMPATIBILITY = 'A'; -- 'A'=Oracle, 'B'=MySQL, 'PG'=原生
---
十、整套方案的"最优"判断(一张表收尾)
┌──────────────┬─────────────────────────────┬────────────────────────────┐
│ 环节 │ 最优选择 │ 为什么 │
├──────────────┼─────────────────────────────┼────────────────────────────┤
│ 编译环境 │ Docker + 目标 OS 官方镜像 │ 隔离、可复现、glibc 不会错 │
├──────────────┼─────────────────────────────┼────────────────────────────┤
│ ARM64 移植 │ 只调编译参数 +crc,不改源码 │ PG 原生支持 ARM64 │
├──────────────┼─────────────────────────────┼────────────────────────────┤
│ 龙芯原子操作 │ 优先用编译器内置 __atomic_* │ 手写汇编易错,内置最稳 │
├──────────────┼─────────────────────────────┼────────────────────────────┤
│ 国密加密 │ 铜锁 Tongsuo 替换 openssl │ 唯一开源且通过认证的国密库 │
├──────────────┼─────────────────────────────┼────────────────────────────┤
│ Oracle 兼容 │ orafce 扩展 │ 开源最成熟,覆盖最广 │
├──────────────┼─────────────────────────────┼────────────────────────────┤
│ 打包 │ fpm │ 一行命令出 RPM/DEB │
├──────────────┼─────────────────────────────┼────────────────────────────┤
│ 验证 │ make check + pgbench │ PG 官方标准,最权威 │
└──────────────┴─────────────────────────────┴────────────────────────────┘
---
给你的下一步建议
你现在卡在哪个具体环节,告诉我就能给更精准的代码:
1. 你的目标 CPU 是哪个?(鲲鹏 ARM?龙芯?申威?)——决定要不要改汇编
2. PG 内核是哪家的?(原生 PG / openGauss / KingbaseES / PolarDB)——决定补丁方式
3. 目标操作系统 + 版本?(麒麟 V10 SP3?UOS?)——决定依赖包和 glibc
把这三个告诉我,我直接给你那条路线的逐条命令 + 可能踩的具体报错和解法。
要我现在就针对某一个具体组合(比如最常见的「鲲鹏 920 + 麒麟 V10 + 原生 PG16」)写一份从零到跑通的完整逐行实操脚本吗?
「鲲鹏 920 + 麒麟 V10 + 原生 PG16」
鲲鹏 920 + 麒麟 V10 + 原生 PG16 —— 从零到跑通完整实操
这是信创最常见、也最顺的组合。鲲鹏 920 是 ARM64(aarch64),PG16 原生支持,不用改任何 C
源码、不用写汇编,核心工作就是「正确的编译参数 + 凑齐依赖 + 调优」。
下面每条命令都能直接复制执行,关键处都有大白话解释。
---
第 0 步:先确认你的环境长这样(30 秒)
uname -m # 必须输出 aarch64
lscpu | grep -i "model name" # 应含 Kunpeng-920
cat /etc/kylin-release # 看麒麟版本,如 V10 SP3
ldd --version | head -1 # glibc 版本,麒麟V10 一般是 2.28
gcc --version | head -1 # 麒麟V10 自带 gcc 7.3,够用
grep -o 'crc32\|aes\|sha' /proc/cpuinfo | sort -u # 确认有硬件加速指令
▎ 大白话:最后一条最关键。鲲鹏 920 必须能看到 crc32,这意味着可以开启硬件 CRC 加速,PG
▎ 校验和性能能快好几倍。看不到就说明 CPU 信息没读对,先别往下走。
---
第 1 步:装齐编译依赖(麒麟 V10 用 yum)
# 切到 root
sudo -i
# 麒麟V10 自带 yum 源就够,一行装齐 PG16 全部编译依赖
yum install -y \
gcc gcc-c++ make \
flex bison \
readline-devel zlib-devel \
openssl-devel \
libicu-devel \
libxml2-devel libxslt-devel \
perl-devel python3-devel tcl-devel \
systemd-devel libuuid-devel \
lz4-devel \
perl-IPC-Run perl-Test-Harness # 这两个是跑回归测试 make check 要用的
逐个解释为什么要装:
- flex bison ——PG 的 SQL 解析器要用它们生成,缺了编译直接报错
- readline-devel ——psql 命令行的方向键/历史记录,没它体验极差
- openssl-devel ——SSL 加密连接,信创基本都要求
- libicu-devel ——中文排序的命根子,缺了中文 ORDER BY 会乱序
- lz4-devel ——WAL 压缩,鲲鹏 IO 常是瓶颈,开了划算
- systemd-devel ——让 PG 能注册成系统服务
▎ 避坑:如果 yum install 报某个包找不到,先 yum makecache 刷新缓存;麒麟有的版本 libuuid-devel 叫
▎ uuid-devel,二选一即可。
---
第 2 步:下载 PG16 源码
cd /usr/local/src
# 官方源码(如果服务器能上外网)
wget https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.bz2
# 内网环境就先在能上网的机器下好,scp 传进来
tar -xjf postgresql-16.2.tar.bz2
cd postgresql-16.2
---
第 3 步:configure ——鲲鹏 920 最优编译参数(核心!)
这一步决定性能上限,鲲鹏专属参数全在这:
# 关键:鲲鹏920的最优 CFLAGS
export CFLAGS="-O2 -march=armv8-a+crc+crypto -mtune=tsv110 -fno-omit-frame-pointer"
./configure \
--prefix=/opt/pgsql/16 \
--with-icu \
--with-openssl \
--with-readline \
--with-libxml \
--with-libxslt \
--with-lz4 \
--with-uuid=e2fs \
--with-systemd \
--with-python \
--enable-thread-safety \
CFLAGS="$CFLAGS"
逐个参数大白话:
┌───────────────────────────┬──────────────────────────────────────────────────────────────┐
│ 参数 │ 干嘛的 │
├───────────────────────────┼──────────────────────────────────────────────────────────────┤
│ -march=armv8-a+crc+crypto │ 告诉编译器用鲲鹏的硬件 CRC 和加密指令——性能关键,必须带+crc │
├───────────────────────────┼──────────────────────────────────────────────────────────────┤
│ -mtune=tsv110 │ tsv110 是鲲鹏 920 的内核代号,针对它优化指令调度 │
├───────────────────────────┼──────────────────────────────────────────────────────────────┤
│ -fno-omit-frame-pointer │ 保留栈帧,将来用 perf 抓性能火焰图时能看到完整调用栈 │
├───────────────────────────┼──────────────────────────────────────────────────────────────┤
│ --prefix=/opt/pgsql/16 │ 装到哪,建议带版本号方便以后多版本共存 │
├───────────────────────────┼──────────────────────────────────────────────────────────────┤
│ --with-icu │ 开 ICU,中文排序正确 │
├───────────────────────────┼──────────────────────────────────────────────────────────────┤
│ --with-systemd │ 能用 systemctl 管理服务 │
└───────────────────────────┴──────────────────────────────────────────────────────────────┘
configure 跑完,验证 CRC 硬件加速有没有真的开启:
grep -E "USE_ARMV8_CRC32C|USE_ICU" src/include/pg_config.h
期望输出(看到这两行才算成功):
#define USE_ARMV8_CRC32C 1 ←硬件 CRC 开了!
#define USE_ICU 1 ←ICU 开了!
▎ 大白话:如果没看到 USE_ARMV8_CRC32C,说明 +crc 没生效,回去检查 CFLAGS。这是鲲鹏移植最值钱的一行优化。
---
第 4 步:编译 + 安装
# 用满所有核心编译(鲲鹏920核多,这步飞快)
make -j$(nproc)
# 编译 contrib 扩展(pgcrypto、orafce 依赖的基础设施等)
make -j$(nproc) -C contrib
# 安装
make install
make install -C contrib
编译期间如果中途报错,看第 11 步的常见报错速查表。
---
第 5 步:创建专用用户 + 初始化数据库
大白话:数据库绝不能用 root 跑(安全红线),建个专用 postgres 用户。
# 建用户和数据目录
groupadd postgres
useradd -g postgres -m postgres
mkdir -p /data/pgdata
chown -R postgres:postgres /data/pgdata /opt/pgsql
# 配置 postgres 用户的环境变量
cat >> /home/postgres/.bash_profile <<'EOF'
export PGHOME=/opt/pgsql/16
export PGDATA=/data/pgdata
export PATH=$PGHOME/bin:$PATH
export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH
export LANG=zh_CN.UTF-8
EOF
# 切到 postgres 用户初始化(注意:必须用普通用户)
su - postgres
source ~/.bash_profile
# 初始化数据库,用 ICU 做默认排序(中文友好)
initdb -D $PGDATA \
--encoding=UTF8 \
--locale-provider=icu \
--icu-locale=zh-CN \
--locale=zh_CN.UTF-8
# 看到 "Success. You can now start..." 就成了
▎ 大白话:--locale-provider=icu --icu-locale=zh-CN 是 PG16 的新特性,让中文排序按拼音正确排,比老的 glibc locale
▎ 更稳。这是信创项目中文场景的最优配置。
---
第 6 步:鲲鹏专属性能调优(postgresql.conf)
大白话:鲲鹏 920 核多但单核主频不如 x86 高,所以策略是"靠并行取胜 + 把 IO 压住"。下面参数针对鲲鹏定制。
# 还是 postgres 用户
cat >> $PGDATA/postgresql.conf <<'EOF'
# ============ 鲲鹏920 信创调优 ============
listen_addresses = '*'
port = 5432
max_connections = 500
# 内存(按物理内存调,这里假设 64G 机器)
shared_buffers = 16GB # 物理内存 25%
effective_cache_size = 48GB # 物理内存 75%
work_mem = 32MB
maintenance_work_mem = 2GB
# 大页:ARM 上收益明显,强烈建议开
huge_pages = try
# 并行:鲲鹏核多,把并行拉满
max_worker_processes = 64 # = CPU 核数
max_parallel_workers = 64
max_parallel_workers_per_gather = 8
max_parallel_maintenance_workers = 8
# IO:国产 NVMe SSD 调高
effective_io_concurrency = 200
random_page_cost = 1.1 # SSD 用 1.1
# WAL:鲲鹏 IO 常是瓶颈,开 lz4 压缩
wal_compression = lz4
wal_buffers = 64MB
max_wal_size = 16GB
min_wal_size = 4GB
checkpoint_completion_target = 0.9
# 日志
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_min_duration_statement = 1000 # 记录超 1 秒的慢 SQL
EOF
配置访问权限(允许网段连接):
cat >> $PGDATA/pg_hba.conf <<'EOF'
# 允许内网网段用密码连接(按你实际网段改)
host all all 192.168.0.0/16 scram-sha-256
EOF
---
第 7 步:注册成 systemd 服务(开机自启)
# 回到 root
exit # 退出 postgres 用户
cat > /etc/systemd/system/postgresql-16.service <<'EOF'
[Unit]
Description=PostgreSQL 16 database server
After=network.target
[Service]
Type=notify
User=postgres
Group=postgres
Environment=PGDATA=/data/pgdata
ExecStart=/opt/pgsql/16/bin/postgres -D /data/pgdata
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=infinity
OOMScoreAdjust=-1000
[Install]
WantedBy=multi-user.target
EOF
# 启用并启动
systemctl daemon-reload
systemctl enable postgresql-16
systemctl start postgresql-16
systemctl status postgresql-16 # 看到 active (running) 就成功
开放防火墙端口:
firewall-cmd --permanent --add-port=5432/tcp
firewall-cmd --reload
---
第 8 步:验证移植成功(功能 + 性能双验证)
8.1 设密码 + 连接测试
su - postgres
psql -c "ALTER USER postgres PASSWORD 'YourStrongPwd@2026';"
psql -c "SELECT version();"
# 应输出:PostgreSQL 16.2 ... aarch64-... 看到 aarch64 说明确实是 ARM 版
8.2 验证中文排序正确(信创必查)
psql <<'EOF'
CREATE TABLE t(n text);
INSERT INTO t VALUES ('张三'),('李四'),('王五'),('赵六');
SELECT n FROM t ORDER BY n; -- 应按拼音排:李四、王五、张三、赵六
EOF
8.3 性能压测(pgbench,鲲鹏实测)
createdb bench
pgbench -i -s 100 bench # 装载约 1000 万行
pgbench -c 64 -j 16 -T 120 -P 10 bench # 64并发压2分钟,每10秒报一次
# 关注输出的 tps 值。鲲鹏920 调好参数后,
# 这套配置 64 并发只读 tps 通常能到 x86 同级机器的 90%~110%
---
第 9 步(可选):Oracle 兼容 + 国密
如果客户原来用 Oracle,装 orafce:
# 先装 orafce(需要先 git clone 或下载源码)
cd /usr/local/src
git clone https://github.com/orafce/orafce.git
cd orafce
make USE_PGXS=1 PG_CONFIG=/opt/pgsql/16/bin/pg_config
make USE_PGXS=1 PG_CONFIG=/opt/pgsql/16/bin/pg_config install
# 在数据库里启用
psql -d bench -c "CREATE EXTENSION orafce;"
psql -d bench -c "SELECT sysdate, nvl(NULL,'默认值'), to_char(1234.5,'9999.99');"
# 立刻能用 Oracle 的函数了
---
第 10 步:打包成 RPM 给客户一键安装
# root 下
gem install fpm # 或 yum install rubygems 后再装
fpm -s dir -t rpm \
-n postgresql16-kunpeng -v 16.2 \
--iteration 1.ky10.aarch64 \
-a aarch64 \
-d readline -d openssl-libs -d libicu -d lz4 \
--prefix=/opt/pgsql/16 \
-C /opt/pgsql/16 .
# 生成 postgresql16-kunpeng-16.2-1.ky10.aarch64.rpm
# 客户机直接:rpm -ivh xxx.rpm
▎ 关键避坑:打包机的 glibc 版本必须 ≤客户机。一定要在同款麒麟 V10 上编译打包,否则客户机会报 GLIBC_2.xx not found。
---
第 11 步:鲲鹏常见报错速查表
┌──────────────────────────────────┬─────────────────────┬────────────────────────────────────────────────────────┐
│ 报错 │ 原因 │ 解法 │
├──────────────────────────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ configure: error: readline │ 没装 readline-devel │ yum install -y readline-devel │
│ library not found │ │ │
├──────────────────────────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ pg_config.h 里没有 │ CFLAGS 漏了 +crc │ 重新 configure,CFLAGS 加 -march=armv8-a+crc │
│ USE_ARMV8_CRC32C │ │ │
├──────────────────────────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ make check 排序相关 case 失败 │ ICU/locale 没配对 │ 确认 --with-icu,重新 initdb 用 icu provider │
├──────────────────────────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ 启动报 huge_pages 失败 │ 系统没配大页 │ 改成 huge_pages = try(自动降级),或 sysctl -w │
│ │ │ vm.nr_hugepages=8192 │
├──────────────────────────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ GLIBC_2.34 not found │ 编译机 glibc │ 在麒麟V10原生环境重编,别用新系统编 │
│ │ 比客户机新 │ │
├──────────────────────────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ 中文显示乱码 │ 客户端编码不对 │ export LANG=zh_CN.UTF-8 + \encoding UTF8 │
└──────────────────────────────────┴─────────────────────┴────────────────────────────────────────────────────────┘
---
整套流程一句话总结
▎ 鲲鹏 920 上移植原生 PG16,完全不用改 C 代码,成败就在两件事:
▎ 1. -march=armv8-a+crc+crypto 一定要带(验证 USE_ARMV8_CRC32C=1)——这是性能命根子;
▎ 2. 在麒麟 V10 原生环境里编译打包——这是部署不翻车的命根子。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐
所有评论(0)