银河麒麟V10上部署MySQL 8,说难不难,说简单也真容易踩坑。我最早一次是在一台x86架构的Kylin V10服务器上装的,本来以为跟CentOS一样,几条yum命令就完事,结果源里压根没有官方MySQL包,能搜到的mysql-server还是MariaDB换皮,白折腾了一个下午。后来换了官方二进制包,才把整个流程跑通。这篇文章就把我当时从选型到初始化、再到配置远程访问的完整过程写出来,能帮你省掉不少试错时间。
这次分享适合谁看?两类人:一类是刚接手国产化服务器,要在内网环境部署数据库的运维和开发;另一类是已经有Linux基础,但第一次在麒麟系统上装MySQL 8,想避开依赖坑的朋友。无论你是x86还是ARM架构的机器,下面的思路都通用,差异点我会单独标出来。
1. 安装方案选型:为什么我建议用官方二进制包而不是yum
很多人一上来就在麒麟V10上执行yum install mysql-server,然后发现装完的是MariaDB,或者干脆提示没有可用软件包。这个问题的根源不在操作,而在源的差异。
1.1 先搞清楚你的麒麟是x86还是ARM
银河麒麟V10有x86_64版本,也有基于飞腾、鲲鹏、龙芯等国产CPU的ARM或MIPS版本。不同架构对应的MySQL包完全不同,装错了连启动都起不来。判断方法很简单:
bash复制uname -m
输出x86_64就按x86流程走,输出aarch64就一定要下载ARM64版本的安装包。我见过有人说“我下载了tar包怎么装都报Exec format error”,一查就是ARM机器下了x86包,这种低级错误很浪费生命。
1.2 四种安装方式对比与最终选型
在麒麟V10上安装MySQL 8通常有四条路,我把各自的适用场景列出来:
| 安装方式 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| yum/dnf安装 | 命令简单,自动处理依赖 | 麒麟源里通常没有MySQL官方包,容易装成MariaDB | 网络环境下可先试一下 |
| RPM包安装 | 便于rpm管理、卸载 | 依赖关系复杂,可能和系统libaio、openssl版本冲突 | 对RPM依赖非常熟悉的用户 |
| 官方Generic二进制包 | 解压即用,路径可控,依赖少 | 需要手动写service文件 | 我最推荐的方式 |
| 源码编译 | 可深度定制 | 编译时间长,依赖工具链复杂 | 有特殊编译参数需求时 |
我当时最终选了官方Generic二进制包。原因有三个:第一,麒麟V10是RHEL系衍生系统,和官方glibc 2.12/2.17的兼容性包能对上;第二,二进制包对yum源没有依赖,内网环境也能装;第三,安装目录完全自己控制,方便后续多实例部署和数据目录迁移。如果你需要在生产环境快速复制到多台机器,解压一份包分发过去就能跑,效率比RPM那套高太多。
1.3 一个容易被忽略的glibc兼容性问题
MySQL官方下载页会把二进制包按glibc版本分好,常见的有glibc2.12和glibc2.17两种。麒麟V10服务器版的glibc版本通常比较高,向下兼容低版本包。稳妥起见,装之前先看一眼系统glibc版本:
bash复制ldd --version
只要你的系统版本高于MySQL包要求的版本,基本上就没问题。我用的包是mysql-8.0.36-linux-glibc2.12-x86_64.tar.xz,在Kylin V10 SP1上运行得很稳。ARM机器则选linux-glibc2.17-aarch64对应版本。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 上手前要做的系统检查与目录规划
安装MySQL最怕的不是下载慢,而是安装到一半才发现系统里有残留数据库组件,或者目录规划不合理导致后面扩容困难。所以动手前先把环境摸清。
2.1 卸载残留数据库组件
麒麟V10有时候会预装MariaDB或者兼容层组件。不卸载直接装MySQL,端口会被占,或者mysql命令指向另一个客户端,排查起来头大。
检查命令:
bash复制rpm -qa | grep -i -E "mysql|mariadb"
如果发现有mariadb-server之类的包,直接卸载:
bash复制yum remove -y mariadb-server mariadb
卸载后顺手清理掉历史数据目录,避免旧数据影响新实例启动。这个步骤不要跳过,我曾在测试机上因为残留的/var/lib/mysql存在,导致初始化阶段系统直接报目录非空错误。
2.2 关闭SELinux与防火墙
麒麟V10默认可能开启SELinux和firewalld,不处理的话,MySQL服务能启动,但远程连接时可能被防火墙挡掉,或者SELinux拦截了mysqld对数据目录的写入。
我当时图省事,直接把两者关掉:
bash复制setenforce 0
systemctl stop firewalld
systemctl disable firewalld
如果你所在的环境对安全有严格要求,不能全局关停,那就只放行3306端口,并给数据目录设置正确的SELinux上下文。但个人实测下来,在纯内网测试环境直接关是最省心的。
2.3 检查动态库依赖与创建系统用户
二进制包虽然依赖少,但不是零依赖。MySQL 8启动时需要libaio和libnuma,缺了会直接报错。提前装好:
bash复制yum install -y libaio numactl-libs
如果机器完全离线,yum用不了,可以在另一台能联网的机器上下载对应rpm包,再拷贝进去。我就在离线环境吃过一次亏——包解压好了,初始化却提示error while loading shared libraries: libaio.so.1,当时没有离线依赖包,只能临时找同网段机器传输,非常被动。
然后是创建mysql用户。MySQL官方建议用独立系统账号运行,不要用root直接跑:
bash复制groupadd mysql
useradd -r -g mysql -s /sbin/nologin mysql
-r表示创建系统账号,-s /sbin/nologin表示禁止该用户登录shell,防止数据库账号被利用后直接获得shell权限。
2.4 数据目录单独规划
我强烈建议不要把数据目录放在MySQL安装目录下。安装目录属于系统盘,一旦系统分区满了,数据库直接宕机;数据盘往往容量更大,也方便做快照和备份。
我当时规划的结构是这样的:
text复制/usr/local/mysql # 程序目录
/data/mysql/data # 数据目录
/data/mysql/logs # 日志目录
创建完成后,把目录属主改掉:
bash复制mkdir -p /data/mysql/data /data/mysql/logs
chown -R mysql:mysql /data/mysql
这样后面初始化时不会因为权限问题报错。
3. mysql8完整安装步骤:解压、初始化与启动
前面环境准备完毕,接下来进入正题:下载二进制包、配置my.cnf、初始化数据目录、首次启动。
3.1 下载正确的MySQL8安装包
MySQL社区版下载地址是官方站点,选择“MySQL Community Server”和“Linux - Generic”版本即可。需要注意CPU架构:
- x86机器选:
mysql-8.0.x-linux-glibc2.12-x86_64.tar.xz - ARM机器选:
mysql-8.0.x-linux-glibc2.17-aarch64.tar.xz
如果你所在的服务器有外网,直接wget即可:
bash复制wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.36-linux-glibc2.12-x86_64.tar.xz
内网环境的话,得先去有网的机器下载,再通过U盘或者内网文件服务传过去。下载完先校验一下md5或者sha256,避免包损坏。解压后看不到bin/mysqld再排查就晚了。
3.2 解压并编写核心配置my.cnf
包解压到/usr/local目录下:
bash复制tar -xvf mysql-8.0.36-linux-glibc2.12-x86_64.tar.xz -C /usr/local/
cd /usr/local
mv mysql-8.0.36-linux-glibc2.12-x86_64 mysql
MySQL安装目录一般不需要修改属主,二进制文件保持root拥有即可,数据目录属于mysql用户。为了后续命令方便,可以顺手把/usr/local/mysql/bin加进PATH:
bash复制echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile
source /etc/profile
配置文件/etc/my.cnf是整个安装过程的核心。我用的配置做了最小化裁剪,方便你理解每个参数含义:
ini复制[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql/data
socket=/tmp/mysql.sock
pid-file=/data/mysql/data/mysqld.pid
log-error=/data/mysql/logs/mysqld.err
port=3306
character-set-server=utf8mb4
collation-server=utf8mb4_0900_ai_ci
max_connections=500
innodb_buffer_pool_size=256M
skip_name_resolve=ON
简单解释下几个关键参数:basedir和datadir分别告诉mysqld程序目录和数据目录在哪里;socket是本地socket连接的路径,PHP或Java程序如果用localhost连接会依赖它;innodb_buffer_pool_size建议设成物理内存的50%到70%,如果服务器只有2G内存,256M就很稳妥;skip_name_resolve=ON可以跳过反向DNS解析,提升连接速度,代价是授权时必须用IP而不是主机名。
3.3 初始化数据目录与首次启动
初始化是很多新手容易卡住的一步。MySQL 8已经不支持mysql_install_db那种老命令,统一使用mysqld --initialize:
bash复制/usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data
注意:这条命令必须用mysql用户执行,或者显式指定--user=mysql,否则会报权限错误。初始化完成后,查看日志文件:
bash复制cat /data/mysql/logs/mysqld.err
日志里会生成一个临时root密码,格式是[Note] A temporary password is generated for root@localhost: 临时密码。务必把这串密码记下来,第一次登录要用。
如果初始化中途报错,先把错误日志最后20行贴出来搜一下,大多数问题集中在权限、libaio缺失、datadir非空这三类。
初始化成功后再启动服务。第一次建议用mysqld_safe方式启动,方便前台观察日志:
bash复制/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &
启动后确认进程和端口:
bash复制ss -lntp | grep 3306
看到LISTEN状态说明启动成功。这时候先别急着配置,确认一次登录流程没问题再往下走。
3.4 拿到临时密码并完成第一次登录
用临时密码登录:
bash复制mysql -uroot -p'临时密码'
登录成功后,第一件事就是修改root密码。MySQL 8默认密码策略要求字母大小写、数字、特殊字符都有,长度至少8位,所以新密码别设得太简单:
sql复制ALTER USER 'root'@'localhost' IDENTIFIED BY 'New_Strong_Pass123';
FLUSH PRIVILEGES;
如果你只是想本地测试,可以把密码策略调低,但生产环境建议保持默认强度。之后重新用新密码登录验证一下,确认修改成功。
4. 用systemd管好mysqld:开机自启与日常运维操作
mysqld_safe方式适合临时启动,但每次开机都手动执行不现实。麒麟V10支持systemd,把mysqld封装成系统服务才是一劳永逸的办法。
4.1 手写一个简洁的mysqld.service
MySQL二进制包自带的support-files里有mysql.server脚本,但我更推荐直接自写service文件,逻辑更清晰,也方便调优。新建/etc/systemd/system/mysqld.service,内容如下:
ini复制[Unit]
Description=MySQL Server 8.0
After=network.target
[Service]
User=mysql
Group=mysql
Type=simple
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE=65535
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
这里有几个参数值得注意。Type=simple告诉systemd直接跟踪mysqld主进程;LimitNOFILE=65535提高文件描述符上限,避免高并发下报Too many open files;Restart=on-failure让服务异常退出时3秒后自动拉起,对数据库这种长驻服务很友好。
4.2 enable和启动的正确顺序
写好评测后,先重新加载systemd配置:
bash复制systemctl daemon-reload
systemctl enable mysqld
systemctl start mysqld
如果之前用mysqld_safe启动过,先把它停掉,避免端口残留,再启systemd服务。启动后检查状态:
bash复制systemctl status mysqld
看到active (running)就说明服务正常。为了验证开机自启确实生效,可以重启一次机器,然后执行ss -lntp | grep 3306确认端口自动监听。
4.3 日常运维与日志查看习惯
服务化之后,日常运维就简单了:
bash复制systemctl restart mysqld # 重启
systemctl stop mysqld # 停止
journalctl -u mysqld -f # 实时查看系统日志
MySQL自己的错误日志在/data/mysql/logs/mysqld.err,很多启动问题在这里比journalctl看得更清楚。遇到服务起不来的情况,我习惯先看这个文件的最后50行:
bash复制tail -n 50 /data/mysql/logs/mysqld.err
80%的问题在这个日志里都有明确提示,比如权限、端口占用、InnoDB崩溃恢复失败等。
5. 配置远程访问与创建业务库
MySQL装好不仅能本地登录,业务系统需要通过网络访问,所以远程访问配置和账号体系也要搭好。
5.1 root远程登录的安全做法
默认情况下,root只能从localhost登录,这是好事。生产环境不建议直接开放root远程登录,而是创建独立业务账号。如果你需要临时远程管理,可以创建一个远程root管理员账号:
sql复制CREATE USER 'root'@'%' IDENTIFIED BY 'Strong_Admin_Pass123';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
注意MySQL 8和MySQL 5.7不一样,不能先GRANT再隐式建用户,必须先CREATE USER再GRANT,否则会报错。
5.2 新建业务库和专用账号
实际业务中更推荐为每个项目建立独立数据库和独立账号,权限精确到库级别。比如创建一个appdb库和appuser账号:
sql复制CREATE DATABASE appdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'appuser'@'%' IDENTIFIED BY 'App_User_Pass123';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'%';
FLUSH PRIVILEGES;
这里把库的默认字符集设成了utf8mb4,这是目前最稳妥的选择,什么语言都能存,不会出现生僻字显示成问号的情况。业务账号只授appdb库权限,即使密码泄露,也不会波及其他库。
5.3 老驱动兼容的处理方法
如果业务系统用的还是老版本Java驱动或PHP扩展,连接MySQL 8时可能会报错:
text复制Authentication plugin 'caching_sha2_password' cannot be loaded
这是因为MySQL 8默认认证插件改成了caching_sha2_password,老的客户端驱动不认识。遇到这种情况,有两种处理:一是升级驱动到支持新插件的版本,比如mysql-connector-java 8.x以上;二是把账号认证方式临时改回老的mysql_native_password:
sql复制CREATE USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'App_User_Pass123';
改完重新授权即可。但我更建议升级驱动,因为mysql_native_password在后续版本里会被逐步淘汰,靠它绕过问题不是长久之计。
6. 麒麟V10上我踩过的坑与排查速查
最后把这轮部署中实际遇到的典型问题整理成下面这张速查表,照着处理能省不少时间。
| 故障现象 | 根本原因 | 快速处理 |
|---|---|---|
| 初始化报缺少libaio.so.1 | 系统未安装libaio | 执行yum install -y libaio |
| mysql命令提示无法连接socket | socket路径不一致 | 检查my.cnf里socket路径,用mysql -uroot -p -S /tmp/mysql.sock连接 |
| 服务启动后立即退出 | datadir权限不对 | chown -R mysql:mysql /data/mysql |
| 3306端口不通 | firewall拦截 | systemctl stop firewalld或放行3306端口 |
| 远程连接报Access denied | root默认仅允许localhost | 创建'root'@'%'或专用远程账号 |
| 启动后进程消失且日志无内容 | 可能缺少numactl依赖 | 执行yum install -y numactl-libs |
| Java连接报caching_sha2_password错误 | 客户端驱动过旧 | 升级驱动或改用mysql_native_password |
| 重启系统后mysqld消失 | 未设置开机自启 | systemctl enable mysqld |
6.1 初始化和启动类问题
我印象最深的一次是初始化时报[ERROR] --initialize specified but the data directory has files in it。原因是我之前手工在该目录跑了其他测试,留下了隐藏文件。解决方法是把目录内所有文件清掉再执行初始化。清数据目录前一定确认没有可用数据,我在测试机上无所谓,生产环境这就是高危操作。
另一个常见问题是mysqld_safe启动后日志里出现Starting MySQL... ERROR!,十有八九是my.cnf里有参数写错。特别是datadir和socket路径手滑打错,启动进程找不到目录,立刻退出。遇到这种情况先别急着怀疑配置,把/data/mysql/logs/mysqld.err最后20行翻出来看看,里面会把具体哪个参数、哪个路径写得明明白白。
6.2 登录与权限类问题
刚初始化完,用临时密码登录时如果密码里有特殊字符,比如%、@、#,在bash里不包引号会被吃掉一部分。用单引号包整串密码最保险:
bash复制mysql -uroot -p'Abc@123456'
如果shell执行mysql时提示找不到命令,是因为没有把bin目录加入PATH。临时解决办法是:
bash复制export PATH=/usr/local/mysql/bin:$PATH
6.3 网络与外联类问题
服务已经启动,但云平台或内网另一台机器连接超时,除了检查本机防火墙,还要看看是否有安全组层面拦截。麒麟服务器如果装了多个网卡,要确认3306是否监听在正确的IP上:
bash复制ss -lntp | grep 3306
出现*:3306说明监听所有网卡,如果只监听了127.0.0.1:3306,就需要在my.cnf里配置bind-address=0.0.0.0并重启服务。这个细节很容易让人误以为是防火墙问题,实际上改了bind-address就好了。
6.4 密码策略导致业务账号无法创建
MySQL 8默认密码校验要求较强,创建业务账号时如果密码强度不够,可能会直接报:
text复制ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
临时把密码校验降级可以这样:
sql复制SET GLOBAL validate_password.policy = LOW;
SET GLOBAL validate_password.length = 6;
但只是临时操作,下次重启会恢复默认。如果要持久化,需要写进my.cnf的[mysqld]片段:
ini复制validate_password_policy=LOW
validate_password_length=6
个人建议测试环境再这么玩,生产环境的数据库密码还是老实设成高强度,业务账号一旦被爆破,整个库都可能被拖走。
这几轮装下来,最值得提醒的就一件事:出现问题先看日志,不要凭感觉乱改配置。很多你觉得玄学的问题,mysqld.err里其实写得明明白白,只是没耐心看。按照这套流程走一遍,从解压二进制包到systemd管理、远程访问配置,基本半小时内能完成。后续如果要升级MySQL小版本,也是下载新包替换basedir下的文件、重启服务这么简单,数据目录完全不用动。这也是我坚持用Generic二进制包的原因——部署可控,升级省心。
