--- 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`](/Users/ray/Documents/project/docker/data/datadir_go_mysql)(约 7.3G) | | 宿主机端口 | `3309` → 容器 `3306` | | root 密码 | `root` | | 库数量 | 约 70 个(全库复制) | 配置来源:[`docker/docker-compose.yml`](/Users/ray/Documents/project/docker/docker-compose.yml) 第 41–53 行。 ## 目标架构 ```mermaid 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`](/Users/ray/Documents/project/docker/docker-compose.yml),在 `goMysql` 服务后追加: ```yaml 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 并等待就绪 ```bash cd /Users/ray/Documents/project/docker docker compose up -d slotMysql ``` 轮询直到可连接(约 30–60 秒): ```bash docker exec slotMysql mysqladmin -uroot -proot ping ``` ## 步骤 3:全库逻辑复制(推荐方式) **选用逻辑导出/导入**,原因: - goMysql **无需停机**,现有应用不受影响 - 避免直接拷贝 `datadir` 带来的 InnoDB 文件锁/UUID 冲突风险 - 两容器版本一致(`8.0.33`),兼容性有保障 在宿主机执行(管道直连,不落盘大 SQL 文件): ```bash 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:验证数据一致性 ```bash # 库数量对比 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`](/Users/ray/Documents/project/www/slot) 及各服务 `.env` 中的 `DB_*_HOST = 'goMysql'`;后续若要切换,再批量改 host 并重启对应 Webman 进程。 ## 风险与注意 1. **复制期间 goMysql 有新写入**:`--single-transaction` 保证 InnoDB 表一致;MyISAM 表(若有)可能略有偏差,开发环境通常可接受。 2. **磁盘空间**:`datadir_slot_mysql` 将再占约 7G+,确保 `/Users/ray/Documents/project/docker/data` 所在磁盘有余量。 3. **复制失败重试**:若导入中断,最干净做法是 `docker compose stop slotMysql`,删除 `datadir_slot_mysql` 目录后重新 `up` 再导入。 4. **用户/权限**:`--all-databases` 会同步 `mysql` 系统库中的用户与授权,root 密码与 goMysql 一致。 ## 涉及文件 - 修改:[`docker/docker-compose.yml`](/Users/ray/Documents/project/docker/docker-compose.yml) - 新建(自动):`docker/data/datadir_slot_mysql/` - 不修改:各服务 `.env`、`php82` 等现有配置