鸿蒙PC高难适配:Percona Server 8.4 移植踩坑复盘
鸿蒙PC高难适配:Percona Server 8.4 移植踩坑复盘
欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
摘要
Percona Server for MySQL 是业界广泛使用的开源 MySQL 增强版数据库,代码体量大、构建图复杂、深度绑定 Linux 特性,属于开源鸿蒙 PC 三方库适配里的"硬骨头"。本文复盘在开源鸿蒙 PC(HarmonyOS PC,AArch64)上移植 Percona Server 8.4.10-10 的完整过程:先以"客户端先行"策略裁剪出静态客户端库与命令行工具,再通过 54 个可复现补丁系统性解决交叉编译探测不确定、HMDFS 文件系统差异、musl 风格 libc API 缺口、CMake 构建图耦合和测试竞态五类问题,最终在真机上完成 conan create 打包、C 消费者程序运行,并通过 142/142 全量 CTest、1979 项单元测试与上游必测的 MTR main.1st 验证。文中给出关键补丁思路、可运行的验证代码与结果数据,供后续移植大型 C/C++ 数据库组件到鸿蒙PC的开发者参考。
关键词:鸿蒙PC、开源鸿蒙、Percona Server、三方库适配、Conan、交叉编译
一、背景:为什么选这块"硬骨头"
在开源鸿蒙 PC 专项积分赛(路径C:三方库适配)中,percona-server 这类高难度库的适配积分高,但拦路虎也多:
| 适配对象 | 信息 |
|---|---|
| 软件名 / 版本 | percona-server / 8.4.10_10(上游 tag:Percona-Server-8.4.10-10) |
| 构建系统 | CMake(上游仅提供 cmake/os/Linux.cmake,无 HarmonyOS 模块) |
| 交付形态 | 静态客户端库 libperconaserverclient.a + 客户端工具(mysql、mysql_config) |
| 目标平台 | HarmonyOS PC,AArch64(armv8) |
| 适配 PR | 【高难度挑战】feat(percona-server): add 8.4.10_10 Conan recipe(AtomGit MR 5751,见文末链接) |
| 补丁规模 | 54 个 OHOS 补丁(编号 0001–0055),70 个文件、约 4200 行新增 |
Percona Server 上游把"所有 Linux 构建都当成完整服务器构建"来组织代码:服务端、路由器、NDB 集群、RPC、coredumper 全部织在同一张 CMake 构建图里,还内置了 Boost、curl、ICU、editline 等十几个三方依赖。把它塞进鸿蒙PC的交叉编译环境,等于同时和构建系统、文件系统、libc、测试框架四方作战。
二、整体思路:先定包面,再拆炸弹
动第一行代码之前,我先明确了最小可用包面(client-first):第一阶段的 Conan 包只交付客户端库和客户端工具,WITHOUT_SERVER=ON 关闭服务端,WITH_ROUTER=OFF、WITH_NDB=OFF 关闭路由器和集群;zlib、lz4、zstd、ICU、protobuf、curl、Boost 一律用源码树内置版本,外部只依赖社区已发布的 openssl/3.5.6.1.1 与 ncurses/6.6。服务端构建不放包里,而是单独起一个全量构建用于跑测试——包面和验证面分离,问题域立刻小了一圈。
这里有个前置插曲:最初 ncurses/6.4 是 W0 级阻塞,客户端的交互式命令行(bundled editline)离不开它。等社区合入 ncurses/6.6 后,用全新的 CONAN_HOME 验证能从 ohpcd 远程拉到 ncurses/6.6 和 openssl/3.5.6.1.1 配方,主配方才得以继续推进。这也提醒大家:高难库适配先盘点依赖链,依赖没就位就先去补依赖,别硬啃。
三、五类疑难问题与解决方案
54 个补丁按问题性质可以归成五类,逐类拆解如下。
3.1 交叉编译探测不确定:让 try_run 结果"可预设"
上游 CMake 用 try_run() 探测 setns、clock_gettime、CLOCK_REALTIME 是否可用。交叉编译时目标程序无法在构建机上执行,探测结果不确定。解法是在 OHOS profile 下显式预置退出码:
-DHAVE_SETNS_EXITCODE=1 # OHOS 无 setns
-DHAVE_CLOCK_GETTIME_EXITCODE=0 # 有 clock_gettime
-DHAVE_CLOCK_REALTIME_EXITCODE=0 # 有 CLOCK_REALTIME
另一个关键决策:CMAKE_SYSTEM_NAME 保持 Linux 而不是新造值。上游按 cmake/os/${CMAKE_SYSTEM_NAME}.cmake 加载 OS 模块,源码树里只有 Linux.cmake 没有 HarmonyOS.cmake;改名会直接找不到模块。配合 -DOHOS=ON 能力宏,既复用上游 Linux 路径,又能精准打点。
3.2 HMDFS 文件系统差异:拒绝符号链接的"脾气"
HarmonyOS PC 的 HMDFS 会拒绝 CMake 配置期创建的便捷符号链接(bin -> runtime_output_directory、lib -> library_output_directory 等),报 Permission denied。补丁直接在 OHOS 上跳过这些链接、保留真实输出目录;同理,tirpc 的 Autotools config.status 对 HMDFS 临时目录行为敏感,于是客户端包索性跳过 RPC 检查(OHOS AND WITHOUT_SERVER 时不执行 MYSQL_CHECK_RPC()),不去改内置的生成式 configure 文件。多个 MTR 补丁(0028、0032、0046 等)也围绕"把临时文件全部收拢进可写临时目录"展开。
3.3 libc 与头文件 API 缺口:musl 风格的"隐藏关卡"
OHOS libc 偏 musl 风格,一批 Linux 里"理所当然"的 API 在这里不存在,需要逐个绕行:
| 问题 | 根因 | 解法 |
|---|---|---|
| DNS SRV 解析编译失败 | 有 res_init/res_search,无 res_ninit/res_nsearch/res_nclose | 补丁走上游现成的 Alpine 分支(res_init 路径),能力宏控制 |
| 内置 libedit 判定平台不支持 | clang 报 __SIZEOF_WCHAR_T__=4 却未定义 __STDC_ISO_10646__ | 向 chartype.h 平台白名单加 OHOS 能力宏 |
| libedit 缺 termcap 原型 | 上游仅对 Solaris 启用手写原型兜底 | 用同一能力宏为 OHOS 启用兜底 |
| 内置 curl 头文件冲突 | SDK 头文件链在 sys/socket.h 后重定义 sockaddr_storage | OHOS 上禁用 HAVE_LINUX_TCP_H 检查,改走 netinet/tcp.h |
| InnoDB 线程优先级告警被判 MTR 错误 | libc 拒绝 Linux setpriority() 路径 | 补丁 0055 让该调用在 OHOS 上变 no-op |
3.4 CMake 构建图治理:别让工具名裸奔
上游大量自定义命令直接用"裸命令名"调用构建期生成器(comp_err、comp_sql、uca9dump 等),依赖 PATH 查找,交叉编译下必然失败。补丁统一改用生成器表达式引用目标文件:
$<TARGET_FILE:cno_huffman_generator>
同时:跳过仅服务端需要的共享库目标及其 .so 符号链接步骤(保留静态客户端库与 json_binlog_static);GCS 单元测试的 SunRPC 头文件包含条件从 WIN32 扩展为 WIN32 OR OHOS,与生产代码对齐;keyring vault 测试辅助目标显式链接 ext::curl,让编译用法要求自洽。这类改动的共同原则是:只做能力宏与目标引用层面的最小修改,不动上游逻辑。
3.5 测试可移植性:真机上"偶现挂死"才最难查
- BGC 300 线程竞态(补丁 0047):
Several_tickets_test里 300 个工作线程共享一个随机数引擎,且忙等循环用yield()空转,在 OHOS 上偶现不确定性挂死。补丁给每个线程独立引擎与分布、用屏障同步所有线程后再进原 100 轮负载,并把忙等换成 1 微秒睡眠——负载规模与断言一概不动。 - NDB 硬件统计初始化失败(补丁 0048):
NdbHW_Init()读取目标用户态读不到的 Linux procfs/CPU 亲和信息,直接跳过这段可选统计初始化,不伪造数据。 - 补丁可复现性:全部 54 个补丁在上游精确 tag 上"正放一遍、逆放还原、再放一遍"三轮验证通过
git diff --check,并可用git apply --check --unidiff-zero对干净源码树直接校验。
四、真机验证结果:数据说话
验证分五个独立阶段,全部在鸿蒙PC(AArch64)真机/远程目标机上完成:
| 验证阶段 | 结果 | 关键数据 |
|---|---|---|
| W0 依赖配方门禁 | 通过 | 全新 Conan home 可拉取 openssl/3.5.6.1.1、ncurses/6.6 |
conan create 打包 | 通过 | 退出码 0;产出 libperconaserverclient.a、mysql、mysql_config |
| C 消费者构建+运行 | 通过 | 输出 percona-client:8.4.10-10:80410:1 |
| 全量服务端 CTest | 通过 | 142/142,0 失败,耗时 707.21 秒 |
| 单元测试(分片) | 通过 | merge_large_tests-t 1979 项 16 分片、merge_innodb_tests-t 952 项 16 分片,全部分片退出码 0(实际执行 920 项,32 项为上游本来就禁用的条目,如实保留) |
MTR main.1st(上游必测) | 通过 | 2/2,含启动与关停 |
诚实声明:完整 MTR 套件(--nounit-tests --parallel=2)仍在跑,出结果前我不会宣称"全量 MTR 通过";本文所有结论以上表已归档的证据为准。
五、消费者验证代码(鸿蒙PC可运行)
test_package 里的 C 消费者程序不到 20 行,却能证明"安装、链接、运行"三件事——静态库闭包完整、C 消费者无需 C++ 运行库也能链上(配方为此显式传播了 c++/c++abi/unwind 系统库信息):
#include <mysql.h>
#include <stdio.h>
int main(void) {
if (mysql_library_init(0, NULL, NULL) != 0) {
return 1;
}
const char *info = mysql_get_client_info(); /* "8.4.10-10" */
unsigned long version = mysql_get_client_version(); /* 80410 */
unsigned int thread_safe = mysql_thread_safe(); /* 1 */
mysql_library_end();
if (info == NULL || info[0] == '\0' || version == 0) {
return 2;
}
printf("percona-client:%s:%lu:%u\n", info, version, thread_safe);
return 0;
}
真机运行输出(一行即可判定客户端库工作正常):
percona-client:8.4.10-10:80410:1
真机运行截图:
图 1:鸿蒙PC 真机终端:自签名(sign success)→ cd 进入二进制目录 → date → 直接执行 ./test_percona_server_client,输出 percona-client:8.4.10-10:80410:1

图 2:鸿蒙PC 真机终端直接执行 ./mysql --version,输出 mysql Ver 8.4.10-10 for Linux on aarch64 (Source distribution)

六、知识沉淀:一条 PR 配齐 md + kv
按照社区规范,本次同步在 knowledge/drafts/ 提交了知识草稿 E329:Prune a bundled database client graph for OHOS CMake cross builds,md 文档与知识引擎检索用的 kv 文件一一对应,沉淀的正是"大型数据库 CMake 单体仓库如何裁剪客户端构建图"这套打法(症状签名、根因、实施步骤、验证命令四要素齐全)。高难适配的经验不落成知识,下一个库还得重踩一遍坑。
七、心得总结
- 先裁包面再动手。
WITHOUT_SERVER=ON一行配置砍掉了大半张构建图,问题域从"整个数据库"缩到"客户端+测试"。 - 补丁要"能力宏化"。所有改动都以 OHOS 能力宏或条件分支实现,非 OHOS 平台行为零变化,这也是补丁能三轮正逆验证、有希望推给上游的基础。
- 证据链要独立分stage。打包归打包、测试归测试,每个阶段单独留日志与哈希,复审时才立得住。
- 偶现问题不放过。BGC 测试在真机上"偶现挂死"最容易糊弄过去,定位到共享随机引擎+忙等竞态并修掉它,比降低负载跑绿有价值得多。
把 MySQL 生态的重量级组件请进鸿蒙PC,靠的不是蛮力改代码,而是"包面裁剪—能力宏—可复现补丁—分阶段证据"这套组合拳。期待更多开发者加入开源鸿蒙PC社区,一起把生态的三方库地图补全。
参考链接
- 适配 PR(AtomGit):https://atomgit.com/OpenHarmonyPCDeveloper/build_in_harmonyos/merge_requests/5751
- 开源鸿蒙 PC 社区项目(AtomGit):https://atomgit.com/OpenHarmonyPCDeveloper
- Percona Server 官方仓库:https://github.com/percona/percona-server
- Percona Server 官方文档:https://docs.percona.com/percona-server/8.4/
- 开源鸿蒙PC社区(CSDN):https://harmonypc.csdn.net/
更多推荐




所有评论(0)