☰
DBmotion容器化迁移:一条docker-compose命令搭建全链路环境
2026/10/13 3:22:28 网站建设 项目流程

简介:DBmotion全量容器集合面向数据库迁移与运维场景,将数据库、迁移引擎、监控告警和Web界面等核心组件打包为可分发镜像,并附可执行的docker-compose.yaml,解决多服务部署繁琐、环境不一致的问题。资源共11个文件,含10个gz容器镜像包和1个yaml编排文件,包体约738.34MB,适合内网或离线环境一次性导入。镜像包覆盖MySQL、Phoenix、Prometheus、Grafana、Alertmanager等数据库与可观测性组件,yaml文件统一定义网络、端口映射、卷挂载等参数,执行docker-compose up即可一键启动整套服务,从数据库实例到迁移代理、监控面板均覆盖完整链路。已有48人学习下载。开发、运维人员拿到后,可快速完成迁移工具链的部署与验证,省去手工拉取镜像、逐个配置容器依赖和联调连通性的环节,显著缩短环境准备时间,是一种可复用的DBmotion工程化交付方案。

1. DBmotion 容器集合是什么:一条 compose 命令撑起迁移全链路

接手 DBmotion 数据库迁移任务,最先让人上头的往往不是迁移规则怎么配,而是环境怎么搭。源库一个实例、目标 openGauss 一个实例、DBmotion 的 web 调度端和 worker 执行端、再加上存迁移元数据的库,细算下来至少四个进程。手工装过的人都知道,JDK 版本、驱动路径、内存参数,每个环节都埋着雷,排错排到怀疑人生。这套标题里的方案则直接换了个思路:把 DBmotion 全量迁移链路里需要的每个角色都装进容器,再配一份可执行的 docker-compose.yaml,让整个迁移环境一条命令起来。适合刚接触 openGauss 迁移、要做 POC 验证、准备培训环境的团队。下面我把组件拆开、compose 逐段讲透,再把最常见的那几个坑挨个说清楚。

2. 拆容器集合:web、worker、源库、目标库和元数据库各司其职

2.1 web 调度端和 worker 执行端:一体两面的迁移架构

DBmotion 并不是一个臃肿的单体程序,它天生就拆成了两个角色:web 端负责交互,worker 端负责执行。你在浏览器里配置迁移任务、选择源库和目标库、做表映射、提交任务,这些操作走的都是 web 服务。真正去连接源库读取数据、把数据写入目标库的,是后面那个默默干活的 worker。

这两个角色拆成独立容器,带来一个很实际的好处:web 重启不会打断已经在跑的数据迁移任务,worker 因为无状态,可以随时替换和重新拉起。DBmotion 的 worker 是 Java 应用,容器化以后最值得留意的是 JVM 堆参数,这一点我在第四章专门讲。拆开部署还有一个附带价值——你需要并发跑多组迁移时,可以起多个 worker 实例分摊压力,migration 任务调度天然支持这种水平扩展。

如果你只是在本机验证功能,web 和 worker 放同一个容器里确实显得省事,但这种省事会在第一次排查问题时反噬你:日志混在一起、版本升级互相牵制、内存无法单独限制。既然标题给的是“全量容器集合”,那就老老实实按角色拆开。

2.2 源库、目标库与元数据库:数据链路的三类角色

搞清楚这条迁移链路,需要分清楚三个数据库各干什么。第一个是源库,DBmotion 全量迁移支持 MySQL、Oracle 等常见关系型数据库,容器集合里我用 MySQL 5.7 做演示。第二个是目标库,openGauss 或 GaussDB 系数据库,容器镜像直接用 openGauss 官方镜像。第三个最容易被忽略,是元数据库。它不存业务数据,存的是 DBmotion 自己的任务定义、执行计划、迁移进度、错误记录。

为什么需要元数据库?因为 web 和 worker 是两个独立进程,它们之间需要共享同一份任务状态。worker 执行到哪一步、失败了多少行、下次从哪个断点继续,这些信息都记录在元数据库里。用 MySQL 做这个角色很常见,DBmotion 自身就兼容。容器集合里把它单独做成一个服务,用命名卷持久化,任务记录就不会因为容器重建而丢失。

数据迁移时的访问路径是:web 和 worker 都通过 JDBC 连元数据库;worker 再从源库读数据,写入目标库。这条链路上每个连接串的地址,在 compose 网络里都应该是服务名,而不是 localhost。这个细节非常容易翻车,第五章会单独说。

2.3 为什么这套集合用 docker-compose 编排而不是其他方式

有人会问,这些容器直接用 docker run 一条条启动不就完了,何必非要一份 docker-compose.yaml?如果你是两三个容器,docker run 确实够用。但 DBmotion 全量链路一旦把源库、目标库、元库、web、worker 算全,手工 docker run 要处理的参数量就开始失控:每次都要手写 --network、--link、--volume、--env,容器重启后 IP 变了还得重新关联。

docker-compose 的价值在于把整个容器集合的拓扑声明式地固化下来。网络定义在 networks 段,卷定义在 volumes 段,服务之间的依赖顺序用 depends_on 控制,环境变量直接在文件里改。这份 docker-compose.yaml 一旦能用,换一台机器就是 git clone 加 docker compose up 的事,这就是标题里“可执行”三个字的分量。

对比 Kubernetes,单机联调或 POC 场景上 k8s 就是大炮打蚊子,光装集群组件就把迁移验证的时间耗掉大半。compose 的目标场景很明确:单机、开发联调、测试环境、小规模生产前置验证。它做的事情足够简单,所以也更可靠。

3. 复现可执行的 docker-compose.yaml:目录、配置与最小演示

3.1 准备目录结构和镜像预检

拿到这套容器集合,第一步不是直接 up,而是先确认目录结构和镜像状态。一个规范的目录应该把初始化脚本、环境变量、数据目录分开,避免把所有东西堆在根目录。

dbmotion-all/ ├── docker-compose.yaml ├── init/ │ └── source/ │ └── 01-demo.sql ├── conf/ │ └── worker.env └── data/ └── worker-logs/
  1. init/source目录存放源库初始化脚本,MySQL 容器首次启动时会自动执行该目录下所有 SQL。
  2. conf/worker.env用来集中管理 worker 的运行参数,避免把环境变量全部塞进 compose 文件。
  3. data/worker-logs挂载到 worker 容器内,迁移日志落盘到宿主机,方便排查。

写好了 docker-compose.yaml,先用配置校验命令确认格式无误,再拉取和检查镜像是否都就位:

docker compose config --quiet docker compose images

第一条命令的输出为空代表 YAML 语法和字段引用没有问题,如果字段写错,报错在 up 之前就能暴露出来。第二条命令列出 compose 里所有服务的镜像名和 tag,方便确认有没有哪个镜像本地缺失。镜像没拉全时,继续执行docker compose pull单独补齐,而不是等到 up 阶段才卡在拉取上。

3.2 核心 compose 配置:完整文件与逐段解读

下面这份就是整套容器集合的核心,一个可直接运行的 docker-compose.yaml。它把 web、worker、元数据库、源库、目标库五个服务全部编排进同一个 bridge 网络:

name: dbmotion-all services: dbmotion-web: image: dbmotion/web:2.0.0 container_name: dbmotion-web restart: unless-stopped ports: - "8080:8080" environment: SERVER_PORT: "8080" WORKER_ADDR: http://dbmotion-worker:8081 META_DB_URL: jdbc:mysql://meta-db:3306/dbmotion?useSSL=false&characterEncoding=utf8 META_DB_USER: dbmotion META_DB_PASSWORD: DbMotion@123 depends_on: meta-db: condition: service_healthy networks: - dbmotion-net dbmotion-worker: image: dbmotion/worker:2.0.0 container_name: dbmotion-worker restart: unless-stopped environment: WORKER_PORT: "8081" JAVA_OPTS: "-Xmx2g -Xms512m" META_DB_URL: jdbc:mysql://meta-db:3306/dbmotion?useSSL=false&characterEncoding=utf8 META_DB_USER: dbmotion META_DB_PASSWORD: DbMotion@123 volumes: - ./data/worker-logs:/opt/dbmotion/logs depends_on: meta-db: condition: service_healthy networks: - dbmotion-net meta-db: image: mysql:5.7 container_name: dbmotion-meta restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: Root@123 MYSQL_DATABASE: dbmotion MYSQL_USER: dbmotion MYSQL_PASSWORD: DbMotion@123 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pDbMotion@123"] interval: 5s timeout: 3s retries: 12 volumes: - meta-data:/var/lib/mysql networks: - dbmotion-net source-mysql: image: mysql:5.7 container_name: demo-source restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: Root@123 MYSQL_DATABASE: demo_src ports: - "3306:3306" volumes: - ./init/source:/docker-entrypoint-initdb.d:ro - source-data:/var/lib/mysql networks: - dbmotion-net target-opengauss: image: opengauss/opengauss:5.0.0 container_name: demo-target restart: unless-stopped environment: GS_PASSWORD: openGauss@123 ports: - "5432:5432" volumes: - target-data:/var/lib/opengauss networks: - dbmotion-net networks: dbmotion-net: driver: bridge volumes: meta-data: source-data: target-data:

这段配置里最关键的是第一行的name字段,它显式声明了 compose 项目名,避免多个工程混在一起时容器名冲突。depends_on配合condition: service_healthy是我强烈建议保留的写法:它让 web 和 worker 等元数据库通过健康检查后再启动,否则 MySQL 初始化需要十几秒,web 先启动就会反复重试数据库连接,日志里堆满异常。

dbmotion-web对外只暴露 8080 端口,这是控制台访问入口;dbmotion-worker的 8081 端口只在内网使用,所以 compose 里没有配置 ports 映射。JAVA_OPTS里-Xmx2g限制了 worker 的 JVM 堆上限,这个参数直接决定了容器不会被宿主机的物理内存拖垮。三个数据卷meta-data、source-data、target-data用来持久化数据库文件,容器删了重建数据还在。

注意到一个细节:source-mysql把init/source目录以只读方式挂载到了/docker-entrypoint-initdb.d。MySQL 官方镜像在首次初始化数据目录时,会按文件名顺序执行这个目录里的 SQL 脚本,这正是我们给源库造演示数据的入口。

3.3 最小演示迁移:源库造数据,目标库收数据

为了让这套容器集合跑通一个看得见结果的迁移,先在init/source/01-demo.sql里写一段初始化数据:

CREATE DATABASE IF NOT EXISTS demo_src; USE demo_src; CREATE TABLE t_user ( id INT PRIMARY KEY, name VARCHAR(50), email VARCHAR(100), created_at DATETIME ); INSERT INTO t_user VALUES (1, 'Alice', 'alice@example.com', NOW()), (2, 'Bob', 'bob@example.com', NOW()), (3, 'Carol', 'carol@example.com', NOW());

这段 SQL 创建的t_user表会被源库容器首次启动时自动加载,三个人的测试数据就是全量迁移的素材。启动整套容器集合只需要一条命令:

docker compose up -d docker compose ps

-d参数让容器在后台运行。第二条命令输出各容器的状态,正常情况下五个服务都应该显示 Up,web 显示 healthy 是最终目标。如果某个容器反复重启,立刻看对应的日志:

docker compose logs -f dbmotion-worker

日志里能看到 worker 启动时连接元数据库、注册到 web 的完整过程,这是排查问题的第一现场。容器全部就绪后,浏览器访问http://宿主机IP:8080,用部署时配置的管理员账号登录,在 web 界面里新建迁移任务,源库地址填source-mysql:3306,目标库地址填target-opengauss:5432。这里填服务名而不是 localhost,原因是 web 和 worker 容器内部的 localhost 指向容器自己,只有通过 compose 网络里的服务名才能正确路由到源库和目标库。

任务提交后,worker 开始执行全量迁移,表的行数和进度可以在 web 界面看到。迁移完成后去目标库查数据,就能看到从源库搬过来的三条记录。

4. 微调四类参数:端口映射、资源限制、网络模式与持久化

4.1 端口冲突与映射规则

容器集合跑在单机上,最常遇到的第一个障

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询