5.5 KiB
5.5 KiB
todos:
- id: "add-compose-service" content: "在 docker-compose.yml 新增 slotMysql 服务(镜像 8.0.33、卷 datadir_slot_mysql、端口 3310)" status: pending
- id: "start-slotmysql" content: "docker compose up -d slotMysql 并等待 mysqladmin ping 就绪" status: pending
- id: "dump-restore" content: "mysqldump 全库管道导入 slotMysql(--single-transaction --set-gtid-purged=OFF)" status: pending
- id: "verify-data" content: "对比库列表并抽样校验表行数,确认复制成功" status: pending isProject: false
创建 slotMysql 并复制 goMysql 数据
现状
| 项目 | goMysql(现有) |
|---|---|
| 镜像 | mysql:8.0.33 |
| 数据卷 | docker/data/datadir_go_mysql(约 7.3G) |
| 宿主机端口 | 3309 → 容器 3306 |
| root 密码 | root |
| 库数量 | 约 70 个(全库复制) |
配置来源:docker/docker-compose.yml 第 41–53 行。
目标架构
flowchart LR
subgraph docker_net [default network]
goMysql["goMysql :3306"]
slotMysql["slotMysql :3306"]
php82[php82]
end
host3309["宿主机 :3309"] --> goMysql
host3310["宿主机 :3310"] --> slotMysql
php82 -->|"现有 .env 仍连 goMysql"| goMysql
goMysql -->|"mysqldump 全库"| slotMysql
两容器并行运行、数据独立;应用暂不切换。
步骤 1:在 docker-compose 中新增 slotMysql
编辑 docker/docker-compose.yml,在 goMysql 服务后追加:
slotMysql:
image: mysql:8.0.33
container_name: slotMysql
working_dir: /app
volumes:
- /Users/ray/Documents/project:/app
- ./data/datadir_slot_mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- "3310:3306"
networks:
- default
要点:
- 独立数据卷
./data/datadir_slot_mysql(首次up时自动初始化空实例) - 宿主机端口
3310(3309已被 goMysql 占用) - 与 goMysql 同镜像、同密码、同网络,便于容器内互访
步骤 2:启动 slotMysql 并等待就绪
cd /Users/ray/Documents/project/docker
docker compose up -d slotMysql
轮询直到可连接(约 30–60 秒):
docker exec slotMysql mysqladmin -uroot -proot ping
步骤 3:全库逻辑复制(推荐方式)
选用逻辑导出/导入,原因:
- goMysql 无需停机,现有应用不受影响
- 避免直接拷贝
datadir带来的 InnoDB 文件锁/UUID 冲突风险 - 两容器版本一致(
8.0.33),兼容性有保障
在宿主机执行(管道直连,不落盘大 SQL 文件):
docker exec goMysql mysqldump -uroot -proot \
--all-databases \
--single-transaction \
--routines \
--triggers \
--events \
--set-gtid-purged=OFF \
| docker exec -i slotMysql mysql -uroot -proot
参数说明:
--single-transaction:InnoDB 一致性快照,复制期间 goMysql 可继续读写--set-gtid-purged=OFF:本地开发环境无 GTID 复制,避免导入报错
预计耗时:7.3G 数据约 15–45 分钟,视磁盘 IO 而定;期间勿重启两容器。
备选方案(未采用)
直接 cp -a datadir_go_mysql → datadir_slot_mysql 需停止 goMysql,且有 binlog/ibdata 一致性风险;仅适合可接受停机且追求极速的场景。本次不采用。
步骤 4:验证数据一致性
# 库数量对比
docker exec goMysql mysql -uroot -proot -N -e "SHOW DATABASES;" | sort > /tmp/go_dbs.txt
docker exec slotMysql mysql -uroot -proot -N -e "SHOW DATABASES;" | sort > /tmp/slot_dbs.txt
diff /tmp/go_dbs.txt /tmp/slot_dbs.txt
# 抽样校验行数(示例)
docker exec goMysql mysql -uroot -proot -N -e "SELECT COUNT(*) FROM s_common.some_table"
docker exec slotMysql mysql -uroot -proot -N -e "SELECT COUNT(*) FROM s_common.some_table"
连通性验证:
- 容器内:
docker exec slotMysql mysql -uroot -proot -e "SELECT 1" - 宿主机:
mysql -h127.0.0.1 -P3310 -uroot -proot -e "SHOW DATABASES;"(若本机有 mysql 客户端)
步骤 5:日常使用说明
| 访问方式 | 命令/地址 |
|---|---|
| 容器内(php82 等) | slotMysql:3306,用户 root,密码 root |
| 宿主机 | 127.0.0.1:3310 |
| 启停 | docker compose up -d slotMysql / docker compose stop slotMysql |
不改动 www/slot 及各服务 .env 中的 DB_*_HOST = 'goMysql';后续若要切换,再批量改 host 并重启对应 Webman 进程。
风险与注意
- 复制期间 goMysql 有新写入:
--single-transaction保证 InnoDB 表一致;MyISAM 表(若有)可能略有偏差,开发环境通常可接受。 - 磁盘空间:
datadir_slot_mysql将再占约 7G+,确保/Users/ray/Documents/project/docker/data所在磁盘有余量。 - 复制失败重试:若导入中断,最干净做法是
docker compose stop slotMysql,删除datadir_slot_mysql目录后重新up再导入。 - 用户/权限:
--all-databases会同步mysql系统库中的用户与授权,root 密码与 goMysql 一致。
涉及文件
- 修改:
docker/docker-compose.yml - 新建(自动):
docker/data/datadir_slot_mysql/ - 不修改:各服务
.env、php82等现有配置