Komodo 数据库复制与 FerretDB v2 迁移指南:`km database copy` 实战 Komodo 数据库复制与 FerretDB v2 迁移指南km database copy实战【免费下载链接】komodo a tool to build and deploy software on many servers 项目地址: https://gitcode.com/gh_mirrors/komo/komodoKomodo 的数据库复制工具Copy Database Utility可以在任意两个正在运行的 Mongo 兼容数据库之间迁移全部数据既适用于 MongoDB 与 FerretDB 之间的互迁也适用于 FerretDB v1 向 v2 的版本升级。本文以官方文档 bin/cli/docs/copy-database.md 为主体结合 CLI 源码与数据库复制实现完整讲解复制服务的部署方式、底层复制机制以及 FerretDB v2 五步迁移实操帮助你在不丢失任何资源数据的前提下完成数据库切换。工具定位与适用场景Komodo 将所有核心数据用户、权限、服务器、部署、栈、同步、更新记录等持久化在 Mongo 兼容数据库中。当需要更换数据库后端时不能简单拷贝数据文件因为 MongoDB、FerretDB v1、FerretDB v2 之间的内部数据结构并不一致。官方提供了基于komodo-cli镜像的数据库复制服务它运行在 compose 中以源数据库 → 目标数据库的方式完成全量数据搬移。该工具适用于以下场景MongoDB ↔ FerretDB 互迁在两者之间移动 Komodo 数据FerretDB v1 → v2 升级v2 内部数据结构已变更无法原地升级必须复制到新库任意两个运行中的 Mongo 兼容库之间迁移只需替换源/目标的连接参数。从 CLI 源码看database子命令族共提供五个能力Backup备份、Restore恢复、Prune备份清理、Copy复制别名cp以及V1Downgrade降级到 v1 兼容结构定义见 client/core/rs/src/entities/config/cli/args/database.rs。本篇文章聚焦其中的Copy。快速上手在 compose 中运行复制服务复制服务本身就是一个一次性容器官方推荐直接加进现有 Komodo compose 文件。最简配置如下services: copy_database: image: ghcr.io/moghtech/komodo-cli command: km database copy -y environment: KOMODO_DATABASE_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}source:27017 KOMODO_DATABASE_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} KOMODO_CLI_DATABASE_TARGET_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}target:27017 KOMODO_CLI_DATABASE_TARGET_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo}其中关键点如下镜像ghcr.io/moghtech/komodo-cli即 Komodo 官方 CLI 容器镜像命令km database copy -y。-y--yes跳过一切交互式确认提示适合在 compose / 自动化环境中无人值守运行对应源码中的wait_for_enter(start copy, yes)见 bin/cli/src/command/database.rs。若不传-y容器会等待人工确认源库连接KOMODO_DATABASE_URI指向旧数据库即待迁移的源库名通过KOMODO_DATABASE_DB_NAME指定默认komodo目标库连接KOMODO_CLI_DATABASE_TARGET_URI指向新数据库库名通过KOMODO_CLI_DATABASE_TARGET_DB_NAME指定。连接参数URI 与 address 两种写法从配置解析源码bin/cli/src/config.rs可以看到源库与目标库各自都支持两种连接方式且目标库database_target还有对应的 CLI 命令行参数连接方式源库环境变量Source目标库环境变量Target目标库 CLI 参数database copy完整 URIKOMODO_DATABASE_URIKOMODO_CLI_DATABASE_TARGET_URI--uri地址 账号KOMODO_DATABASE_ADDRESSKOMODO_CLI_DATABASE_TARGET_ADDRESS--address/-a用户名KOMODO_DATABASE_USERNAMEKOMODO_CLI_DATABASE_TARGET_USERNAME--username/-u密码KOMODO_DATABASE_PASSWORDKOMODO_CLI_DATABASE_TARGET_PASSWORD--password/-p库名KOMODO_DATABASE_DB_NAMEKOMODO_CLI_DATABASE_TARGET_DB_NAME--db-name/-d是否建索引——--index/-i默认 true跳过确认——--yes/-ylib/database的连接初始化逻辑lib/database/src/lib.rs规定当uri非空时直接使用 URI否则要求addressusernamepassword三者齐全后拼接连接。也就是说上述两套变量二选一即可。另外两个实用细节--index参数默认true即复制完成后会为目标库重建索引。若希望跳过建索引例如后续还要再做一次复制可以显式传-i false运行时终端会以红色提示Target Db Indexing: DISABLED见 bin/cli/src/command/database.rs配置优先级CLI 参数 环境变量 配置文件从 bin/cli/src/config.rs 的合并顺序可确认。这意味着目标库参数可以完全不写进 compose而在命令行覆盖。复制原理源码级解读km database copy的复制逻辑在lib/database的 lib/database/src/utils/copy.rs 中实现整体流程清晰枚举源库集合调用source_db.list_collection_names()拿到源库全部集合users、servers、deployments、stacks、updates、alerts、stats等按集合并发复制每个集合一个tokio::spawn异步任务多个集合并行复制流式读取 批量 Upsert逐条find文档按_id组装BulkUpdate$set整篇文档攒满缓冲后调用bulk_update_retry_too_big(..., upsert true)批量写入目标库超大文档自适应Update集合单条文档体积远大于其他集合容易触发 BSON 上限因此它的缓冲上限是1_000条其余集合为10_000条幂等可重跑由于采用按_id的 upsert 写入重复执行复制不会产生重复文档可以在失败后安全地再次运行结束日志每个集合复制完成后打印Finished copying {collection} collection | Copied {count}全部完成后打印Finished copying database ✅lib/database/src/utils/copy.rs。复制启动前CLI 会在终端打印源库与目标库的连接信息摘要URI 中的密码会被sanitize_uri脱敏便于人工核对然后再进入确认等待bin/cli/src/command/database.rs。FerretDB v2 升级背景与注意事项在 Komodo 1.17.5 及之前需要使用 Postgres / SQLite 后端的用户被引导部署FerretDB v1。如今 FerretDB v2 已经发布v1 将逐渐失去官方支持。官方建议用户迁移到 v2 以获得更好的性能与持续更新支持但需要注意v2 的内部数据结构已经改变无法原地升级必须通过复制工具搬到新库FerretDB v2 不再支持 SQLite仅支持定制的 Postgres 发行版DocumentDB 版 Postgres即便如此FerretDB 仍然是主机无法运行 MongoDB场景下的可靠替代方案本文的迁移流程同样适用于MongoDB 与 FerretDB 互迁只需把新数据库换成你实际要迁入的目标即可。五步迁移实操FerretDB v1 → v2Step 1将新数据库加入 compose 文件顶部在现有 Komodo compose.yaml 中新增postgres2与ferretdb2两个服务。不要忘记同时声明新的 volumes。## In Komodo compose.yaml services: postgres2: # Recommended: Pin to a specific version # https://github.com/FerretDB/documentdb/pkgs/container/postgres-documentdb image: ghcr.io/ferretdb/postgres-documentdb labels: komodo.skip: # Prevent Komodo from stopping with StopAllContainers restart: unless-stopped # ports: # - 5432:5432 volumes: - postgres-data:/var/lib/postgresql/data environment: POSTGRES_USER: ${KOMODO_DB_USERNAME} POSTGRES_PASSWORD: ${KOMODO_DB_PASSWORD} POSTGRES_DB: postgres # Do not change ferretdb2: # Recommended: Pin to a specific version # https://github.com/FerretDB/FerretDB/pkgs/container/ferretdb image: ghcr.io/ferretdb/ferretdb labels: komodo.skip: # Prevent Komodo from stopping with StopAllContainers restart: unless-stopped depends_on: - postgres2 # ports: # - 27017:27017 volumes: - ferretdb-state:/state environment: FERRETDB_POSTGRESQL_URL: postgres://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}postgres2:5432/postgres ...(unchanged) volumes: ...(unchanged) postgres-data: ferretdb-state:要点说明komodo.skip标签防止 Komodo 的 StopAllContainers 等操作把这些数据库容器一并停掉在compose/mongo.compose.yaml的mongo服务上也有同样的用法见 compose/mongo.compose.yaml端口映射默认注释数据库只在内网互通不暴露到宿主机POSTGRES_DB: postgres不要改动这是 FerretDB DocumentDB 约定的数据库名建议把镜像 pin 到具体版本便于复现与回滚。Step 2加入数据库复制服务copy_database服务的SOURCE_URI指向现有旧数据库即旧 FerretDB v1。旧 v1 的部署方式不同连接串也不同旧库使用Postgres后端使用下方示例中的带认证的 URI旧库使用SQLite后端直接使用类似mongodb://ferretdb:27017的地址即可。## In Komodo compose.yaml services: ...(new database) copy_database: image: ghcr.io/moghtech/komodo-cli command: km database copy -y environment: KOMODO_DATABASE_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}ferretdb:27017/${KOMODO_DATABASE_DB_NAME:-komodo}?authMechanismPLAIN KOMODO_DATABASE_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} KOMODO_CLI_DATABASE_TARGET_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}ferretdb2:27017 KOMODO_CLI_DATABASE_TARGET_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} ...(unchanged)此处源库 URI 中的?authMechanismPLAIN是 FerretDB v1 的认证机制要求务必保留。目标库指向新增的ferretdb2服务。Step 3Compose Up 启动新数据库并执行复制运行以下命令把xxxxx.compose.yaml换成你实际的 compose 文件名docker compose -p komodo --env-file compose.env -f xxxxx.compose.yaml up -d该命令会同时启动旧库与新库并触发copy_database服务执行数据复制。等待片刻让复制容器跑完容器退出后检查日志确认数据是否成功迁移每个集合会打印Finished copying ... Copied {count}确认无误后再进入下一步。Step 4将 Komodo Core 指向新数据库在 compose.yaml 中先注释掉copy_database服务与旧的 ferretdb v1 服务然后把core服务的数据库环境变量改为指向ferretdb2services: ... core: ...(unchanged) environment: KOMODO_DATABASE_ADDRESS: ferretdb2:27017 KOMODO_DATABASE_USERNAME: ${KOMODO_DB_USERNAME} KOMODO_DATABASE_PASSWORD: ${KOMODO_DB_PASSWORD}这里使用的是 Core 的地址 账号 密码连接方式KOMODO_DATABASE_ADDRESS与KOMODO_DATABASE_USERNAME/KOMODO_DATABASE_PASSWORD在 config/core.config.toml 中有完整注释说明。如果需要走完整 URI也可以用KOMODO_DATABASE_URIconfig/core.config.toml。Step 5最终 Compose Up 并验证再次执行与 Step 3 相同的docker compose命令使改动生效然后打开 Komodo 的 Web 页面能正常访问恭喜迁移完成。之后可以清理 compose 文件中已注释的旧服务、旧 volumes 等遗留内容无法访问查看容器日志定位问题必要时可以撤销前面几步把core的数据库配置改回旧库回滚到迁移前状态。进阶CLI 直接运行复制非容器方式除容器外也可以直接用 CLI 二进制执行复制。参考 bin/cli/README.md 安装komodo_cli后目标库参数既可以用环境变量KOMODO_CLI_DATABASE_TARGET_*也可以用命令行参数直接覆盖例如komodo database copy -y \ --uri mongodb://user:passtarget:27017 \ --db-name komodo源库仍从KOMODO_DATABASE_URI或KOMODO_DATABASE_ADDRESS等读取。这样便于在脚本中临时指定目标而无需改动持久化配置。常见问题速查问题处理建议复制容器一直等待不退出命令中没有-y容器在等待人工确认确认交互式环境或补上-y日志提示某集合复制失败单个集合失败不会中断整体检查源/目标连接权限然后重跑upsert 幂等可安全重试Update集合复制报 BSON 过大复制实现已对Update集合使用更小的1_000条批量缓冲lib/database/src/utils/copy.rs若仍失败请确认目标库版本与 BSON 限制迁移后 Web 无法访问检查core日志与数据库连接变量必要时按 Step 4 回滚连接配置旧库是 SQLite 后端源 URI 简化为mongodb://ferretdb:27017不需要用户名密码与authMechanismPLAIN参考资源官方文档原文bin/cli/docs/copy-database.mdCopy命令实现bin/cli/src/command/database.rsCLI 参数定义client/core/rs/src/entities/config/cli/args/database.rs配置解析与优先级bin/cli/src/config.rs复制算法实现lib/database/src/utils/copy.rs数据库连接初始化lib/database/src/lib.rsCore 数据库配置项config/core.config.tomlMongoDB 部署参考compose/mongo.compose.yaml【免费下载链接】komodo a tool to build and deploy software on many servers 项目地址: https://gitcode.com/gh_mirrors/komo/komodo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考