Files
cmautobuy/docs/admin/09-sqlite迁移到mysql.md

3.2 KiB

SQLite 单向迁移到 MySQL 8

这份文档用于把历史 admin.db 一次性迁移到新的空 MySQL 8 数据库。迁移不是同步:成功切换后只使用 MySQL,不再把数据写回 SQLite。

1. 安全边界

  • 源 admin.db 必须是 schema v8;工具使用操作系统只读模式和 SQLite query_only 打开。
  • 目标必须是本程序刚建立且业务表为空的独立 MySQL 数据库;任何业务表非空都会拒绝执行。
  • 不支持覆盖、合并、双写和重复导入。重新演练时新建另一个空测试库。
  • 迁移命令优先使用环境变量传入数据库密码;Windows 本地也可读取被 Git 忽略的 admin/config.yaml。两种方式都不得把密码写入命令历史、仓库、日志或工单。
  • 输出只包含表名和数量,不包含账号、Cookie、Session、订单号或商品明细。

2. 迁移前准备

先停止旧 Admin 的写入,复制一份只读备份,并记录哈希。以下命令从 admin/ 目录执行:

New-Item -ItemType Directory -Force data\backup
Copy-Item data\admin.db data\backup\admin-before-mysql.db
Get-FileHash data\admin.db -Algorithm SHA256

由数据库管理员提前创建独立的空数据库和最小权限账号。按部署环境设置这五个变量:

$env:CMAUTOBUY_DB_HOST="127.0.0.1"
$env:CMAUTOBUY_DB_PORT="3307"
$env:CMAUTOBUY_DB_NAME="<空数据库名>"
$env:CMAUTOBUY_DB_USER="<迁移账号>"
$env:CMAUTOBUY_DB_PASSWORD="<从安全渠道取得>"

3. 先演练

go run ./cmd/migrate-sqlite-to-mysql --source data/admin.db --dry-run

预期第一行是“演练检查通过,未写入数据”,后面只显示 15 张业务表的数量。此时 MySQL 业务表仍为空。

4. 执行并独立复核

go run ./cmd/migrate-sqlite-to-mysql --source data/admin.db --execute
go run ./cmd/migrate-sqlite-to-mysql --source data/admin.db --verify-only
Get-FileHash data\admin.db -Algorithm SHA256

--execute 在一个 MySQL 事务中导入全部业务表,然后比较源、目标的逐表数量和全列摘要。--verify-only 再独立读取两边核对一次。最后的 SQLite 哈希应与迁移前一致。

5. 失败时怎样处理

  • “SQLite schema 必须是 v8”:先用旧版本 Admin 的迁移逻辑把备份副本升级到 v8,不要直接改 user_version。
  • “MySQL 目标不是空库”:停止操作,换一个新的空数据库;不要手工清表后继续生产迁移。
  • “无法写入 MySQL”或“数量或内容摘要不一致”:不要启动新 Admin;保留源库和迁移前备份,丢弃本次目标库,修复原因后在新的空库重演。
  • 迁移失败会回滚业务数据;MySQL schema 建表是可重放的,但业务数据绝不能部分保留后继续补写。

6. 切换门禁

只有下面各项都完成后才能让生产 Admin 使用新库:

  • 演练、正式迁移和 --verify-only 均通过;
  • SQLite 文件哈希迁移前后相同;
  • MySQL 已备份,Admin 环境变量由系统服务安全注入;
  • 页面登录、蝦皮/PDD/顺运宝列表、客户端领取和一次演练模式采购任务冒烟通过;
  • 旧 admin.db 保留为只读回退证据,不再由 Admin 打开。