先说说我和这套系统的缘分。前一阵帮朋友在银河麒麟V10的服务器上部署MySQL,原本以为半小时能搞定的小事,结果从下午折腾到晚上——不是缺依赖就是目录权限不对,好不容易装完了,客户端又连不上,最后还因为字符集问题被一长串乱码教育了一顿。网上关于麒麟系统装MySQL的资料不少,但很多是零散片段,要么写得过于简略,要么命令直接照搬CentOS结果各种报错。所以这次把完整过程整理成一篇能照着抄的实操记录,尤其是那些不说就很容易踩的坑,一并写清楚,给需要在麒麟系统上部署MySQL的朋友省点时间。
这篇内容主要解决三个问题:怎么确认自己的麒麟系统该装什么包;怎么用最稳的方式把MySQL 8.0装好并启动;装完之后怎么处理远程连接、字符集、开机自启这些绕不开的细节。无论你是刚接触Linux的新手,还是被国产系统迁移折腾的运维老哥,这套流程都适用。
1. 安装前的系统确认与方案选型
1.1 先确认麒麟版本和CPU架构,别装错包
很多人上来就搜“麒麟系统安装MySQL”,然后复制一段命令直接执行,结果各种报错。第一个坑就出在“麒麟系统”这四个字上——银河麒麟V10严格来说是一个系列,有桌面版、服务器版,底层有的基于Debian系,有的基于RHEL/CentOS系,CPU架构又有x86_64和aarch64(ARM)之分。
装错包最典型的现象就是执行mysqld时提示“cannot execute binary file: Exec format error”,或者干脆命令不存在。所以动手之前,先跑三行命令确认环境:
cat /etc/os-release cat /etc/kylin-release 2>/dev/null uname -m第一行看系统版本和包管理基础,第二行看具体的麒麟发行版本信息,第三行看CPU架构。我这次安装的机器输出是x86_64,系统是基于CentOS系的银河麒麟服务器版,后面命令就是按这个环境来的。如果你的输出是aarch64,那下载MySQL安装包时要选ARM版本,其余流程基本一致。
还有一个判断技巧:看系统自带的是apt还是yum/dnf。有apt的走Debian系安装逻辑,有yum的走RHEL系安装逻辑。这篇内容主线以RHEL系为主,Debian系的差别我在对应位置会额外标注。
1.2 三种安装方式怎么选
同一个MySQL,在不同Linux发行版上安装方式五花八门,归纳起来无非三种:系统源安装、官方二进制包安装、源码编译安装。
| 安装方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 系统源(yum/apt) | 命令简单,依赖自动处理 | 版本通常偏老,有的麒麟源里默认是MariaDB而非MySQL | 内网测试、对版本不敏感 |
| 官方二进制tar包 | 可自定义版本,不污染系统库,离线可部署 | 依赖需要自己补齐,服务脚本要自己配置 | 生产环境、内网部署,本文采用 |
| 源码编译 | 可深度定制编译参数 | 编译慢、依赖多、后期升级麻烦 | 有特殊优化需求时才考虑 |
系统源安装确实省事,但在麒麟上有个很尴尬的问题:你执行yum install mysql-server,装出来可能不是MySQL而是MariaDB。不是说MariaDB不好,而是很多业务系统是按MySQL特性开发的,迁移过去容易出现兼容性问题。源码编译又太折腾,一个make install跑下来可能就是一晚上,对大多数人来说没必要。
1.3 我为什么选官方通用二进制包
对比下来,官方提供的Linux通用二进制包(glibc版本)是最平衡的方案。它本质上就是一套已经编译好的MySQL程序文件,解压就能用,不依赖系统的包管理器,x86和ARM都有对应版本,而且完全可以离线部署——在一台能联网的机器上把包下载好,传到内网麒麟机器上解压即可,这在很多要求离线交付的环境里很关键。
缺点是依赖库需要自己留意,比如libaio、numactl这种基础库,后面会专门讲怎么装。另外MySQL的启动服务、开机自启这些也需要手工配置,但一次配好之后基本不用再动。整体流程可控、思路清晰,出了问题也知道从哪里排查。
2. 环境准备与依赖处理
2.1 清理冲突组件,腾出3306端口
麒麟系统尤其是服务器版,预装软件里可能已经有mariadb相关的包了,如果直接装MySQL,两者抢数据库目录、抢3306端口,轻则启动失败,重则数据错乱。先检查一下:
rpm -qa | grep -i mariadb ss -lntp | grep 3306第一行查MariaDB包,第二行查3306端口占用。如果rpm -qa有输出,执行yum remove -y mariadb*清理掉;如果3306端口被其他进程占着,要确认是谁在用,避免误杀别的服务。
另外,仔细看一下系统是否装了libaio,这个库MySQL 8.0必须用到,缺失时初始化或启动会直接报错:error while loading shared libraries: libaio.so.1。就算当前还没报,也不代表后面不会踩,建议现在就把依赖补齐。
2.2 把依赖包装齐,少一个都起不来
基于RHEL系的麒麟系统,执行:
yum install -y libaio numactl-libs如果是Debian系的麒麟系统,执行:
apt install -y libaio1 libnuma1numactl-libs(或libnuma1)是NUMA内存管理相关的库,MySQL在启动时会调用,缺少同样会报共享库加载错误。这两个包装了基本就能覆盖MySQL 8.0在Linux上的起步依赖。
有朋友会问,系统里没有外网,能不能离线装依赖?可以。找一台相同架构、相同版本的麒麟机器,用yumdownloader libaio numactl-libs把rpm包下载下来,再拷贝到目标机器上执行yum localinstall安装;或者直接用麒麟系统安装ISO里的 Packages 目录,里面就能找到对应rpm包。Debian系则用apt download或dpkg -i处理。这也再次印证了选官方二进制包的好处:最大头的事前依赖就这两三个,其他的随包自带。
2.3 规划目录和专用账户
专业一点的部署习惯是“程序目录、数据目录、日志目录分离”。程序目录放安装文件,数据目录放数据文件,日志目录放错误日志和运行日志。这样做的好处很直白:数据盘挂载、备份、灾备时可以只针对数据目录操作;权限控制也更清晰,没有那么容易误删程序文件。
我这次按下面的结构规划:
/usr/local/mysql # 程序安装目录 /data/mysql/data # 数据文件目录 /data/mysql/logs # 日志文件目录 /data/mysql/run # pid、socket等运行时文件然后创建MySQL专用账户:
groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql mkdir -p /data/mysql/{data,logs,run} chown -R mysql:mysql /data/mysql这里有个细节:useradd -r创建的是系统账户,-s /sbin/nologin表示这个账户不能登录shell。MySQL服务以这个低权限用户运行,即便后续被入侵,攻击者拿到的也不是一个能直接登录系统的shell,这是非常基础但重要的安全习惯。生产环境别用root直接跑MySQL,回头看这条建议你会感谢自己。
3. 核心安装流程全实录
3.1 从官网拿包,上传解压
MySQL官方下载页面里,选择“Linux - Generic”类别下的tar包。注意区分版本号:x86_64对应Intel/AMD架构,aarch64对应ARM架构;glibc2.12一般适配较老系统,glibc2.17适配较新系统,麒麟V10基本两种都能跑,优先按系统实际架构选。下载命令示例(以x86_64的8.0.32为例):
wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.32-linux-glibc2.12-x86_64.tar.xz如果服务器不方便联网,就在本地下载后通过scp、U盘等方式传到服务器。传到目标机器后解压到/usr/local目录:
cd /usr/local tar -xJf mysql-8.0.32-linux-glibc2.12-x86_64.tar.xz mv mysql-8.0.32-linux-glibc2.12-x86_64 mysql加上环境变量,让自己能在任意目录直接敲mysql命令:
echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile source /etc/profile验证一下:
mysql --version如果输出版本号,说明程序和PATH配置没问题,继续往下走。
3.2 写一份能直接用的my.cnf
/etc/my.cnf是MySQL的主配置文件。很多新手装完不写配置直接初始化,后面遇到字符集乱码、pid文件找不到、端口被占用等问题再回头补,反而更乱。我建议初始化之前就把配置写好,这是整篇教程里最值得多花两分钟的地方。
我的配置文件如下,你可以在这个基础上删减:
[mysqld] user=mysql basedir=/usr/local/mysql datadir=/data/mysql/data socket=/tmp/mysql.sock pid-file=/data/mysql/run/mysqld.pid port=3306 server-id=1 log-bin=mysql-bin binlog_format=row character-set-server=utf8mb4 collation-server=utf8mb4_general_ci max_connections=500 default-storage-engine=InnoDB innodb_buffer_pool_size=512M innodb_flush_log_at_trx_commit=1 sync_binlog=1 skip-name-resolve [client] default-character-set=utf8mb4几个关键点:
character-set-server=utf8mb4和collation-server=utf8mb4_general_ci是字符集设置,现在的新项目建议直接用utf8mb4,能完整支持中文和emoji,别再用已经过时的utf8,它实际是utf8mb3,字符集支持不全。
innodb_buffer_pool_size是InnoDB缓冲区大小,一般设为物理内存的60%~70%。测试机内存2G,设512M就够了;内存大的机器可以按比例调高。注意别贪多,给系统和其他进程留一些余量,不然启动后发现内存吃紧,反而得不偿失。
skip-name-resolve这个参数建议开启,作用是让MySQL不通过DNS反向解析客户端主机名,连接速度会变快,也能避免DNS异常导致的连接超时。代价是远程授权时不能用域名匹配用户,要用IP或%通配符。
提示:如果业务系统涉及Windows上的存量数据库迁移,你可能会想到
lower_case_table_names=1让表名不区分大小写。这个参数必须在MySQL 8.0初始化之前就定好,初始化之后再改基本不生效,而且容易引发数据目录异常。要不要用,先用脑,再用命令。
其实pid-file和socket路径也要和配置一致,否则后面用mysql客户端登录时找不到socket文件,会提示“Can't connect to local MySQL server through socket”。
3.3 初始化数据目录,认清临时密码
数据目录在初始化前必须为空。如果刚才创建目录时里面有文件,或者是从别处拷贝过数据,先清空再动手:
rm -rf /data/mysql/data/* chown -R mysql:mysql /data/mysql执行初始化:
/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize --user=mysql--initialize表示初始化系统数据,并生成root用户的随机临时密码。命令执行完没有输出是正常的,重点看日志:
tail -20 /data/mysql/data/*.err日志里会出现一行类似[Note] A temporary password is generated for root@localhost: xxxxxxxx的内容,冒号后面那串就是MySQL给你的初始密码,先复制保存下来,后面第一次登录要用。
如果初始化时报错,先看是不是以下三种:包缺失、目录权限不对、datadir非空。前两种按前面步骤就能解决,第三种清理目录后再跑一次。
3.4 启动MySQL并验证
初始化完成后,启动方式有两种,先讲最快的手动启动:
/usr/local/mysql/support-files/mysql.server startmysql.server是MySQL官方自带的服务脚本,内部会调用mysqld_safe帮我们拉起并守护进程。启动后确认一下状态:
ps -ef | grep mysqld看到mysqld进程在跑,再用初始密码登录:
mysql -uroot -p提示输密码时粘贴刚才保存的临时密码(注意终端不支持Ctrl+V粘贴时可能要用鼠标右键或Shift+Insert),登录成功后执行:
SHOW VARIABLES LIKE 'version'; SELECT 1;能正常返回数字和版本号,说明核心功能已经通了。此时MySQL还没开机自启,重启系统后会消失,下一步处理。
3.5 配置开机自启,重启不失联
生产环境重启后MySQL必须自动拉起,这里用systemd来管最简单,也符合麒麟V10的习惯。先停掉手动启动的MySQL:
/usr/local/mysql/support-files/mysql.server stop然后创建服务文件/etc/systemd/system/mysqld.service:
[Unit] Description=MySQL Server After=network.target [Service] Type=forking User=mysql Group=mysql PIDFile=/data/mysql/run/mysqld.pid ExecStart=/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf ExecReload=/bin/kill -HUP $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target加载并启用服务:
systemctl daemon-reload systemctl enable mysqld systemctl start mysqld systemctl status mysqld这里有个容易踩的坑:PIDFile路径必须和my.cnf里的pid-file完全一致,否则systemd会警告“PID file ... not readable (yet?) after start”,虽然有时候服务能跑,但状态显示不准确,后面管理起来很别扭。
Type=forking是这套配置的关键。mysqld_safe启动后会fork出子进程并后台运行,所以要用这个类型,systemd靠PID文件来确认主进程。如果启动失败,第一件事看状态输出和MySQL错误日志,后面第五章有排查清单。
4. 密码安全与远程访问配置
4.1 拿到初始密码后第一步:改密
用临时密码登录MySQL后执行的第一个SQL,一定是改root密码:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPassword_2025!';MySQL 8.0默认密码校验策略是validate_password,对密码强度有要求——至少包含大写、小写、数字和特殊字符,长度一般不少于8位。如果你设置简单密码被拒绝,别急着关策略,那是在保护你。实在想换回宽松策略可以执行SET GLOBAL validate_password.policy = LOW;,但生产环境强烈不建议。
顺手把匿名用户和测试库清理一下:
DELETE FROM mysql.user WHERE User=''; DROP DATABASE IF EXISTS test; FLUSH PRIVILEGES;另外建议顺手执行mysql_secure_installation,这个交互脚本会引导你完成匿名用户清理、root远程登录禁用、测试库删除等安全配置,简单回答几步就行,比手动执行SQL更不容易漏。
4.2 新建业务账号,开放远程登录
直接用root账号给业务应用连数据库,属于高危操作。规范做法是建一个按业务划分的专用账号,权限精确到库表。
CREATE USER 'app_user'@'%' IDENTIFIED BY 'AppPassword_2025!'; GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app_user'@'%'; FLUSH PRIVILEGES;上面这条只给了appdb库的增删改查权限,够大部分业务用了。'%'表示允许从任意IP连接,如果业务服务器IP固定,更稳的写法是'app_user'@'192.168.1.100',可以缩小暴露面。需要让root也能远程连的话,建议新建一个管理员账号而不是直接改root@'%',方便后期审计和权限回收。
这里有一个麒麟系统上经常被忽略的细节:如果前面配置了skip-name-resolve,连接时MySQL不会做DNS反解,授权时用'%'或用具体IP都没影响;但如果两个参数之间的理解有偏差,容易出现在本机用localhost能连、远程IP却始终提示“Host is not allowed to connect”。
4.3 防火墙与SELinux,两个隐藏拦路虎
装完后远程连不上,十有八九不是MySQL的问题,而是防火墙没放行3306端口。麒麟系统如果开着firewalld:
systemctl status firewalld firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload如果不想开防火墙(仅限内网测试环境),直接:
systemctl stop firewalld systemctl disable firewalldSELinux是另一个容易忽略的因素。执行getenforce,如果输出Enforcing,建议先临时关闭测试连接:
setenforce 0确保不是SELinux在拦截后再决定长期策略。要永久关就在/etc/selinux/config里把SELINUX=enforcing改成SELINUX=disabled,改完重启生效。麒麟V10有些版本的SELinux默认就是disabled,没有这个问题的机器可以跳过。
4.4 客户端连不上?先检查认证插件
这是我在麒麟上遇到频率最高的问题。MySQL 8.0默认认证插件是caching_sha2_password,安全性更高,但老的客户端驱动——比如Navicat 12及以下版本、老版本Python的pymysql、Java老版本的JDBC驱动——不支持这种认证方式,连接时会报:
Authentication plugin 'caching_sha2_password' cannot be loaded
解决办法有两个方向。升级客户端到支持MySQL 8.0的版本是最好的选择;如果客户端暂时没法升级,可以把账号的认证插件改成老式的mysql_native_password:
ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'AppPassword_2025!'; FLUSH PRIVILEGES;另外,Navicat连接时如果勾选了SSL但服务器没配置证书,也会报SSL错误。稳妥做法是连接参数里选择“不加密”或“如果可用则使用SSL”,避免认证协议不一致导致来回折腾。
5. 高频问题与排查实录
5.1 初始化就翻车,八成是这三种原因
初始化阶段报错概率最高,而且错误信息往往隐藏在一长串日志里。最常见的三类:
一是缺依赖库,报错关键词libaio.so.1或libnuma.so.1,解决命令前面已经给了,多执行一次不丢人。
二是目录权限不对,报错关键词Can't create/write to file '/data/mysql/data/...'或者The designated data directory /data/mysql/data is unusable。原因基本就是/data/mysql的属主不是mysql,或者datadir里有残留文件。执行:
chown -R mysql:mysql /data/mysql rm -rf /data/mysql/data/*再初始化一次即可。
三是配置文件路径和实际目录不一致。比如my.cnf里写了basedir=/usr/local/mysql,但解压时放了别的路径,初始化时用--basedir显式指定就能定位问题。
5.2 启动后进程莫名其妙退出
初始化成功、执行mysql.server start也提示success,但几秒后进程没了。碰到这种情况别急着重复启动,先看错误日志:
tail -100 /data/mysql/data/*.err dmesg | tail -20日志里常见的错误有:InnoDB: Unable to lock ./ibdata1,一般是MySQL已经在运行或者上次异常退出有残留进程,使用ps -ef | grep mysqld查杀再启动;Out of memory,那就是innodb_buffer_pool_size配得太大,系统内存不足,调小后重试;还有socket file /tmp/mysql.sock already exists,说明上次没有干净退出,删掉socket文件再启动。
有一个实用习惯:进程反复异常退出时,用/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &前台模式启动,报错信息会直接打在终端,不用在日志文件里大海捞针。
5.3 从问题表象到解决命令的速查表
把这次安装和平时运维遇到的典型问题整理成表,放到手边,排查时直接对照:
| 问题现象 | 可能原因 | 解决命令/方法 |
|---|---|---|
mysql: command not found | PATH未配置 | export PATH=/usr/local/mysql/bin:$PATH |
libaio.so.1: cannot open shared object file | 缺少依赖库 | yum install -y libaio |
libnuma.so.1: cannot open shared object file | 缺少依赖库 | yum install -y numactl-libs |
The designated data directory is unusable | datadir非空或权限错 | 清空目录,chown -R mysql:mysql |
Can't connect to local MySQL server through socket '/tmp/mysql.sock' | 服务没启动或socket路径不一致 | 检查进程,确认my.cnf里socket路径 |
Access denied for user 'root'@'localhost' (using password: YES) | 密码错误 | 用临时密码登录后改密,或走密码重置流程 |
Host 'x.x.x.x' is not allowed to connect to this MySQL server | 无远程授权 | 创建远程用户并授权 |
Authentication plugin 'caching_sha2_password' cannot be loaded | 客户端驱动过旧 | 升级客户端,或改用mysql_native_password |
| 中文写入后查询乱码 | 字符集不是utf8mb4 | 改my.cnf后重启,确认库表字符集 |
| 服务启动后自动退出 | 内存不足/残留进程/数据页锁 | 看错误日志,调小buffer,清理进程 |
最后再分享一个个人经验:在麒麟上装MySQL,最忌讳的就是“抄命令式部署”。同样的命令在这台机器能跑,换一台机器就报错,环境差异太大了。动手前先花两分钟确认系统版本、包管理器、CPU架构,配置文件和目录规划好再动手,反而最快。像libaio、numactl这类依赖直接在准备阶段装好,能省掉后面一大半的报错时间。
还有一点很实用——整套流程建议先在临时测试环境完整走一遍,再上生产。麒麟V10版本众多,不同SP版本、不同内核形态确实存在细微差别,测试环境跑通后形成一份适合自己单位的操作记录,后面批量部署就是复制粘贴的事了。踩过坑不可怕,就怕同一个坑反复踩。这篇内容如果你顺利走通,后续主从复制、备份恢复这些进阶配置,建议也一并规划起来,有了这套底子,数据库层面的高可用方案会顺畅很多。