mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): rehearse legacy sqlite upgrade
This commit is contained in:
@@ -157,6 +157,11 @@ receipt。
|
||||
|
||||
### 2.2 adopted 2.x 的 Docker legacy silence gate
|
||||
|
||||
已有 2.x SQLite 部署必须先完成
|
||||
[`inspect → stage → verify → activation`](./ql3-local-sqlite-adoption.md),取得真实、未手写的 manifest、activation 与 digest。
|
||||
下列 silence/cutover 命令只消费该证据,不负责隐式迁移数据库。source、target 和 recovery 必须一直保留到回退或 reconciliation
|
||||
正式闭合。
|
||||
|
||||
adopted target 不得直接使用旧 v1 配置启动。当前第一条可达的 cutover 产品路径只接管由
|
||||
Docker 精确容器 ID 标识的 2.x owner;systemd/OpenRC legacy、Kubernetes 和远端 cluster
|
||||
不允许伪装成 Docker evidence。先确保 deployment root 与其 `service/` 都是当前 UID 的
|
||||
@@ -399,11 +404,12 @@ reconciliation_required
|
||||
manual_review
|
||||
```
|
||||
|
||||
- `rollback_candidate`:target 主文件仍等于 activation 初始 SHA-256、source 仍等于 recovery SHA-256,
|
||||
- `rollback_candidate`:target 主文件仍等于 activation 的 `targetSha256`、source 仍等于 activation 的
|
||||
`sourceSha256`,
|
||||
且两者均没有 `-wal`、`-shm`、`-journal` sidecar。
|
||||
- `reconciliation_required`:target 主文件已经变化,或发现 target SQLite sidecar;必须保留 target 并进入
|
||||
后续数据域 reconciliation,不能启动 2.x。
|
||||
- `manual_review`:activation/文件稳定身份不能证明,或 target 未写但 source 已偏离 recovery;不得猜测。
|
||||
- `manual_review`:activation/文件稳定身份不能证明,或 target 未写但 source 已偏离 activation 时原始 source;不得猜测。
|
||||
|
||||
`rollback_candidate` 本身不是 legacy restart 授权。实例 head 成功后进入 `target_stopped`,旧 restart
|
||||
command 会在 Docker authority 前失败;只有下一节的双阶段 ceremony 可以请求启动 2.x。
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
# QingLong 2.x SQLite 接管到 3.0
|
||||
|
||||
本流程把已有 QingLong 2.x `database.sqlite` 以不覆盖 source 的方式接管为 3.0 adopted storage。它只处理单个 SQLite 主库;
|
||||
scripts、configs、logs 和其他 data directory 文件不在本流程内。
|
||||
|
||||
全部命令由最终运行 QingLong 的同一个 POSIX 用户执行。`ql3-adoption` 是一次性 CLI,不启动服务,也不会自动执行 cutover 或
|
||||
Legacy rollback。
|
||||
|
||||
## 1. 空间与停机前检查
|
||||
|
||||
- `deploymentRoot` 及输出父目录必须是当前 UID、canonical、非 symlink 的 `0700` 目录;
|
||||
- command file 必须是当前 UID、canonical、单链接 `0600` 文件;
|
||||
- source 必须是当前 UID 的 canonical 普通单链接文件,且 group/world 不可写;生产环境建议 `0600`;
|
||||
- target、recovery、manifest、activation 必须尚不存在,并全部位于 `deploymentRoot` 内;
|
||||
- source、target、recovery、manifest、activation 五个路径必须互不相同;
|
||||
- 预留 recovery + target 两份数据库以及 SQLite 临时/sidecar 余量。不要以删除 recovery 的方式解决空间不足。
|
||||
|
||||
inspect 和 Online Backup 可以在 2.x 仍可读时执行,但最终 stage review 后到 activation/cutover 期间必须停止外部 writer,并保证
|
||||
source 不再漂移。activation prepare 会尝试取得 source/target write fence;无法取得时失败关闭。
|
||||
|
||||
低配设备说明:四个阶段都是 one-shot 进程,没有后台 timer、监听端口或自动重试;schema inventory 最多 4096 项,manifest 最多
|
||||
256 KiB,SQLite backup 按页复制而不是把整个数据库载入 JS heap。制品审计的 import RSS 不是迁移峰值承诺,正式升级前仍需在目标
|
||||
路由器/NAS 上测量可用空间、耗时、峰值 RSS 和断电恢复。
|
||||
|
||||
## 2. Inspect:生成待审核计划
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"operation": "local-sqlite.adoption.inspect",
|
||||
"options": {
|
||||
"deploymentRoot": "/opt/qinglong3",
|
||||
"profile": "edge",
|
||||
"sourcePath": "/opt/qinglong/data/database.sqlite",
|
||||
"legacyTimezone": "Asia/Shanghai"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
chmod 0600 /secure/operator/ql3-sqlite-inspect.json
|
||||
ql3-adoption run --command-file /secure/operator/ql3-sqlite-inspect.json
|
||||
```
|
||||
|
||||
记录返回的 `planDigest`,审核 schema catalog、table names 与 task inventory。不要在审核后修改 source;若 source 变化,重新 inspect,
|
||||
不要沿用旧 digest。
|
||||
|
||||
## 3. Stage:生成 recovery、target 与 manifest
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"operation": "local-sqlite.adoption.stage",
|
||||
"options": {
|
||||
"deploymentRoot": "/opt/qinglong3",
|
||||
"profile": "edge",
|
||||
"sourcePath": "/opt/qinglong/data/database.sqlite",
|
||||
"targetPath": "/opt/qinglong3/artifacts/qinglong3.sqlite",
|
||||
"recoveryPath": "/opt/qinglong3/artifacts/database.pre-ql3.sqlite",
|
||||
"manifestPath": "/opt/qinglong3/artifacts/qinglong3-adoption.json",
|
||||
"expectedPlanDigest": "REPLACE_WITH_INSPECT_PLAN_DIGEST",
|
||||
"legacyTimezone": "Asia/Shanghai"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
chmod 0600 /secure/operator/ql3-sqlite-stage.json
|
||||
ql3-adoption run --command-file /secure/operator/ql3-sqlite-stage.json
|
||||
```
|
||||
|
||||
stage 通过 SQLite Online Backup 创建独立 recovery 和 target,只在 target 上执行 3.0 migration,并以 `0600` no-replace 文件发布
|
||||
结果。source 不会被覆盖。任一输出已存在时不要删除后盲目重跑,应先把现有文件和命令结果作为一次未完成 ceremony 调查。
|
||||
|
||||
## 4. Verify:独立复验 staged 结果
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"operation": "local-sqlite.adoption.verify",
|
||||
"options": {
|
||||
"deploymentRoot": "/opt/qinglong3",
|
||||
"profile": "edge",
|
||||
"targetPath": "/opt/qinglong3/artifacts/qinglong3.sqlite",
|
||||
"recoveryPath": "/opt/qinglong3/artifacts/database.pre-ql3.sqlite",
|
||||
"manifestPath": "/opt/qinglong3/artifacts/qinglong3-adoption.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
chmod 0600 /secure/operator/ql3-sqlite-verify.json
|
||||
ql3-adoption run --command-file /secure/operator/ql3-sqlite-verify.json
|
||||
```
|
||||
|
||||
记录返回的 `manifestDigest`。verify 只接受与 manifest 一致的 recovery/target、完整 migration 和通过的 adopted readiness。
|
||||
|
||||
## 5. Prepare activation:冻结三份物理事实
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"operation": "local-sqlite.activation.prepare",
|
||||
"options": {
|
||||
"deploymentRoot": "/opt/qinglong3",
|
||||
"profile": "edge",
|
||||
"sourcePath": "/opt/qinglong/data/database.sqlite",
|
||||
"targetPath": "/opt/qinglong3/artifacts/qinglong3.sqlite",
|
||||
"recoveryPath": "/opt/qinglong3/artifacts/database.pre-ql3.sqlite",
|
||||
"manifestPath": "/opt/qinglong3/artifacts/qinglong3-adoption.json",
|
||||
"activationPath": "/opt/qinglong3/artifacts/qinglong3-activation.json",
|
||||
"expectedManifestDigest": "REPLACE_WITH_VERIFY_MANIFEST_DIGEST"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
chmod 0600 /secure/operator/ql3-sqlite-activation.json
|
||||
ql3-adoption run --command-file /secure/operator/ql3-sqlite-activation.json
|
||||
```
|
||||
|
||||
activation 分别记录 `sourceSha256`、`recoverySha256` 和 `targetSha256`。SQLite Online Backup 的 recovery 与 source 可以逻辑等价
|
||||
但物理字节不同,因此不能比较两者哈希来判断 clean rollback。记录返回的 `activationDigest`,并把 exact activation path/digest
|
||||
交给 adopted application 和后续 cutover 命令。
|
||||
|
||||
## 6. Cutover 与回退判定
|
||||
|
||||
完成 activation 后,继续执行 [Edge/Standalone 部署准备](./ql3-local-deployment.md) 中的 legacy silence、target start/stop 和双阶段
|
||||
rollback ceremony。不要仅凭 activation 启动两个 writer。
|
||||
|
||||
target stop 后的数据分类为:
|
||||
|
||||
- `rollback_candidate`:target/source 都保持 activation 时字节且双方 sidecar clear;
|
||||
- `reconciliation_required`:target 已接受写入或存在 target sidecar;保留三份数据库,禁止自动启动 2.x;
|
||||
- `manual_review`:source 漂移、activation 或稳定文件身份无法证明;禁止猜测。
|
||||
|
||||
证据字段 `sourceMatchesActivation` 表示 source 与 activation 时的原 source 哈希相同,不表示 source 与 Online Backup recovery 文件
|
||||
物理相同。`rollback_candidate` 也不是启动授权,仍须走双阶段 Legacy rollback。
|
||||
|
||||
## 7. 当前边界
|
||||
|
||||
本流程不迁移完整 2.x data directory,不做 target 写后的自动逆迁移,不连接 Cluster 控制面,也没有云端恢复服务。任何
|
||||
`reconciliation_required` 必须保留现场并等待后续显式数据域工具;不要把 target 覆盖回 source。
|
||||
Reference in New Issue
Block a user