Files
cursor/plans/slotMysql-82f6bca9.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

5.5 KiB
Raw Blame History


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 第 4153 行。

目标架构

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 时自动初始化空实例)
  • 宿主机端口 33103309 已被 goMysql 占用)
  • 与 goMysql 同镜像、同密码、同网络,便于容器内互访

步骤 2启动 slotMysql 并等待就绪

cd /Users/ray/Documents/project/docker
docker compose up -d slotMysql

轮询直到可连接(约 3060 秒):

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-transactionInnoDB 一致性快照,复制期间 goMysql 可继续读写
  • --set-gtid-purged=OFF:本地开发环境无 GTID 复制,避免导入报错

预计耗时7.3G 数据约 1545 分钟,视磁盘 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 进程。

风险与注意

  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
  • 新建(自动):docker/data/datadir_slot_mysql/
  • 不修改:各服务 .envphp82 等现有配置