用 dbbot v0.14.0 并发部署三台 MySQL 9.7 EA 单机
上一篇 把 dbbot 这个项目的定位说清楚了。这一篇开始走真正的实战:在三台机器上并发部署 3 套 MySQL 9.7 EA 单机实例。
顺嘴提一句这次的小巧合 —— Rocky Linux 9.7 + MySQL 9.7,凑了个"双 9.7"。纯属凑数字图个乐子,刚好都是比较新的系统和数据库,也都在 dbbot 支持矩阵里 —— 后续我就用这"双 9.7"来做主力测试环境了。
这套环境之后会一直留着 —— 后续我会在它上面挨个看看 9.7 里那些值得 DBA 提前关注的变化。所以这一篇本质上是实验环境搭建篇,把"基准机器"先稳稳放好。
但有一个工程问题挡在前面:MySQL 9.7 现在还是 EA 包,不在 dbbot 的官方支持矩阵里。我们要先解决"矩阵外的包怎么走自动化"。
一、为什么 EA 包过去走不通自动化
很多 DBA 都熟悉这个套路:
- Oracle 先放一个 EA 包出来,包名跟正式包不一样。
- 公司内部可能又会基于 EA 重命名、重打包、加一层校验。
- 已经写好的自动化脚本只认"支持矩阵里的官方包名",认不出来这个新文件。
最后只剩两条路:临时改 playbook,或者干脆手工分发二进制。能跑是能跑,但事后排查会很难看 —— 这台机器到底用了哪个包?checksum 校验过没?basedir 是不是覆盖了旧目录?复制关系是不是自动验过?所有这些都得靠人脑记。
dbbot 默认是不允许"包名我不认识"的部署进入主流程的,这是出于稳定性的克制。但完全堵死也不现实,DBA 总会遇到要验 EA、要验内部重打包的场景。
二、v0.14.0 开了哪条受控口子
v0.14.0 加了几个变量,明确告诉 playbook:“这次允许我用一个矩阵之外的 MySQL Server 主包”:
fcs_allow_custom_mysql_package—— 允许自定义。默认false,必须显式打开。mysql_custom_package—— 指向本地下载目录里的安装包文件名,支持.tar.gz和.tar.xz。mysql_custom_package_checksum_type/mysql_custom_package_checksum—— checksum 校验仍然要做。mysql_software_dir—— basedir 单独隔离,避免 EA 包覆盖旧目录。mysql_version—— 真实版本依然要写明,不靠包名猜。
⚠️ 这不是关闭安全检查: 这个开关只覆盖 MySQL Server 主包名一项。版本判断、目标 OS 判断、部署拓扑判断仍然都在;InnoDB Cluster / Router 场景里的 MySQL Shell 和 Router 包也仍然来自支持矩阵,不能靠这个开关绕过。
这里面最容易被低估的是 mysql_software_dir。强烈建议每次都给自定义包单独留 basedir,不要和正式包共用 9.7.0。我这次实测的三台机器上,原本已经有:
/database/mysql/base/9.7.0
/database/mysql/3306
部署完成后,每台机器上新增的是:
/database/mysql/base/9.7.0-EA
/database/mysql/3308
最终每台机器上 3306、3308 两个 systemd 服务可以同时 active,端口、目录都不打架。这就是分目录的好处 —— 出了问题,你一眼能看出来这个实例用的是正式包还是 EA。
三、本次实验环境
| 节点 | IP | 系统 | 部署内容 |
|---|---|---|---|
| node-1 | 192.168.161.11 | Rocky Linux 9.7 | MySQL 9.7 EA 单机,端口 3308 |
| node-2 | 192.168.161.12 | Rocky Linux 9.7 | MySQL 9.7 EA 单机,端口 3308 |
| node-3 | 192.168.161.13 | Rocky Linux 9.7 | MySQL 9.7 EA 单机,端口 3308 |
三台机器之间没有复制关系 —— 这次只是把同一份 single_node.yml 并发跑到三台上,每台一个独立的 EA 实例。这样后面写不同特性文章时,可以拿其中一台单独折腾,不会牵连其他。
为什么用 3308?这三台机器上已经跑着 3306 的实例,我故意保留了,正好顺带验证 dbbot 多实例部署互不打架。
公开演示密码沿用 dbbot 默认值 (Dbbot_<user>@8888 / Dbbot_<linux_user>@9999),仅用于 lab;生产环境务必换成自己的 SSH key 和数据库密码。
1. 下载 dbbot v0.14.0
cd /tmp
dbbot_version="v0.14.0"
curl -fL -O "https://github.com/fanderchan/dbbot/releases/download/${dbbot_version}/dbbot-${dbbot_version}.tar.gz"
tar -zxvf "dbbot-${dbbot_version}.tar.gz" -C /usr/local/
/usr/local/dbbot/bin/dbbotctl env setup
source ~/.bashrc
ansible-playbook --version
生产环境一定要固定版本,不要让 CI 跑
latest。同一份"上次跑通过的脚本",在两个 release 之间跑出来的结果可能就不一样。
2. 准备 MySQL 9.7 EA 包
9.7 EA 当前不在 dev.mysql.com/get/Downloads 的常规目录里,要去 snapshots 拿:
cd /usr/local/dbbot/mysql_ansible/downloads
curl -fL -O "https://downloads.mysql.com/snapshots/pb/mysql-9.7.0-csa/mysql-9.7.0-csa-linux-glibc2.28-x86_64.tar.xz"
md5sum mysql-9.7.0-csa-linux-glibc2.28-x86_64.tar.xz
本次实测的 MD5:
bf7a16834c99d447630fd917b5f32529 mysql-9.7.0-csa-linux-glibc2.28-x86_64.tar.xz
如果你拿到的是公司内部重打包文件 —— 比如镜像仓库里改过文件名的版本 —— 只需要把文件放到同一个下载目录,然后改变量里的 mysql_custom_package 和对应 checksum,不需要改 playbook。这点很重要:自动化脚本不能因为一次 EA 测试就退化成一次性脚本。
3. 写 inventory
/usr/local/dbbot/mysql_ansible/inventory/hosts.ini:
[dbbot_mysql]
192.168.161.11 ansible_user=root ansible_ssh_pass="'Dbbot@2026'"
192.168.161.12 ansible_user=root ansible_ssh_pass="'Dbbot@2026'"
192.168.161.13 ansible_user=root ansible_ssh_pass="'Dbbot@2026'"
[all:vars]
ansible_python_interpreter=auto_silent
先做连通性检查:
cd /usr/local/dbbot/mysql_ansible/playbooks
ansible -i ../inventory/hosts.ini dbbot_mysql -m ping
三台返回 pong 再继续。自动化部署最忌讳带着 SSH、Python、sudo 这类基础问题往下冲 —— 后面剧本一旦报错,根因经常和报错信息隔了好几层,排查起来非常绕。
4. 写独立变量文件
不要为了一个 EA 测试去改默认变量。新建一个独立文件,部署时用 -e @vars/mysql-9-7-ea-single-node.yml 引入,这样这次实验和未来的标准部署互不污染。
/usr/local/dbbot/mysql_ansible/playbooks/vars/mysql-9-7-ea-single-node.yml:
mysql_version: "9.7.0"
mysql_port: 3308
mysql_software_dir: "/database/mysql/base/9.7.0-EA"
fcs_auto_download_packages: false
fcs_allow_custom_mysql_package: true
mysql_custom_package: "mysql-9.7.0-csa-linux-glibc2.28-x86_64.tar.xz"
mysql_custom_package_checksum_type: "md5"
mysql_custom_package_checksum: "bf7a16834c99d447630fd917b5f32529"
fcs_allow_dbbot_default_passwd: true
dbbot_confirmation_input: "confirm"
变量刻意写得很短。除了端口、basedir、自定义包这几条这次必须改的,其他能用默认就用默认 —— 实验环境用 fcs_allow_dbbot_default_passwd: true 临时放行公开默认密码,部署后再按需改。
最值得盯住的还是这四行:
mysql_software_dir: "/database/mysql/base/9.7.0-EA"
fcs_allow_custom_mysql_package: true
mysql_custom_package: "mysql-9.7.0-csa-linux-glibc2.28-x86_64.tar.xz"
mysql_custom_package_checksum_type: "md5"
fcs_allow_custom_mysql_package 必须显式打开。mysql_custom_package 必须是本地文件名,不能带目录分隔符,后缀必须是 .tar.gz 或 .tar.xz。这个限制看着啰嗦,其实是为了避免把任意路径塞进解压流程 —— 受控开关该管的事,还是要管住。
5. 一条命令并发部署三台
cd /usr/local/dbbot/mysql_ansible/playbooks
ansible-playbook \
-i ../inventory/hosts.ini \
single_node.yml \
-e @vars/mysql-9-7-ea-single-node.yml
CI 或脚本场景建议用绿色版 Ansible 的显式路径,避免被环境里其他 Python / Ansible 干扰:
cd /usr/local/dbbot/mysql_ansible/playbooks
ANSIBLE_HOST_KEY_CHECKING=False \
python3 /usr/local/dbbot/portable-ansible/ansible-playbook \
-i ../inventory/hosts.ini \
single_node.yml \
-e @vars/mysql-9-7-ea-single-node.yml
single_node.yml 跑在 [dbbot_mysql] 三台机器上,Ansible 默认就是按主机并发执行的,所以三台是同时往前推进的。
执行过程中可以看到 dbbot 走了自定义包分支:
TASK [Use custom MySQL Server package metadata (local)] ************************
ok: [192.168.161.11 -> localhost]
ok: [192.168.161.12 -> localhost]
ok: [192.168.161.13 -> localhost]
TASK [Check mysql-9.7.0-csa-linux-glibc2.28-x86_64.tar.xz checksum when configured (local)] ***
ok: [192.168.161.11 -> localhost]
ok: [192.168.161.12 -> localhost]
ok: [192.168.161.13 -> localhost]
TASK [../roles/mysql_server : Unarchive MySQL install package to /database/mysql/base/9.7.0-EA] ***
changed: [192.168.161.11]
changed: [192.168.161.12]
changed: [192.168.161.13]
最终 PLAY RECAP:
192.168.161.11 : ok=86 changed=26 unreachable=0 failed=0
192.168.161.12 : ok=86 changed=26 unreachable=0 failed=0
192.168.161.13 : ok=86 changed=26 unreachable=0 failed=0
Playbook run took 0 days, 0 hours, 1 minutes, 32 seconds
三台 ok / changed 数完全对齐 —— 这正是单机并发部署该有的样子,每台跑同一份剧本,没有谁是"主"。post-deploy 检查也跟着跑完了:
MySQL instance post-check passed on 192.168.161.11.
MySQL instance post-check passed on 192.168.161.12.
MySQL instance post-check passed on 192.168.161.13.
92 秒,从空环境到三台独立的 9.7 EA 单机带 post-check —— 没有"任务跑完了,但不知道结果对不对"的灰色地带。
6. 验证结果
先看每台机器上的服务,原来的 3306 和新装的 3308 应该都是 active:
systemctl is-active mysql3306 mysql3308
三台都返回:
active active
挨台确认 3308 实例的版本、端口和目录:
/database/mysql/base/9.7.0-EA/bin/mysql \
-h127.0.0.1 -P3308 -uadmin -pDbbot_admin@8888 \
-NBe "select @@hostname, @@port, @@version, @@basedir, @@datadir;"
三台分别返回:
r9-01.iaas.local 3308 9.7.0 /database/mysql/base/9.7.0-EA/ /database/mysql/3308/data/
r9-02.iaas.local 3308 9.7.0 /database/mysql/base/9.7.0-EA/ /database/mysql/3308/data/
r9-03.iaas.local 3308 9.7.0 /database/mysql/base/9.7.0-EA/ /database/mysql/3308/data/
上面这条命令把 basedir、admin 用户和密码都贴在命令行里,演示场景一目了然,但日常登录其实不用这么累。dbbot 默认会给
mysql用户生成快捷登录命令(参见fcs_create_mysql_fast_login),思路和 PostgreSQL 那边su - postgres后直接psql进库一样:su mysql db3308切到
mysql用户、敲一个db<port>就直接进对应实例了,不用记 basedir 路径,也不用把密码写在命令行里。多端口实例并存时尤其顺手。
basedir 干净落在 9.7.0-EA,没有污染原来 3306 用的 9.7.0。这是上面强调"分目录"那段话的实际意义。
到这里,三套独立的 9.7 EA 3308 单机就稳稳跑起来了。更重要的是:变量文件、包名、checksum、端口、目录、执行日志都留下来了。哪天要复盘,一份变量文件就能解释清楚这台机器是怎么来的。
自定义包能力的边界
简单收口一下,这个开关只覆盖 MySQL Server 主包这一项,其他都不变:
| 项 | 受影响 | 说明 |
|---|---|---|
| MySQL Server 主包名 | ✅ 可以走自定义 | 必须本地文件、必须 .tar.gz / .tar.xz |
mysql_version | ❌ 不受影响 | 真实版本仍要写明,不靠包名猜 |
| 目标 OS 判断 | ❌ 不受影响 | 不满足 9.7 的 glibc2.28 仍会失败 |
| 部署拓扑判断 | ❌ 不受影响 | 主从、MGR、IDC 各自的前置仍要满足 |
| MySQL Shell / Router 包 | ❌ 不受影响 | 仍来自支持矩阵 |
| checksum 校验 | ✅ 配了就跑 | 推荐每次都配 |
我个人的几条习惯:
- 正式生产部署优先走支持矩阵里的标准包名和 checksum。
- EA、内部测试、厂内重打包再打开
fcs_allow_custom_mysql_package。 - 自定义包一定单独设置
mysql_software_dir,不要和正式包共享 basedir。 - checksum 能配就配,尤其是经过对象存储、制品库、跳板机多次转运的包。
三台 9.7 EA 实验机已就绪
写到这里,这套实验环境就稳稳挂在那里了:
- 三台 Rocky Linux 9.7 主机,并发部署完成
- 每台一个独立的 MySQL 9.7 EA 单机实例,端口
3308 - basedir、datadir、binlog、配置都是 dbbot 默认布局
- 旁边还顺带跑着
3306的旧实例,多版本不打架
后续 9.7 系列的文章都会基于这套环境展开 —— 省得每篇文章都重新装一遍,也省得每次都解释一遍"为什么我能用 9.7 EA 跑这个测试"。三台机器互相独立,写不同特性时可以各跑各的,互不影响。下一篇就开始挖 9.7 里我比较关注的几个变化,从 release notes 写明的那些先聊起。