Scert/doc/构建版本与数据库支持矩阵.md

133 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 构建版本与数据库支持矩阵
核查日期:2026 年 9 月 27 日。本文区分代码支持、隔离测试和正式生产准入,不把驱动存在视为兼容性验收。
## 一、工具链与依赖
| 项目 | 当前固定来源 | 当前核查值 | 发布要求 |
|---|---|---|---|
| Go | `backend/go.mod`、`backend/go.sum` | 模块内 `go1.26.6 windows/amd64` | 在模块内记录实际版本,不使用仓库根目录的版本推断 |
| 工具链选择 | `go env GOTOOLCHAIN` | `auto` | 自动选择仍必须与模块要求一致,不得降低版本绕过失败 |
| Node.js | `frontend/package.json` 的 `engines`、`devEngines`,锁文件 | `v24.19.0` | 精确匹配,升级需同步声明并重跑测试和构建 |
| npm | 同上,另有 `packageManager` | `11.17.0` | 精确匹配,使用锁文件安装;Windows 使用 `npm.cmd` |
| Vue | `frontend/package.json`、`frontend/package-lock.json` | `3.5.41` | 直接依赖固定精确版本,声明及锁文件必须一致 |
| Vite | 同上 | `6.4.3` | 同上 |
| Vue 构建插件 | 同上 | `5.2.4` | 同上 |
| SQLite Go 驱动 | `backend/go.mod` | `modernc.org/sqlite v1.37.0` | 驱动版本不等于数据库引擎版本 |
| MySQL Go 驱动 | 同上 | `github.com/go-sql-driver/mysql v1.9.3` | 不代表 MySQL 所有服务端版本均通过验收 |
| PostgreSQL Go 驱动 | 同上 | `github.com/jackc/pgx/v5 v5.9.2` | 同上 |
| 编译目标 | `build/build-release.ps1` | `windows/amd64`、`linux/amd64` | 核心二进制 `CGO_ENABLED=0`、`-trimpath` |
核查命令:
```powershell
cd backend
go version
go env GOVERSION GOTOOLCHAIN GOOS GOARCH
go mod verify
go test -p 1 -count=1 -timeout=3m ./...
go vet -p=1 ./...
cd ../frontend
node --version
npm.cmd --version
npm.cmd ci
npm.cmd test
npm.cmd run build
```
历史基线只验证过现有依赖;随后 P0-03 已在 `fab98d1` 独立克隆重新执行 `npm ci`、150 项前端测试和双平台候选构建。该次安装仍有脚本批准策略警告,不能证明安装脚本被禁止。P0-04 改为明确禁用依赖安装脚本,执行证据持续记录在《Scert整改任务执行清单.md》,不能将旧安装结果当作新策略验证。
### 构建机与安装策略
| 项目 | 固定基线或约束 | 验收边界 |
|---|---|---|
| 当前 Windows 构建机 | Windows 11 Home China,系统 `10.0.26200`,amd64;Windows PowerShell 5.1 | 记录实际值,不把系统显示名称误写成内核版本;系统更新后需重新验收 |
| Linux 原生构建机 | 脚本允许 Linux amd64,但尚无本批指定发行版、内核、PowerShell 版本的原生构建证据 | 不宣称 Linux 原生可重复构建已通过;Linux 候选包由 Windows 交叉编译 |
| 目标平台 | `windows/amd64`、`linux/amd64`,`CGO_ENABLED=0`、`-trimpath`、`-mod=readonly` | 构建机版本与生产运行系统分别记录 |
| 安装脚本 | `.npmrc` 固定 `ignore-scripts=true`,正式入口再显式传参 | npm 未审查警告不是安全保证,禁止白名单和全量放行 |
| 可选平台包 | `npm ci` 显式包含开发和可选依赖 | esbuild 不执行安装脚本,使用锁文件中的平台包;外部二进制覆盖被拒绝 |
| 发布追溯 | `manifest.json` 的 `build_environment` | 包含实际工具链、系统、直接前端依赖、安装策略和五份输入文件 SHA256;Go 驱动及依赖由模块文件哈希追溯 |
| 源码换行 | `.gitattributes` 固定文本 LF,二进制自动识别并保留 | 覆盖用户 `core.autocrlf` 差异;原目录不强制重写,正式验证使用干净克隆 |
正式发布入口自动校验工具链、核验 Go 模块缓存、按锁文件干净安装,并在构建结束后复核输入文件。环境不符时尽早失败;构建中版本文件漂移则不生成发布清单。`toolchain.mjs` 和配套测试属于正式构建代码,不作为替代真实部署的辅助验收脚本。具体流程见 `build/README.md`。
## 二、数据库支持矩阵
| 数据库 | 预期定位 | 代码现状 | 本轮验证 | 尚未满足的正式验收 |
|---|---|---|---|---|
| SQLite | 单机、开发、轻量部署 | 驱动、初始化、迁移 1~9、CLI 备份恢复 | 临时独立库从版本 0~9 升级、重复迁移、非法历史和新版数据库拒绝 | 并发读写/锁、服务重启、完整业务数据升级恢复 |
| MySQL 5.7.44 | 历史兼容目标,仍保留实现 | 独立方言、迁移 1~9、DDL 重入、文件头 BOM 处理及 Windows 空闲连接恢复 | `9cf3a3b`:55 项 Windows 隔离实库子测试通过,包括原有 48 项迁移及安全场景、7 项连接恢复与事务场景 | Linux 同候选恢复实测、CLI 备份恢复、Web 初始化和完整业务回归、目标生产系统验证 |
| MySQL 8.0.45 | 正式生产支持目标 | 同上 | 同候选独立实库 55 项通过,不复用 5.7 的结果 | 同上;不代表 8.0 全部补丁版本已经验证 |
| PostgreSQL | 正式生产支持目标,实际服务端版本待本轮复核 | 独立方言、迁移 1~9、严格 TLS 和官方备份恢复工具接入 | 文件/嵌入/登记一致性、凭据/TLS 单元测试 | 当前版本真实集群、初始化、升级、失败回滚、备份恢复和业务回归 |
正式支持目标不等于已经生产放行。旧文档中的 PostgreSQL 实机记录仅作为线索,不替代当前候选版本复测。本批 MySQL 测试自行初始化 loopback 独立实例,不连接本机已有服务或生产数据库;PostgreSQL 当前候选实库测试未执行。
## 三、迁移与降级边界
1. 三种数据库必须提供相同编号和名称的迁移,SQL 内容允许因方言不同而不同。
2. `migration_catalog_test.go` 检查源码目录、嵌入资源和 `latestMigrationVersion`;新增文件忘记登记或嵌入时必须失败。
3. `Migrate` 在执行后续迁移前读取完整有序版本历史;版本高于程序支持范围或历史不连续时拒绝启动,不自动删除或修补版本记录。
4. MySQL 的 DDL 重入和 PostgreSQL 的事务回滚必须用对应引擎验证,不能通过文件数量一致推断行为一致。
5. 当前不存在通用向下迁移承诺。降级须使用兼容程序及对应已验证备份,在隔离环境验证后再操作,禁止通过删除 `schema_migrations` 绕过拒绝。
## 四、真实实例验收步骤
每个数据库和声明支持的服务端版本独立执行以下步骤,保存版本、候选提交、命令退出码和脱敏证据:
1. 建立明确归属的隔离空库和最小权限账户,验证 TLS 与主机身份;不使用现有业务库。
2. 按正式初始化入口完成配置;创建用户、域名、DNS 账户、服务器和任务,验证权限隔离。
3. 从支持的旧版本数据库升级,检查数据、索引、默认值、归属和任务状态;重复执行不产生额外变更。
4. 注入迁移中断,在恢复后确认重入/回滚;新版数据库被旧程序拒绝且原数据保持不变。
5. 按该数据库的 CLI 备份恢复流程在另一隔离空库恢复;验证敏感配置和证书关联,篡改备份必须拒绝。
6. 重启服务验证持久化,完成前后端业务回归;记录未执行、跳过和失败项,不汇总为通过。
MySQL/PostgreSQL 没有当前实机证据的格子保持待验收。本矩阵不授权清理共享数据库或同机其他服务。
## 五、MySQL 隔离迁移正式回归
测试入口为 `backend/internal/database/mysql_integration_test.go`,实例生命周期由同目录的 `mysql_integration_helpers_test.go` 管理;属于正式 Go 测试,不需要辅助脚本。未显式提供程序目录时显示跳过,不得把常规 `go test ./...` 的结果当作实库通过。
本批 Windows 实际命令如下,两个版本分别执行;产物根可复用,但测试每次创建全新数据目录,不复用业务库:
```powershell
Set-Location D:\Desktop\Scert\backend
$env:SCERT_MYSQL_TEST_ROOT = 'D:\Desktop\Scert\artifacts\mysql-matrix-20260927'
$env:SCERT_MYSQL_TEST_BIN = 'E:\DB\5.7\bin'
go test -count=1 -v -timeout=8m -run '^TestMySQLRealMigrations$' ./internal/database
$env:SCERT_MYSQL_TEST_BIN = 'E:\DB\8.0\bin'
go test -count=1 -v -timeout=8m -run '^TestMySQLRealMigrations$' ./internal/database
```
安全和覆盖边界:
1. 只接受绝对程序及产物目录,不接受外部 DSN;使用 `--no-defaults`,不会读取既有实例配置。数据库管理命令只作用于本次创建的随机端口与数据目录。
2. 初始化不开放监听;首次启动在接收连接前设置随机密码。运行时仅绑定 loopback,强制 TLS,验证 CA 和 IP 身份;8.0 的额外 X 协议关闭。
3. 迁移使用库级业务账户,不用管理账户替代最低权限检查;测试保留管理账户仅用于创建隔离库和正常关闭自己的进程。
4. 每个历史起点及每个 DDL 中间状态升级后,比较表引擎、字段类型、默认值、字符集及全部索引。此比较证明升级结构与全新迁移一致,不单独证明业务设计本身完全正确。
5. 冷重启用例关闭应用连接池、停止数据库、重启后重新打开连接。保留旧池的独立在线恢复测试见第六节,不能用冷重启结果代替。
6. 测试正常结束会停止自己的进程,清空初始口令文件,保留日志和数据目录;产物已被 Git 忽略。非正常终止后应先核对具体进程归属,禁止批量停止所有 MySQL。
7. 本批不是发布包部署、Web 初始化、备份恢复、Windows Service 或 Linux 运行验收;PostgreSQL 和 SQLite 剩余矩阵不得据此标记通过。
## 六、MySQL 在线连接池恢复
正式入口:`backend/internal/database/mysql_recovery_integration_test.go`;复用第五节隔离夹具。两个版本分别设置程序目录后运行:
```powershell
go test -count=1 -v -timeout=8m -run '^TestMySQLReal(Migrations|PoolRecovery)$' ./internal/database
```
实现和行为边界:
1. 锁定的 MySQL 驱动在 Windows 上没有有效的空闲套接字检查。复用连接之前通过驱动的 `SessionResetter` 增加一次有界 `COM_PING`;Linux 保留驱动原有检查,不增加这次往返。
2. 单次探测最多 2 秒;调用者更短的截止时间或取消优先。探测失败关闭连接并返回 `driver.ErrBadConn`,让连接池在发送业务语句之前更换连接。
3. 完整保留驱动的查询、写入、预编译、事务、参数转换和连接校验接口。不包装业务执行及提交错误,不新增 SQL 或事务重放逻辑。
4. `checkConnLiveness` 默认开启;显式关闭时不启用上述额外检查,不保证失效空闲连接上的首次请求成功。连接仍可能在探测成功后断开,应用必须处理执行错误及提交结果不确定性。
5. 成本是 Windows 每次复用池连接时增加一次协议往返;同一已取得的事务连接内部不重复探测。当前没有远距离网络性能基准,不以 loopback 测试推断生产延迟。
新增 7 个实库场景每个使用单独业务库:保留旧池并重启数据库后的首次写入、空闲断线后的预编译语句、首次查询及迁移、无符号整数参数及正常提交、只读事务与正常回滚、活动事务连接中断、数据库不可用时有界失败并恢复。每次故障后的数据值均验证,避免把重复写入或未提交数据当作恢复成功。
`mysql_pool_test.go` 另行验证健康探测、驱动拒绝、探测失败、截止时间、取消、写入前更换连接,以及查询、写入和提交响应不确定时保留原错误且不重放。响应丢失场景是驱动接口层故障注入,不声称已完成真实网络丢弃提交确认包的演练。
候选 `9cf3a3b` 在 Windows 的 MySQL 5.7.44、8.0.45 均为 55 项子测试通过,0 失败、0 跳过。产物位于 `artifacts/mysql-matrix-20260927/mysql57-9cf3a3b.log` 和 `mysql80-9cf3a3b.log`,不纳入源码。Linux 数据库测试包交叉编译通过,但没有执行 Linux 实库恢复;其门禁仍然保留。