给客户做银河麒麟V10服务器迁移时最头疼的往往不是业务本身而是数据库这个基础组件——官方源里的MariaDB版本落后得让人想砸键盘。想要在麒麟系统上用上较新版本的MariaDB自己编译安装基本是唯一出路。这篇文章就把我在银河麒麟V10含ARM和x86两种架构上编译安装MariaDB的完整过程、参数取舍和踩坑记录一次说清给正要动手的你一条能直接走通的路。1. 为什么非要从源码编译麒麟自带源的真实差距先说一个大家可能已经踩过的坑在银河麒麟V10上执行sudo apt install mariadb-server装出来的版本往往在10.3左右甚至更低。不是说10.3不能用而是如果你要接的业务侧有版本要求——比如需要支持特定窗口函数、CTE语法或者要跟云上实例做版本匹配——老版本会让你卡在兼容性上进退两难。这里补充一个基本认知银河麒麟V10虽然是基于Debian系桌面版和服务器版都走apt/dpkg这一套但它的软件源镜像更新节奏和上游Debian/Ubuntu并不完全同步。为了稳定性麒麟官方仓库往往锁定了一批软件版本数据库这种基础件更是不轻易升级。所以如果你的场景是“数据库版本必须比官方仓库更新”那么源码编译就成了最可控的路线。1.1 源码包版本选择的实际考量用户需求里写的版本是“mariadb12.2”这个编号值得先理一理。截至目前MariaDB官方发布的主线版本号还在11.x阶段不存在12.2这个正式版本。我推测这里可能是需求方笔误原本想要的很可能是10.11 LTS或11.x系列。如果你下载源码时在官网列表里找不到12.2请直接去 MariaDB官方下载页 或GitHub Releases里选当前最新的稳定版——我这次演示用的就是11.4 LTS版本编译流程和参数对所有10.11、11.x版本完全通用具体版本差异只体现在功能层面不影响安装步骤。1.2 编译安装前的收益与成本评估不要因为“编译安装”四个字就头大。它的收益很明确版本可控装多新由你说了算安装路径可控不会污染系统目录编译参数可控能按实际机器资源定制功能不依赖麒麟源状态一套流程在Debian/Ubuntu/麒麟上都能跑成本也摆在这里编译需要时间一般15到40分钟不等取决于机器CPU核心数、需要一定的依赖处理能力以及编译完成后的初始化、systemd配置、权限处理等收尾工作。坦率讲比apt一键装上要多花半小时左右但换来的是一个版本干净、配置透明的数据库实例长期看这笔时间花得很值。2. 编译环境准备依赖清单和工具链细节先把环境底板铺好。我先说一个容易出现低级错误的地方麒麟系统自带的是gcc但MariaDB在CMake阶段需要g如果只装了gcc报错会让你莫名其妙。下面是完整依赖安装命令。2.1 基础工具链和依赖包安装在联网状态下运行sudo apt update sudo apt upgrade -y sudo apt install -y gcc g make cmake bison libncurses-dev \ libaio-dev libssl-dev pkg-config build-essential wget tar逐项说明一下为什么需要这些gcc/gC和C编译器MariaDB源码绝大部分是C写的make驱动编译过程的构建工具cmakeMariaDB从10.x起全面改用CMake作为构建系统这个工具是核心bison语法分析器生成工具MariaDB内置的SQL解析器需要它libncurses-dev终端交互库编译mysql客户端部分会链接libaio-devLinux原生异步I/O库InnoDB的io能力依赖它libssl-devTLS/SSL支持客户端连数据库走加密通道全靠它pkg-config编译时查找依赖库头文件路径的辅助工具2.2 ARM与x86架构的关键差异麒麟V10服务器最常见的是x86_64和aarch64ARM两种CPU架构。在编译层面前文依赖包在两种架构下名称基本一样apt会自动安装对应架构的包不需要特别处理。真正需要留意的差异在CMake参数阶段目前主流两者通用但有一个细微点如果你在ARM机器上做压力测试或业务侧有纯CPU密集任务建议额外加-DCMAKE_BUILD_TYPERelease并检查编译器是否带有crc32相关硬件支持在cmake输出日志中能看到-march相关选项。不过这些不是编译失败的必要条件属于性能调优范畴后文会再说。2.3 用户和环境准备创建专用系统用户避免数据库以root身份运行这是一个从运维角度必须养成的习惯sudo useradd -r -s /sbin/nologin mysql sudo mkdir -p /data/mariadb/data sudo chown -R mysql:mysql /data/mariadb数据目录我习惯放在 /data/mariadb/data 而不是默认的 /var/lib/mysql原因很简单/data 挂载点往往单独分区出问题重装系统不会把数据带走它也不受系统盘扩容限制。你如果自己的机器分区规划不同路径随意但下面的所有步骤要跟着保持一致。3. 源码下载与CMake配置参数逐项拆解依赖和用户就绪后进入核心阶段拿到源码、配置编译参数。这一步是最容易“照抄出问题”的环节因为网上大量教程直接堆参数但没人告诉你怎么根据环境调整。3.1 源码包获取带不带boost是关键选择MariaDB源码包有两种发布形态普通源码包和带boost的源码包。CMake编译时MariaDB会强制要求WITH_BOOST参数指向boost库所在目录。如果你下载的是普通包就得额外下载boost并解压如果下载mariadb-11.4.x.tar.gz这种标准包它其实会自带boost的下载/检测逻辑但保险做法还是直接下载对应官方链接中带boost标识的包例如mariadb-11.4.2.tar.gz配合WITH_BOOST...指向系统解压目录。下载命令示例wget https://archive.mariadb.org/mariadb-11.4.2/source/mariadb-11.4.2.tar.gz tar -xzf mariadb-11.4.2.tar.gz cd mariadb-11.4.2注意arch/mirror源路径的版本号要按官网实际提供的数字来这里有变化不用惊讶。3.2 CMake配置实战命令及每个参数背后的理由进入源码目录后执行CMake配置。下面是我在麒麟V10上验证过的完整命令直接可以用cmake . \ -DCMAKE_INSTALL_PREFIX/usr/local/mariadb \ -DMYSQL_DATADIR/data/mariadb/data \ -DSYSCONFDIR/etc/mysql \ -DWITHOUT_TOKUDB1 \ -DWITHOUT_ROCKSDB1 \ -DWITHOUT_MROONGA1 \ -DWITH_SSLsystem \ -DWITH_ZLIBsystem \ -DWITH_BOOST~/boost_1_74_0 \ -DCMAKE_BUILD_TYPERelease逐项解释-DCMAKE_INSTALL_PREFIX/usr/local/mariadb安装根目录。选 /usr/local/mariadb 而非 /usr/local 主要是为了方便将来直接删除目录完成卸载数据库这种组件我建议独立前缀。-DMYSQL_DATADIR/data/mariadb/data数据目录和前面建的用户、目录对齐。-DSYSCONFDIR/etc/mysql配置文件目录后面新建的 my.cnf 放这里。-DWITHOUT_TOKUDB/ROCKSDB/MROONGA1这几个是MariadB对应的非InnoDB存储引擎默认会被编译但对大多数业务没用。逐一关掉能明显缩短编译时间和减少产物体积。如果你确实要用TokuDB现在基本不建议用或RocksDB直接去掉对应参数即可。-DWITH_SSLsystem优先使用系统自带的OpenSSL而不是自带的老版本。麒麟V10自带的OpenSSL版本较新对接安全合规也更有保障。-DWITH_ZLIBsystem使用系统压缩库避免静态链接带来的体积和更新问题。-DWITH_BOOST~/boost_1_74_0这里要注意如果系统用apt装了libboost-dev可以直接指定/usr/include否则下载boost解压后指向该路径。麒麟V10的apt源里有libboost-dev包能用系统的就用系统的最省事。-DCMAKE_BUILD_TYPERelease启用编译优化生产环境必选不要用Debug模式。如果CMake配置中途报错先看输出末尾的具体错误绝大多数情况都是缺依赖或BOOST路径不对。把报错关键词丢到搜索引擎一般能快速定位。3.3 一个必须提前避开的配置坑麒麟V10的PAM可插拔认证模块头文件路径和标准Debian略有差异。如果你看到类似Could NOT find PAM的报错不要慌执行下面的命令再重新配置一次即可sudo apt install -y libpam0g-dev另外提醒一下如果你的系统环境里同时存在多个Boost版本务必检查CMake实际找到的是哪一个。建议用-DCMAKE_VERBOSE_MAKEFILEON打开配置日志检查关键路径避免后续编译阶段出现头文件版本错乱。4. 编译、安装与数据库初始化全流程配置完成后进入编译阶段这个阶段最考验耐心也是大家容易中途放弃的节点。4.1 make编译时长与资源控制编译命令本身不复杂make -j$(nproc)nproc返回CPU核心数-j参数指定并行编译任务数。按我的实测4核虚机约35到45分钟8核物理机约15到20分钟16核以上基本10分钟内搞定这里有两个很有价值的建议如果编译中途因为内存不足报错典型日志是internal compiler error: Killed不要直接加-j反而要降低并行度比如改成make -j2甚至make -j1让每个编译任务有足够内存。编译期间最好别开一堆重型应用16GB内存的机器跑-j8时内存占用容易到10GB左右SSH别被挤掉就行。4.2 make install与安装后目录结构确认编译结束无报错后安装sudo make install这一步会把所有二进制、库文件、头文件、man文档复制到/usr/local/mariadb下。安装完成后执行ls /usr/local/mariadb/bin如果看到mariadb、mariadbd、mariadb-install-db、mariadb_safe这些可执行文件就说明安装已经成功。这里有个细节你可能注意到现代MariaDB的命令都带mariadb前缀和传统MySQL的命名不一样前者其实是官方新命名规范功能完全一样。4.3 初始化数据目录与首次启动初始化系统库表是安装后最重要的一个环节sudo /usr/local/mariadb/bin/mariadb-install-db \ --usermysql \ --basedir/usr/local/mariadb \ --datadir/data/mariadb/data这里如果提示mysqld_safe权限问题检查/usr/local/mariadb目录属主是否已经是mysql用户安装目录建议chown -R mysql:mysql /usr/local/mariadb也做一遍。初始化成功的标志是看到两个Success或类似提示并且 /data/mariadb/data 下出现mysql、performance_schema、sys等目录。接下来手动启动验证sudo -u mysql /usr/local/mariadb/bin/mariadbd \ --basedir/usr/local/mariadb \ --datadir/data/mariadb/data \ --socket/tmp/mysql.sock \ --port3306 \ --pid-file/tmp/mysql.pid 等几秒后检查进程ps aux | grep mariadbd能看到进程稳定挂着就说明数据库本身没有问题可以进入下一步系统服务化配置。5. 配置systemd服务让它开机自启、平稳运行手动启动只适合验证真正生产环境必须做成systemd服务让系统自动托底管理进程生命周期。5.1 编写mariadb.service文件创建配置文件sudo vim /etc/systemd/system/mariadb.service写入以下内容[Unit] DescriptionMariaDB database server Afternetwork.target [Service] Typesimple Usermysql Groupmysql ExecStart/usr/local/mariadb/bin/mariadbd --basedir/usr/local/mariadb --datadir/data/mariadb/data --socket/tmp/mysql.sock --port3306 ExecReload/bin/kill -HUP $MAINPID Restarton-failure RestartSec5s PrivateTmptrue LimitNOFILE65535 [Install] WantedBymulti-user.target几个关键点Typesimple配合ExecStart直接指定二进制即可不用像老式SysV脚本那样启动后再fork。Restarton-failure是数据库服务保活最基础的一道防线。LimitNOFILE65535必须加上数据库对文件描述符的需求远高于普通应用默认1024连接数稍高就会报Too many open files。socket路径和pid路径尽量保持一致后面工具连接都靠它。然后依次执行sudo systemctl daemon-reload sudo systemctl enable mariadb sudo systemctl start mariadb systemctl status mariadb看到active (running)就说明服务化成功。5.2 防火墙与安全初始化麒麟V10默认可能开着firewalld。如果数据库要对局域网开放需要放行3306端口sudo firewall-cmd --permanent --add-port3306/tcp sudo firewall-cmd --reload如果只在本地使用比如只服务本机应用这一步可以跳过反而更安全。然后执行安全初始化脚本删除默认匿名账户、设置root密码sudo /usr/local/mariadb/bin/mariadb-secure-installation跟着交互提示操作root密码设一个强度足够的是否删除匿名用户选Y是否禁止root远程登录如果业务都是本机连接选Y是否删除test库选Y。这套流程和MySQL原版几乎一致。5.3 my.cnf基础配置建议创建 /etc/mysql/my.cnf写入实际生产可用的配置[mysqld] basedir/usr/local/mariadb datadir/data/mariadb/data socket/tmp/mysql.sock port3306 character-set-serverutf8mb4 collation-serverutf8mb4_general_ci bind-address127.0.0.1 max_connections500 innodb_buffer_pool_size1G innodb_log_file_size512M slow_query_log1 slow_query_log_file/data/mariadb/slow.log long_query_time2参数怎么定要看机器内存和业务负载。innodb_buffer_pool_size我一般设为物理内存的50%到70%只跑数据库的机器这个值决定InnoDB在内存里缓存多少数据和索引太小人会频繁读磁盘太大会导致内存紧张。max_connections默认151在并发稍高的场景不够用但也不要盲目调到几千每个连接都要占内存根据实际并发去压测调整。6. 踩坑实录编译安装全过程的卡点与排查思路这部分是我最想分享的因为网上教程大多只写“正常流程”不写“失败了怎么办”。下面几个坑都是我实际在麒麟V10上遇到并解决的能帮你省下半天折腾时间。6.1 找不到libncurses/termcap的CMake报错现象CMake配置阶段报Could NOT find Curses (missing: CURSES_LIBRARY CURSES_INCLUDE_PATH)或者编译过程中出现tinfo相关的链接错误。根因MariaDB客户端部分需要curses库终端屏幕控制而麒麟系统的apt包里libncurses-dev和libncurses5-dev间存在符号链接问题导致cmake探测不到完整的头文件。解决链路sudo apt install -y libncurses-dev libncurses5-dev sudo ln -s /usr/lib/x86_64-linux-gnu/libncurses.so /usr/lib/libncurses.so sudo ln -s /usr/lib/x86_64-linux-gnu/libtinfo.so /usr/lib/libtinfo.soARM机器把x86_64-linux-gnu替换成aarch64-linux-gnu然后重新执行cmake命令。这个软链接本质是让cmake在找不到默认路径时能定位到实际的库文件。经验麒麟V10虽然基于Debian但部分dev包的文件布局和Debian原生有细微差异。用软件包管理器装好依赖后如果cmake还报找不到检查 /usr/lib 和 /usr/lib/x86_64-linux-gnu 下是否存在同名so文件缺了就软链。6.2 编译中途“internal compiler error: Killed”现象make执行到一半通常在编译sql/或storage/innobase下的大文件时终端输出g: fatal error: Killed或internal compiler errormake中断。根因这是内存不足导致g进程被杀。MariaDB源码中InnoDB相关文件编译开销极大单文件就可能吃掉2GB以上内存。虚机分配的内存要是只有2到4GB开8个并行编译任务必炸。解决链路第一步查看物理内存free -h确认是否真的紧张第二步把并行度降到make -j2甚至串行make -j1先确保能编译完第三步临时增加swap空间救急编译完成可删sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile经验编译资源这件事宁可在前面多花时间也不要卡在半路。如果机器给的是2核4G这种低配直接用-j1慢慢跑去喝杯茶回来就好。6.3 初始化数据目录后root无法本地登录现象用mariadb-install-db初始化成功启动服务后执行/usr/local/mariadb/bin/mariadb -uroot却报ERROR 1698 (28000): Access denied for user rootlocalhost。根因现代MariaDB默认root的认证插件是unix_socket即只允许系统root用户通过本地socket免密登录普通方式登录会被拒绝。这是安全设计不是故障。解决链路用系统root账户执行sudo /usr/local/mariadb/bin/mariadb能直接进因为unix_socket匹配进入后执行ALTER USER rootlocalhost IDENTIFIED VIA mysql_native_password USING PASSWORD(你的密码); FLUSH PRIVILEGES;然后执行/usr/local/mariadb/bin/mariadb -uroot -p输入密码即正常登录经验如果业务上需要root账号走TCP远程连接还需要额外创建权限账号并执行CREATE USER admin% IDENTIFIED BY 密码;再赋所有权限。但生产环境强烈不建议开root远程登录要么建专用账号要么保持本地socket认证。6.4 老版本兼容性引发的大小写敏感问题现象从MySQL迁移到新编译的MariaDB之后应用报找不到表名。根因MariaDB的lower_case_table_names参数默认值在不同初始化方式下可能不一致。MySQL 8默认是0表名大小写敏感而部分Linux发行版默认设置会导致表名小写化。解决链路初始化之前就把参数写进my.cnf明确设置一个值比如 Linux环境建议lower_case_table_names0保持和默认一致如果是从Windows迁移应用表名全是小写的可以设1避免大小写不一致。注意这个参数必须在mariadb-install-db初始化之前设置初始化之后再改会导致表名找不到的诡异问题。经验上面这条属于老调重弹但特别容易忽略的点。我的习惯是把my.cnf先建好、参数先定好再执行初始化而不是初始化完再补配置。7. 最终可用性验证和日常运维补充服务正常运行后我习惯做一套基本验证再交付。这套验证能覆盖“数据库是否真的可用”的每一层。# 测试TCP连接 mysql -h127.0.0.1 -P3306 -uroot -p -e select version(); # 测试socket连接 mysql -uroot -p -e show variables like version; # 测试innodb基本功能 mysql -uroot -p -e create database testdb; use testdb; create table t1(id int primary key, name varchar(20)); insert into t1 values(1,ok); select * from t1;如果以上命令全部通过编译安装的MariaDB就算真正可用。日常维护上补充三点都是生产中用得上的经验日志查看用journalctl -u mariadb -f -n 50而不是去 /var/log 翻乱七八糟的系统日志备份直接跑mariadb-dump脚本化之后放cron每天定时全量备份到独立磁盘升级小版本时源码包重新执行CMakemakemake install即可数据目录不动但最好先备份。另外那些编译参数在后续版本升级时要保持一致性尤其是CMAKE_INSTALL_PREFIX和DATADIR不能变变了等于拆库。我个人编译过几十次之后最大的感受是麒麟V10上编译MariaDB真正的难点不在CMake参数而在依赖环境的处理。只要把依赖的坑填平了剩下的就是等待编译完成所以这篇文章把依赖检查放在了最前面希望你照着走的时候少走弯路。如果第一次编译失败别急着怀疑源码有问题先看依赖和资源八成是这两块没到位。