银河麒麟V10上部署MySQL 8.0.28:tar包安装与Systemd托管全记录
在国产操作系统上部署MySQL是这两年绕不开的话题尤其是银河麒麟V10项目里新采购的服务器几乎都是这套系统。我最近在一台麒麟V10服务器上装MySQL 8.0.28网上搜到的不少教程要么只讲了半截要么就是拿CentOS的步骤硬套结果在依赖库、初始化、自启动这几个环节接连踩坑。这篇文章把整个安装过程重新捋一遍从版本确认到tar包安装从依赖处理到Systemd托管最后附上错误排查清单给同样需要在麒麟V10上装MySQL的人一份可以直接照着做的记录。1. 动手之前先确认系统底细避免装到一半翻车很多人在国产系统上装软件失败第一反应是这不就是CentOS吗怎么不兼容其实多数问题出在没确认系统具体的子版本和架构就直接开装。银河麒麟V10有多个分支有的基于RHEL 7的思路有的基于RHEL 8的思路x86和ARM的包还不一样连操作系统的glibc版本都会直接影响MySQL官方二进制包能否跑起来。1.1 查看版本、架构和包管理器类型登录服务器后我习惯先执行这几条命令把系统底细摸清楚cat /etc/os-release uname -m rpm --version || dpkg --version/etc/os-release会显示系统的名称和版本ID能从里面看出是基于哪一类包的生态。比如输出里出现PRETTY_NAMEKylin Linux V10时还需要再多看一眼ID和VERSION_ID字段判断它更贴近哪个上游版本的包管理风格。uname -m确认架构x86_64的机器可以放心使用官方针对x86发布的二进制包如果输出是aarch64那就要找ARM版本用错包会出现无法解析或启动即崩溃的问题。1.2 检查系统是否已经装了老版MySQL或MariaDB这一步容易被忽略。麒麟服务器版经常预装MariaDB的客户端库或完整服务如果直接启动MySQL 8.0的服务很可能因为端口占用、socket文件冲突或者库文件版本不一致导致启动失败。我一般这样查rpm -qa | grep -iE mysql|mariadb有输出的话需要先评估哪些可以卸载。如果只是mariadb-libs这类底层库建议卸载后再装MySQL否则后面rpm安装MySQL时会提示冲突如果本身装了mariadb-server那更需要先停服、清掉数据目录避免初始化时被历史数据干扰。预装的mariadb数据目录和相关配置建议先做好备份再清理。确认完版本、架构和已有软件情况后就可以确定安装策略了。2. 选RPM BUNDLE还是通用tar包取决于你的实际使用环境MySQL 8.0.28的官方安装方式有rpm、deb、tar包几种。放到银河麒麟V10上实际可用的主要是RPM Bundle和Linux通用tar包两种。两种方式没有绝对好坏得看这台机器之后怎么管。下表是两种方式的初步对比对比项RPM Bundle通用二进制tar包依赖处理自动处理大部分依赖但需要逐个rpm安装不依赖系统包手动准备运行库安装位置按RPM规范安装到固定路径可自定义目录结构完全可控配置文件自动生成样例路径固定手动编写升级回滚通过rpm管理需要自行维护软链和版本多实例部署较麻烦更适合与麒麟系统的匹配度需要选对el版本否则依赖报错只要glibc满足适配性更广2.1 RPM Bundle适合用系统包管理习惯的维护者RPM Bundle是一个包含多个rpm的压缩包里面按common、libs、client、server等模块拆开。安装时顺序一般是rpm -ivh mysql-community-common-8.0.28-1.el8.x86_64.rpm rpm -ivh mysql-community-libs-8.0.28-1.el8.x86_64.rpm rpm -ivh mysql-community-client-8.0.28-1.el8.x86_64.rpm rpm -ivh mysql-community-server-8.0.28-1.el8.x86_64.rpm注意rpm包名中间的el8标识。如果银河麒麟V10的系统生态更贴近el7就要选el7的rpm包选错了会出现依赖库版本不匹配的报错。RPM安装的优势是后续可以用rpm -e卸载、用rpm -qa查询和系统包管理整合度高适合习惯了yum管理方式的维护者。2.2 通用tar包生产环境中我更推荐的方式MySQL官方提供了Linux Generic版本的tar包它是一个编译好的二进制包不依赖系统的rpm体系只要运行库齐全就能直接使用。tar包方式的优点体现在目录完全可控——可以将MySQL独立安装到指定路径与系统其他组件解耦升级时直接换软链就行。在国产操作系统上这种不依赖系统包管理的特性反而降低了兼容性风险。我最终在麒麟V10上选择tar包还有一个现实原因rpm方式在依赖不全时不只会提示缺哪个包还可能因为麒麟仓库里的某个库版本比RHEL高导致rpm校验失败解决起来很麻烦。tar包只要解决libaio和numactl两个库后面的事就和自己管目录一样简单。选定了安装方式接下来进入核心安装步骤。3. tar包安装MySQL 8.0.28的完整流程含初始化细节以下步骤基于mysql-8.0.28-linux-glibc2.12-x86_64.tar.xz这个包麒麟V10 x86环境实测可复现。全程使用root操作所有命令和路径都以我实际验证过的为准。3.1 创建用户与基础目录MySQL不允许用root用户直接运行需要先创建专用的系统用户groupadd mysql useradd -r -g mysql -s /bin/false mysql mkdir -p /opt/mysql mkdir -p /opt/mysql/data mkdir -p /opt/mysql/logs数据目录单独划分出来是因为后续备份、扩容、迁移时只需处理数据目录。/opt/mysql作为软件根目录软件包和配置都放这里。-s /bin/false设置该用户不能登录shell这样即使被外部利用也无法直接获得命令行符合最小权限原则。3.2 解压并布局目录将下载的tar包上传到服务器后执行tar -xvf mysql-8.0.28-linux-glibc2.12-x86_64.tar.xz -C /opt/mysql mv /opt/mysql/mysql-8.0.28-linux-glibc2.12-x86_64 /opt/mysql/mysql cd /opt/mysql chown -R mysql:mysql /opt/mysql注意压包名中的glibc2.12标识的是编译时依赖的最低glibc版本不代表只能在2.12上运行。麒麟V10的glibc版本一般高于2.28跑这个包没有问题。3.3 编写核心配置文件/etc/my.cnftar包安装需要手动创建配置文件。我在/etc/my.cnf写入以下内容[mysqld] basedir/opt/mysql datadir/opt/mysql/data socket/opt/mysql/mysql.sock pid-file/opt/mysql/mysql.pid log-error/opt/mysql/logs/error.log port3306 character-set-serverutf8mb4 collation-serverutf8mb4_general_ci lower_case_table_names1 default-time-zone08:00 max_connections500 innodb_buffer_pool_size1G innodb_log_file_size256M这里的重点是目录路径不能错。basedir指软件根目录datadir指数据目录socket文件建议放到MySQL自己的目录下而不是系统默认的/tmp因为/tmp目录在某些系统上会被清理或受权限限制会导致客户端连接时出现socket文件找不到的问题。lower_case_table_names1默认开启原因是如果之后需要把数据目录迁移到其他平台忽略大小写的通用性更好而且Linux平台默认对表名大小写敏感很多业务迁移时会受影响。innodb_buffer_pool_size我最初设为默认值但生产环境读多写少调成1G后查询效率明显提升后续根据物理内存再按比例调整。3.4 初始化数据目录MySQL 8.0已经废弃了mysql_install_db初始化统一用mysqld --initialize。进入软件目录后/opt/mysql/bin/mysqld --defaults-file/etc/my.cnf --initialize --usermysql--initialize会生成root临时密码密码打印在错误日志里。初始化完成后必须立刻查看日志cat /opt/mysql/logs/error.log | grep temporary password如果这条命令没有输出说明初始化日志里没有临时密码这可能是因为初始化过程报错中断了。查看整个日志会被各种初始化信息刷屏用grep过滤是因为MySQL生成的临时root密码一定会出现在带这个关键词的行里。初始化成功后检查/opt/mysql/data目录是否生成了mysql系统库文件若生成则说明初始化正常。3.5 启动服务并安全登录完成初始化后先尝试用mysqld_safe方式启动这样能快速判断程序本身是否正常/opt/mysql/bin/mysqld_safe --defaults-file/etc/my.cnf sleep 5 /opt/mysql/bin/mysqladmin -uroot -p临时密码 ping能ping通说明服务正常。如果想要更规范的启动方式直接使用后面的Systemd托管方案。首次登录时的临时root密码是有有效期的若不尽快修改密码后续操作会提示密码过期。4. 麒麟V10专属依赖坑libaio、numactl和mariadb冲突这部分是重头戏。如果安装过程中遇到启动报错多数都是下面几个依赖或冲突导致的提前解决能省大量排查时间。4.1 卸载老版mariadb-libs解除rpm依赖冲突麒麟V10预装mariadb-libs是比较常见的情况。直接装RPM Bundle时会因为和mariadb-libs的文件冲突而报错必须处理。根据是否依赖rpm体系有两种做法如果选RPM安装卸载mariadb-libs前先检查哪些软件对它依赖rpm -qa | grep mariadb rpm -e --nodeps mariadb-libs使用--nodeps说明这样确实可以强制卸载但如果系统中还有别的软件需要libmysqlclient卸载后那些软件会无法运行。所以更稳妥的方法是在uninstall前先确认所有依赖方都不重要或可以进行替代处理。如果选tar包官方二进制自带了客户端库不依赖系统的mariadb-libs卸载它之后完全不影响MySQL运行。4.2 libaio库缺失导致初始化失败MySQL 8.0的InnoDB存储引擎依赖libaio库如果系统里没有安装初始化时日志会出现错误提示找不到librt或libaio相关的库文件。yum install -y libaio libaio-devel这两个包在麒麟自带的Yum源里一般都有直接安装即可。安装后用ldd验证库是否加载成功ldd /opt/mysql/bin/mysqld | grep libaio如果有输出说明依赖已满足没有输出则需再次确认库文件路径和ld.so.conf中的库搜索路径避免库文件装上了但二进制运行时找不到。4.3 libnuma.so.1缺失导致进程无法启动这是我这次装机遇到最隐蔽的问题。初始化完成后启动mysqld进程莫名其妙闪退。查看错误日志时只有一行error while loading shared libraries: libnuma.so.1。原因在于MySQL 8.0.28的二进制编译时链接了NUMA库用于内存分配策略优化。解决方式很直接yum install -y numactl-libs安装完后重新执行ldd /opt/mysql/bin/mysqld | grep numa看到libnuma.so.1路径存在就恢复正常了。这类运行库问题在CentOS上偶尔也会遇到但在麒麟V10上出现的概率更高所以安装前就应先把libaio和numactl-libs装好避免启动后反复排查。4.4 防火墙和SELinux远程连接失败的一大诱因数据库服务启动后本地能连但远程连不上排在防火墙之后的原因依次是bind-address问题、用户授权问题、SELinux问题。检查远程连接时先看3306端口是否被防火墙策略拦截。从安全角度出发我不建议简单粗暴地关闭防火墙更推荐针对端口放行firewall-cmd --zonepublic --add-port3306/tcp --permanent firewall-cmd --reload如果之前执行过setenforce 0临时关闭SELinux重启后又会回到enforcing状态。对数据库主机而言若业务确实需要在较高安全级别下运行单端口放行即可不必全局关闭SELinux。确实遇到SELinux拦截时用ausearch -m avc查日志确认原因再做针对性规则调整。4.5 ARM架构服务器的额外注意事项如果目标服务器是飞腾、鲲鹏等ARM架构前面所有安装步骤同样适用但下载时一定要选择aarch64版本或明确标注支持ARM的包。ARM环境的安装坑不在步骤上而在二进制包选择上——用通用的x86_64包去初始化启动时会提示无法执行的二进制格式。此外ARM版本的MySQL在初始化日志里可能输出更多的警告信息部分硬件平台io_uring不可用时会默认回退到libaio模式日志出现This is a warning类提示不必恐慌确认进程还活着即可。5. 初始化密码修改、远程用户授权和认证插件调整初始化完成后第一件事是改root密码和调整访问权限。MySQL 8.0默认的认证插件是caching_sha2_password这个插件对老客户端不友好实际业务中几乎所有团队都希望改成兼容方式。5.1 使用临时密码登录并修改root密码用临时密码登录/opt/mysql/bin/mysql -uroot -p登录后执行修改密码ALTER USER rootlocalhost IDENTIFIED BY 新强密码; FLUSH PRIVILEGES;8.0的密码校验策略默认等级中等至少需要8位混合大小写字母、数字和符号。如果不想用默认策略可以降低校验等级SHOW VARIABLES LIKE validate_password%; SET GLOBAL validate_password.policy LOW;生产环境一般不建议降到LOW只有在内网测试环境或临时开发机时这样操作。密码修改后要立刻验证新密码能否登录避免改完密码却遗忘。5.2 caching_sha2_password插件带来的连接兼容性问题MySQL 8.0默认使用caching_sha2_password认证插件但老版本客户端连接时会出现Authentication plugin caching_sha2_password cannot be loaded的错误。早期很多5.7时代的客户端、部分编程语言的旧驱动都无法直接识别这个插件。在不升级客户端的前提下常见做法是让新建用户使用mysql_native_password认证方式CREATE USER app_user% IDENTIFIED WITH mysql_native_password BY 密码; GRANT ALL PRIVILEGES ON yourdb.* TO app_user%; FLUSH PRIVILEGES;如果要让root用户也支持老客户端连接ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 新密码;注意mysql_native_password在MySQL 8.4开始会被移除但8.0.28版本使用它没有问题。对于新项目而言尽量让客户端升级到支持caching_sha2_password的版本更好。5.3 创建远程访问用户并授权在开发测试场景中远程工具连接数据库是常态。创建用户时要用%而不是localhost否则连不上CREATE USER dev% IDENTIFIED BY 密码; GRANT ALL PRIVILEGES ON *.* TO dev% WITH GRANT OPTION; FLUSH PRIVILEGES;这里WITH GRANT OPTION表示该用户可以给其他用户授权生产环境一般不建议给普通应用账号加这个权限只给账号必要的库权限。使用Navicat或DBeaver连接测试时如果提示Access denied优先排查授权如果是连接超时优先排查防火墙和bind-address。5.4 修改bind-address允许网卡对外提供服务MySQL默认只监听localhostbind-address是127.0.0.1。如果远程连接一直超时但防火墙没拦检查一下这项配置[mysqld] bind-address0.0.0.0设置为0.0.0.0表示监听所有网卡。安全要求高的环境可以直接绑定业务网卡IP比如bind-address192.168.1.10。修改后必须重启MySQL才生效。这一步很容易被漏掉很多人卡在远程连不上那一步代码、账号、防火墙全查遍了最后发现是bind-address的问题。6. 用Systemd托管mysqld实现开机自启和状态管理tar包安装方式不会自动生成Systemd服务如果不手动配置每次开机都要手工启动MySQL这在生产环境中无法接受。给MySQL创建Systemd服务是tar包安装的收尾关键步骤。6.1 编写mysqld.service单元文件在/usr/lib/systemd/system/mysqld.service中写入[Unit] DescriptionMySQL Server 8.0.28 Afternetwork.target Aftersyslog.target [Service] Usermysql Groupmysql Typesimple ExecStart/opt/mysql/bin/mysqld --defaults-file/etc/my.cnf ExecStop/opt/mysql/bin/mysqladmin --defaults-file/etc/my.cnf -uroot -p密码 shutdown Restarton-failure LimitNOFILE65536 [Install] WantedBymulti-user.targetTypesimple表明ExecStart启动的进程就是主服务进程不需要等待额外心跳。User和Group指定为mysql避免用root运行MySQL进程。LimitNOFILE提高文件描述符上限高并发连接时需要这个设置。ExecStop里的密码参数如果觉得暴露不好可以改成ExecStop/opt/mysql/bin/mysqladmin --defaults-file/etc/my.cnf -uroot shutdown配合/root/.my.cnf文件存放登录凭据mysqladmin读取配置文件中的账号密码不把密码写在service文件里。这种写法更规范运维同事看到service文件也不会摸不着头脑。6.2 重新加载配置并启用开机自启systemctl daemon-reload systemctl enable mysqld systemctl start mysqld systemctl status mysqld执行enable后系统会在multi-user.target依赖里建立软链实现开机自启。验证自启是否真正生效可以reboot后重新执行systemctl status mysqld确认服务状态是active。这里可以明确一点不要用chkconfig去懂得这套服务麒麟系统上Systemd是标准管理方式chkconfig面向老版本SysV脚本两者不能混用。6.3 日志管理与日常命令MySQL运行日志默认输出到/opt/mysql/logs/error.log。查看启动阶段日志tail -100 /opt/mysql/logs/error.log排查连接问题时可以看/var/log/messages里是否有进程被kill的记录。日常管理命令汇总操作场景命令查看运行状态systemctl status mysqld重启服务systemctl restart mysqld安全关闭服务systemctl stop mysqld查看监听端口ss -tlnp | grep 3306进程是否存在ps -ef | grep mysqld重启服务要比kill进程可靠。直接kill掉mysqld进程可能导致InnoDB崩溃恢复流程虽然有redo log保护不至于丢数据但恢复过程会耗时高负载情况下甚至可能影响业务感知。7. 装完之后的验证手法与典型故障排查清单服务正常启动、root密码能登录并不代表这台MySQL可以安心上线。压测时间有限但几个基础验证项不能省。7.1 基础功能与连接能力验证本地执行几条查询确认基本功能SELECT VERSION(); SHOW DATABASES; SELECT port, socket, datadir;然后从另一台机器用客户端工具尝试连接。能正常查询说明网络层、授权层都通了。检查系统资源占用情况top -p $(pgrep -d, mysqld) free -g df -h /opt/mysql内存不到2G的情况下InnoDB缓冲池配置过大会导致内存交换数据目录所在分区空间不足会导致事务提交失败——这两个是最常见的稳定运行隐患。7.2 启动报错与连接失败的定位路径遇到启动即失败时不要盲目重启一步步看日志和依赖故障现象排查顺序启动后马上退出看error.logldd确认libaio/numactl初始化失败检查目录权限确认libaio已装本地能连远程不能连检查firewalld放行检查bind-addressAccess denied检查user host是否含%客户端认证插件报错调整用户为mysql_native_password占用端口冲突netstat -tlnp检查3306端口是否被占用每个故障都需要确认前置条件。比如启动后马上退出要先确认是否为root用户启动——以root用户运行mysqld但缺少--usermysql参数时进程会以root身份启动并拒绝运行。7.3 一次真实排错案例hash索引初始化超时之前在一台ARM架构麒麟V10上装8.0.28初始化时日志一直提示初始化时间较长最后报了一个Failed to initialize ldata directory的错误。排查后发现是系统性能评估脚本占满了CPU初始化程序在内核调度上得不到足够的CPU时间导致初始化超时。把负载降下来后重新初始化数据目录顺利生成。这提醒我初始化前先检查系统负载初始化失败后必须清空数据目录不要在同一目录上反复重试。经过这一轮安装和验证MySQL 8.0.28在银河麒麟V10上运行稳定服务重启、远程连接、日常查询全部正常。整个过程下来最大的体会是国产系统环境装软件耐心和日志排查比命令本身更重要。每一条报错日志都指向具体的依赖或配置问题只要按依赖库、权限、网络、认证这几个维度逐步排查基本都能在半小时内解决问题。如果谁在安装过程中遇到文中没有覆盖的报错建议把error.log的开头日志和操作系统版本发出来顺着日志往下追比盲目重装有效得多。