docs: 记录已授权迁移的备份恢复阻塞与只读核验

This commit is contained in:
wangzhibiao committed 2026-10-14 13:02:37 +08:00
1 parent 5560a3ac04
commit b94ac7f05a
4 files changed
+122 -6

No files matched your search

+9 -5
View File
@@ -5,8 +5,9 @@
## 当前验收边界
Round 5V 已核对目标 Kingbase 版本、低权限账号及迁移前表结构。005 尚未执行:
`MIGRATION_WAITING_APPROVAL`。不能将 H2/替身测试、构建成功或登录页显示称为
Round 5V-2 用户已明确批准仅对目标QA库执行005增量迁移,但备份/隔离恢复前提
尚未满足,当前状态为 `MIGRATION_AUTHORIZED_BLOCKED_RESTORE`,005未执行。
不能将 H2/替身测试、构建成功或登录页显示称为
Kingbase 事务/浏览器业务闭环验收。真实硬件验收始终未进行。
迁移前置、失败回滚和核验清单见 [迁移计划](docs/iot/ROUND5V_KINGBASE_MIGRATION_PLAN.md)。
**不要执行 qa-bootstrap 全量初始化、清空测试数据、重建库、重置已有账号或序列。**
@@ -65,7 +66,10 @@ python3 scripts/qa/qa.py verify-snapshot --snapshot-dir .qa-runtime/snapshot-REP
检查使用只读 repeatable-read 事务并 rollback,记录版本、schema、列、索引和计数;
不打印业务行。快照含两张受影响表的敏感内容,仅存 `.qa-runtime/`(目录0700,
数据0600);其 XML 解析和 SHA 验证不等同于原生全库备份或数据库恢复演练。
本机未找到原生备份客户端,完整备份及回退演练由管理员按迁移计划准备。
在本轮已检查范围中未找到匹配的原生备份客户端,本机Docker守护进程不可用,
也未发现或取得可用的独立恢复实例。仅有两表快照不能通过恢复门禁。
需要提供已有且获准使用的恢复环境、匹配版本工具和受保护的QA库DDL管理配置;
不要创建数据库、猜测密码、提权或把业务账号当成迁移账号。
## 3. 启停隔离 QA(迁移批准并完成后)
@@ -114,6 +118,6 @@ stop只处理本脚本账本中且进程命令身份仍匹配的PID;不会清
`.gitlab-ci.yml` 已改为显式web+RUN_FUSION_VALIDATION=true才允许的验证流水线;
Java21、私有JDBC预检及npm ci,**无部署job**。本轮未Push,也未触发/验证远程Runner。
当前仍缺明确005迁移授权、原生备份/回退演练、真实Kingbase生命周期验证和
依托新QA后端的完整Chrome验收。后端未获准迁移时,单独前端会明确返回502,
005授权已明确;当前仍缺可用的原生备份/隔离恢复条件、已配置的授权DDL管理账号、真实Kingbase生命周期验证和
依托新QA后端的完整Chrome验收。迁移安全前提未满足时,单独前端会明确返回502,
不得用旧实验后端或伪造API响应冒充新版本验收。
+93
View File
@@ -0,0 +1,93 @@
# Round 5V-2 — authorization received, restore prerequisite blocked
Date: 2026-10-14. Branch `fix/iot-safety-hardening`; starting commit
`5560a3ac0456b694609cdf9f21f7f59810950d76`. The user explicitly approved the
non-destructive migration on the named QA database, but not bypassing backup or
restore proof, database creation/deletion, privilege expansion or hardware control.
## Fresh actual database evidence
Read-only JDBC inspection connected only to
`192.168.139.218:4321/railwaysystem_fusion_qa_20261013`, using `fusion_qa_app`.
The server returned `KingbaseES V009R003C018`, database name exact, current schema
`public`, internal server endpoint `172.17.0.5:54321`. `transaction_read_only=on`,
repeatable-read transaction ended in rollback. No DDL/DML was issued.
- Base tables: public54, iotlocks9. Counts: train_student47, train_enrollment57,
train_accommodation34, lock_auth10, lock_command15. No personal rows were printed.
- Round 5S lifecycle metadata is absent. Existing schema/index definitions remain
in their pre-migration state. Historical LEGACY defaults cannot be claimed applied.
- App role is not superuser/createdb/createrole; no CREATE on either application
schema, affected tables owned by kingbase. Existing DML grants were inspected,
not exercised. Extra TRUNCATE/TRIGGER/REFERENCES on public.sys_menu,
public.sys_notice_read, public.sys_role_menu remain unchanged pending admin review.
- An initial read-only table-inventory query through information_schema.tables
returned SQLSTATE42501. The probe now reuses the already-readable pg_tables
catalog view and completes successfully without extra grants.
Evidence: `scripts/qa/QaDatabaseProbe.java` and private
`.qa-runtime/round5v2-preflight.log` (metadata/counts only).
## Migration scope PASS; runtime DDL semantics BLOCKED
Full 005 content was reviewed and independently allowlisted: 20 statements,
16 ADD COLUMNs and 4 CREATE INDEXes (2 unique), all limited to the two approved
`iotlocks` tables. No DROP/TRUNCATE/DELETE/UPDATE/GRANT or sequence reset.
SHA256: `90648b6ac67470f9a14f0795c4479dfb4811d4907e41a13ee5eeada16582b87f`.
The file was not changed. Additive scope is verified, but actual Kingbase DDL
transaction rollback, null-key uniqueness, repeated execution and lock behavior
have NOT been tested because the prerequisite restore gate is blocked.
## Concrete backup/restore blockers
1. No sys_dump/sys_restore/ksql/pg_dump/pg_restore on local PATH or in the scoped
common install/download locations checked. A PostgreSQL client was not installed
or substituted as evidence of Kingbase compatibility.
2. Docker CLI and Docker.app exist, but the configured desktop-linux daemon socket
does not exist; docker info fails. No usable local Kingbase restore instance
was discovered or supplied. No Docker startup, install, database creation,
network modification or engine initialization was performed.
3. Existing SSH alias wzbmatebook is reachable, but no vendor tools were found on
PATH or in the bounded /opt, /usr/local, /usr/lib, /home/wzb search; no matching
database/container process was reported. This is only a scoped resource check,
not a claim that no vendor installation exists anywhere.
4. Existing SSH authentication to database host 192.168.139.218 as configured user
wzb was denied. No password guessing, root fallback, new host-key acceptance,
remote installation or server changes were attempted.
5. Protected local QA configuration is 0600 and contains the usable app credential.
No explicit QA DDL-management connection or isolated restore connection was
found among its keys. Web-admin login keys are NOT treated as database-admin
credentials. The application role was not elevated or used to attempt DDL.
BACKUP_CREATED = BLOCKED: no new native consistent backup.
ISOLATED_RESTORE_VERIFIED = BLOCKED: no actual isolated database restore.
Previous private XML snapshots remain protected but do not satisfy either result.
Therefore formal migration and all dependent phases stop, as explicitly required.
## Work completed without migration
- Frontend production build rerun successfully from this archive, using its own
declared dependencies/lockfile and Quill transpilation configuration. Evidence:
`.qa-runtime/round5v2-frontend-build.log`. No Antigravity temporary path was used.
- 11 QA-tool tests rerun successfully. The modified Java probe actually compiled
and ran on Java21 against Kingbase in read-only mode. No critical backend source
changed; prior 85 JUnit results are historical evidence, not a new Kingbase run.
- Runbook and migration plan now acknowledge authorization and identify restore
prerequisites, rather than incorrectly saying user approval is still missing.
- New Spring Boot/Redis/Chrome was not started; no old experiment backend or fake
API substituted. Full login/routes, original homepage/charts, nine IoT pages and
accommodation software E2E remain BLOCKED, not PASS.
- Safety defaults remain MQTT Mock, real writes false, whitelist empty, face HTTP
disabled, OpenAPI/QA control interfaces disabled. No real device operation occurred.
## Required inputs to unblock this same workflow
Provide a matching licensed Kingbase native tool location, an **already existing
and approved** independent restore instance/database with protected connection
configuration, and the existing authorized DDL-management connection for this QA
database. Do not send passwords in chat. No new database or expanded app privilege
is requested or inferred. Once those inputs exist, prove restore first, then follow
the migration plan and run actual Kingbase transactions, startup and Chrome E2E.
SOFTWARE_QA_READY = BLOCKED.
READY_FOR_SUPERVISED_HARDWARE_TEST = BLOCKED.
+13 -1
View File
@@ -1,5 +1,17 @@
# Round 5V — isolated Kingbase migration and rollback gate
## Current Round 5V-2 decision
The user explicitly authorized migration 005 **only** on
`railwaysystem_fusion_qa_20261013`, together with protected backup and isolated
restore rehearsal. Scope SHA256 remains
`90648b6ac67470f9a14f0795c4479dfb4811d4907e41a13ee5eeada16582b87f`.
Authorization is no longer missing. Status: `MIGRATION_AUTHORIZED_BLOCKED_RESTORE`.
No DDL or business data writes have been performed because native backup and
actual isolated restore cannot yet be proved. Existing two-table XML snapshots
are not an acceptable substitute. Do not create a database or elevate privileges
to overcome this gate. See [current evidence](ROUND5V2_ACCEPTANCE.md).
## Scope and observed prestate
2026-10-14 read-only JDBC probe: database `railwaysystem_fusion_qa_20261013`, user
@@ -51,7 +63,7 @@ the global/database/user search path or accidentally query system `sys_user` vie
native backup utility or restore destination is assumed or provisioned here.
Do not use a mismatched PostgreSQL client or restore into any shared database.
## Execution and failure rollback (not executed in this round without approval)
## Execution and failure rollback (authorized, blocked on backup/restore)
With an approved migration account, enforce `current_database()` equals the exact
target before any change. Begin a transaction, set a local lock timeout (5s),
+7
View File
@@ -40,8 +40,15 @@ public class QaDatabaseProbe {
r.next(); if (!DATABASE.equals(r.getString(1))) throw new SecurityException("Database mismatch");
}
query(c,"identity", "SELECT current_database(), current_user, current_schema(), version()");
query(c,"server_endpoint", "SELECT inet_server_addr(),inet_server_port(),current_database(),current_user");
query(c,"read_only_transaction", "SHOW transaction_read_only");
query(c,"search_path", "SHOW search_path");
query(c,"schemas", "SELECT schema_name FROM information_schema.schemata ORDER BY schema_name");
// Kingbase information_schema.tables can require extra catalog privileges;
// reuse the readable pg_tables view rather than broadening the app role.
query(c,"table_inventory", "SELECT schemaname,count(*) FROM pg_tables WHERE schemaname IN ('public','iotlocks') GROUP BY schemaname ORDER BY schemaname");
query(c,"training_counts", "SELECT 'train_student',count(*) FROM public.train_student UNION ALL SELECT 'train_enrollment',count(*) FROM public.train_enrollment UNION ALL SELECT 'train_accommodation',count(*) FROM public.train_accommodation");
query(c,"round5s_prestate", "SELECT count(*) FROM information_schema.columns WHERE table_schema='iotlocks' AND table_name IN ('lock_auth','lock_command') AND column_name IN ('execution_mode','environment_id','intent_key','intent_version','execution_state','intent_action','intent_at','attempt_started_at')");
query(c,"columns", "SELECT table_schema,table_name,column_name,data_type,is_nullable,column_default "
+ "FROM information_schema.columns WHERE (table_schema='iotlocks' AND table_name IN ('lock_auth','lock_command')) ORDER BY table_name,ordinal_position");
query(c,"constraints", "SELECT table_schema,table_name,constraint_name,constraint_type FROM information_schema.table_constraints "