鸿蒙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_storageOHOS 上禁用 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

鸿蒙PC真机运行 test_percona_server_client

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

鸿蒙PC真机运行 mysql --version

六、知识沉淀:一条 PR 配齐 md + kv

按照社区规范,本次同步在 knowledge/drafts/ 提交了知识草稿 E329:Prune a bundled database client graph for OHOS CMake cross builds,md 文档与知识引擎检索用的 kv 文件一一对应,沉淀的正是"大型数据库 CMake 单体仓库如何裁剪客户端构建图"这套打法(症状签名、根因、实施步骤、验证命令四要素齐全)。高难适配的经验不落成知识,下一个库还得重踩一遍坑。

七、心得总结

  1. 先裁包面再动手。WITHOUT_SERVER=ON 一行配置砍掉了大半张构建图,问题域从"整个数据库"缩到"客户端+测试"。
  2. 补丁要"能力宏化"。所有改动都以 OHOS 能力宏或条件分支实现,非 OHOS 平台行为零变化,这也是补丁能三轮正逆验证、有希望推给上游的基础。
  3. 证据链要独立分stage。打包归打包、测试归测试,每个阶段单独留日志与哈希,复审时才立得住。
  4. 偶现问题不放过。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/
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐