【运维实战】MySQL 8.0 数据库 · 一键自动化部署方案 (适配银河麒麟 V10 / 龙蜥 8 / Rocky Linux 8 / CentOS 8)

国产操作系统下MySQL离线一键部署:从"编译三天"到"10分钟开箱即用"

在金融、政务、央国企的国产化替代进程中,我们遇到一个真实痛点:在银河麒麟、龙蜥、Rocky Linux等国产OS上离线安装MySQL 8.0 。依赖缺、网络差、报错多,让一套简单的数据库部署变成"劝退"任务。

本文分享我们如何打造一套支持RPM bundle、自动基线优化、全量备份的离线一键部署方案,最终将部署时间从数小时压缩到10分钟以内。


一、业务背景:国产化替代下的文件共享难题

某省级政务云平台启动"全栈国产化"改造:

  • 操作系统:银河麒麟服务器版 V10(基于 CentOS 8 生态)
  • 数据库:MySQL 8.0(为内网文件共享系统提供元数据存储)
  • 网络环境离线,无互联网,仅内网 YUM 仓库(不完整)
  • 交付要求:30 台新服务器,每台需在 2 小时内完成数据库部署并接入业务。

传统做法:

  1. 用源码编译 ------ 缺依赖、耗时长,平均每台 3~5 小时
  2. 用二进制 tar 包 ------ 需要手工配置 systemd、SELinux、内核参数,容易遗漏
  3. 用官方 RPM ------ 但因为缺少 libaioperlclient-plugins 等依赖,反复报错

结果:项目组陷入"每台机器都要踩一遍坑"的噩梦,交付严重延期。


二、需求分析:我们需要一个"开箱即用"的MySQL离线一键部署工具

结合现场反馈,我们整理了必须满足的 8 项核心需求

需求编号 描述
R1 单命令完成:运维人员只需上传一个 bundle 包,执行一条命令
R2 离线可用:不依赖互联网,所有依赖必须来自 bundle 包或系统 ISO
R3 自动处理残留:若之前有 MySQL(rpm/进程/目录),交互确认后彻底清理
R4 系统基线优化:自动关闭防火墙、SELinux、SWAP;设置时区;优化 limits.conf;配置内核参数(透明大页关闭、numa=off)
R5 自定义数据目录 :业务要求 /data/mysql 独立磁盘,默认必须支持
R6 全自动备份 :安装后自动生成每日 mysqldump 全量备份脚本,且并行、压缩、记录 GTID
R7 完全可复现:在 x86_64 架构的 麒麟 V10 / 龙蜥 8 / Rocky 8 / CentOS 8 上均能一致运行
R8 安全可控 :必须生成 /root/.my.cnf 免密文件,root 密码可指定,不允许暴露在命令行历史中

除了这些功能指标,还有一个隐性痛点

团队里既有熟悉 CentOS 6 的老手,也有刚接触国产 OS 的新人,指望所有人手动解决依赖顺序、RPM 冲突、systemd 单元编写是不现实的。

因此,我们决定开发一个100% 自包含的 Bash 脚本,把所有"坑"化作自动化逻辑。


三、方案设计:打造"一键式MySQL离线一键部署工具"

3.1 整体架构

复制代码
┌─────────────────────────────────────────────────────┐
│                  用户执行一条命令                      │
│   bash install_mysql8_rpm.sh -p bundle.tar          │
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│  阶段1 环境检查 & 操作系统识别(麒麟/龙蜥/CentOS/Rocky)│
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│  阶段2 残留清理:卸载旧RPM、杀进程、删数据目录          │
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│  阶段3 系统基线:防火墙/SELinux/SWAP/时区/内核参数      │
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│  阶段4 RPM安装(智能顺序 + 依赖检测)                  │
│  common → client-plugins → libs → icu-data-files     │
│            → client → server                         │
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│  阶段5 自定义配置:my.cnf + 数据目录 + systemd单元     │
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│  阶段6 初始化 & 启动 & 改密 & 生成 /root/.my.cnf      │
└─────────────────────┬───────────────────────────────┘
                      ▼
┌─────────────────────────────────────────────────────┐
│  阶段7 部署备份脚本(并行库备份 + 7天轮转 + crontab)  │
└─────────────────────────────────────────────────────┘

3.2 核心技术决策

决策点 选型 理由
安装包格式 RPM bundle(含 common / client-plugins / libs / icu-data-files / client / server) 符合 EL8 生态(麒麟、龙蜥均兼容),可被 yum localinstall 自动处理部分依赖。
残留清理策略 rpm -e --nodeps + pkill + rm -rf强制二次确认 避免误删数据;但允许重复执行覆盖安装。
系统基线 写入 limits.confsysctl.conf/etc/default/grub,并立即生效或标记需重启 解决大并发下文件句柄不足、SWAP 占用、CPU 调度等问题。
数据目录 强制自定义至 /data/mysql(可修改) 解耦系统盘与数据盘,方便扩容与迁移。
备份方案 按库拆分 + gzip + sha256sum + 并行 xargs -P + 保留 7 天 兼顾恢复效率(单库单独恢复)、存储空间与审计需求。

3.3 解决的关键坑点

  1. RPM 依赖顺序错误

    原问题:直接安装 server 会报 缺少 mysql-community-client-plugins缺少 mysql-community-icu-data-files

    解决:脚本自动识别 bundle 解压后的 rpm 文件,按顺序安装。

  2. mysqld 二进制路径不一致

    RPM 安装后 mysqld 位于 /usr/sbin/mysqld,而客户端在 /usr/bin

    脚本动态检测 mysqld 位置,并写入 systemd 单元文件。

  3. 初始化后临时密码获取失败

    通过解析数据目录下的 *.err 文件中的 temporary password 行,自动提取并执行 ALTER USER

  4. 国产 OS 的 GRUB 差异

    麒麟 V10 同时支持 grub2-mkconfig,但默认可能未安装 grubby。脚本会优先使用 grubby,否则修改 /etc/default/grub 并尝试生成配置。


四、脚本核心代码节选(完整版见文末)

以下展示关键逻辑,完整 500+ 行脚本请关注博主并在后台回复"MySQL离线安装"获取。

4.1 智能 RPM 安装顺序

bash 复制代码
install_mysql_rpms() {
    cd "${TMP_EXTRACT_DIR}"
    # 精准匹配各个组件包
    common_pkg=$(ls mysql-community-common-*.rpm 2>/dev/null | head -n1)
    client_plugins_pkg=$(ls mysql-community-client-plugins-*.rpm 2>/dev/null | head -n1)
    libs_pkg=$(ls mysql-community-libs-*.rpm 2>/dev/null | head -n1)
    icu_data_pkg=$(ls mysql-community-icu-data-files-*.rpm 2>/dev/null | head -n1)
    client_pkg=$(ls mysql-community-client-*.rpm 2>/dev/null | head -n1)
    server_pkg=$(ls mysql-community-server-*.rpm 2>/dev/null | head -n1)

    # 缺失则直接报错退出
    [[ -n "$common_pkg" && -n "$client_plugins_pkg" && -n "$libs_pkg" && 
       -n "$icu_data_pkg" && -n "$client_pkg" && -n "$server_pkg" ]] || die "缺少核心RPM包"

    # 以正确顺序 localinstall
    yum localinstall -y "./$common_pkg"
    yum localinstall -y "./$client_plugins_pkg"
    yum localinstall -y "./$libs_pkg"
    yum localinstall -y "./$icu_data_pkg"
    yum localinstall -y "./$client_pkg"
    yum localinstall -y "./$server_pkg"
}

4.2 自动检测 mysqld 路径

bash 复制代码
detect_mysqld_path() {
    if [[ -x "/usr/sbin/mysqld" ]]; then
        MYSQLD_BIN="/usr/sbin/mysqld"
    elif [[ -x "/usr/libexec/mysqld" ]]; then
        MYSQLD_BIN="/usr/libexec/mysqld"
    elif command -v mysqld >/dev/null 2>&1; then
        MYSQLD_BIN="$(command -v mysqld)"
    else
        die "未找到 mysqld 二进制文件"
    fi
}

4.3 自定义 my.cnf 生成(部分参数)

bash 复制代码
cat > "${mycnf}" <<EOF
[mysqld]
user    = ${MYSQL_USER}
port    = ${PORT}
datadir = ${BASE_DATA}/data
log-error = ${BASE_DATA}/log/mysql.err
innodb_buffer_pool_size = ${BUFFER_POOL}
gtid_mode = ON
enforce_gtid_consistency = ON
lower_case_table_names = ${LOWER_CASE_TABLE_NAMES}
...
EOF

4.4 每日备份脚本(关键片段)

bash 复制代码
# 并行备份每个库
cat db.list | xargs -P ${jobs} -I{} bash -c '
    mysqldump --single-transaction --databases "{}" | gzip > "${outdir}/db_{}.sql.gz"
    sha256sum "${outdir}/db_{}.sql.gz" >> "${outdir}/SHA256SUMS"
'
# 生成 manifest.json 记录 binlog 位点、GTID 等信息

五、部署效果演示(成功输出摘要)

在一台银河麒麟服务器版 V10(4C/8G)上,执行命令:

bash 复制代码
bash install_mysql8_rpm_final.sh -p /root/mysql-8.0.44-1.el8.x86_64.rpm-bundle.tar

最终输出摘要(节选):

复制代码
[2026-04-27 22:25:01] [阶段] 总结输出
[2026-04-27 22:25:01] [总结输出] 安装总结:
  服务状态:   systemctl status mysqld.service
  安装方式:   RPM bundle (mysqld: /usr/sbin/mysqld)
  配置文件:   /data/mysql/conf/my.cnf
  数据目录:   /data/mysql/data
  端口:       3306
  root 密码:  mysql
  免密文件:   /root/.my.cnf(已生成,权限 600)
  备份任务:   已写入 root crontab(每天 02:00 执行全备,保留 7 天)

提示:安装完成后建议重启主机,确保系统配置生效。


验证数据库

bash 复制代码
mysql -uroot -pmysql -e "SELECT VERSION();"
+-------------------------+
| VERSION()               |
+-------------------------+
| 8.0.44                  |
+-------------------------+

查看备份任务

bash 复制代码
crontab -l | grep mysql_full_backup
00 02 * * * /usr/local/bin/mysql_full_backup.sh >> /var/log/mysql_full_backup.log 2>&1

用时统计 :从解压到服务启动完成,仅 9 分 42 秒 (包括安装依赖、基线优化、初始化等全部步骤)。

与手工安装对比:↓ 92% 时间成本


六、后期维护建议

一键部署脚本解决了"从 0 到 1"的问题,但上线后的长期稳定同样关键。以下 4 条维护建议供参考:

  1. 内核配置必须重启生效

    脚本修改了 transparent_hugepage=nevernuma=offelevator=deadline务必在维护窗口重启主机 ,否则性能优化不生效。

    查验:cat /sys/kernel/mm/transparent_hugepage/enabled 应显示 [never]

  2. 定期验证备份的可恢复性

    备份脚本虽然每天运行,但推荐每月手工执行一次恢复演练

    bash 复制代码
    gunzip < batch_xxx/db_xxx.sql.gz | mysql test_restore
  3. 监控磁盘与 binlog 空间

    默认 expire_logs_days = 30,备份保留 7 天。可根据实际数据量调整:

    • 减少保留天数:修改脚本中的 RETENTION_DAYS
    • 增加 binlog 保留:SET GLOBAL expire_logs_days = 7;
  4. 追踪 RPM 更新

    当 MySQL 发布安全补丁时,重新下载新的 RPM bundle 包,再次执行脚本(脚本会自动清理旧版本并升级)。

    注意:升级前务必备份数据,并测试业务兼容性。


写在最后

本文分享的这套 MySQL 离线一键部署方案,已经在 20+ 个国产化项目中验证,累计部署超过 200 台服务器。它将依赖解析、系统基线、备份自动化融合进一个脚本,真正做到了"下载即用,10 分钟交付"。

如果您正在面临类似的国产 OS + MySQL 部署困境,欢迎关注本博客账号,并在后台回复"MySQL离线安装",即可获取完整版脚本(持续更新,支持 MySQL 8.0.44+)。

云动课堂 | 专注国产基础软件运维与架构

后台回复:MySQL离线安装 → 获取一键部署脚本 + 详细文档

相关推荐
cui_ruicheng1 小时前
Linux进程间通信(一):管道与IPC基础
linux·运维·服务器
阿正呀1 小时前
CSS粘性定位不生效怎么办_检查父元素高度与overflow属性设置
jvm·数据库·python
2403_883261091 小时前
如何获取DDL语句_DBMS_METADATA.GET_DDL提取对象定义
jvm·数据库·python
Lumos_7771 小时前
Linux -- 互斥锁
linux
m0_613856291 小时前
mysql数据库乱码如何解决_mysql字符集与校对规则配置方法
jvm·数据库·python
Bert.Cai1 小时前
MySQL CEIL()函数详解
数据库·mysql
一叶龙洲1 小时前
Ubuntu开机无法用向日葵远程控制
linux·运维·ubuntu
m0_602857762 小时前
Chart.js 4 中实现基于数据极值的垂直线性渐变填充
jvm·数据库·python
夏恪2 小时前
如何计算SQL同比环比数据_利用窗口函数LAG与LEAD
jvm·数据库·python