15 KiB
构建版本与数据库支持矩阵
核查日期: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 |
核查命令:
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 连接恢复及基本 SQL 备份恢复 | 原有 55 项迁移和连接恢复;7bfd400 新增 10 项基本恢复、会话、取消及同进程正式命令失败回滚测试 |
一致性快照、对象完整性、官方工具与独立发行命令、Linux 实库、Web 初始化和目标生产系统验证 |
| MySQL 8.0.45 | 正式生产支持目标 | 同上 | 同候选独立实库验证原有及新增场景,不复用 5.7 的结果 | 同上;不代表 8.0 全部补丁版本已经验证 |
| PostgreSQL | 正式生产支持目标,实际服务端版本待本轮复核 | 独立方言、迁移 1~9、严格 TLS 和官方备份恢复工具接入 | 文件/嵌入/登记一致性、凭据/TLS 单元测试 | 当前版本真实集群、初始化、升级、失败回滚、备份恢复和业务回归 |
正式支持目标不等于已经生产放行。旧文档中的 PostgreSQL 实机记录仅作为线索,不替代当前候选版本复测。本批 MySQL 测试自行初始化 loopback 独立实例,不连接本机已有服务或生产数据库;PostgreSQL 当前候选实库测试未执行。
三、迁移与降级边界
- 三种数据库必须提供相同编号和名称的迁移,SQL 内容允许因方言不同而不同。
migration_catalog_test.go检查源码目录、嵌入资源和latestMigrationVersion;新增文件忘记登记或嵌入时必须失败。Migrate在执行后续迁移前读取完整有序版本历史;版本高于程序支持范围或历史不连续时拒绝启动,不自动删除或修补版本记录。- MySQL 的 DDL 重入和 PostgreSQL 的事务回滚必须用对应引擎验证,不能通过文件数量一致推断行为一致。
- 当前不存在通用向下迁移承诺。降级须使用兼容程序及对应已验证备份,在隔离环境验证后再操作,禁止通过删除
schema_migrations绕过拒绝。
四、真实实例验收步骤
每个数据库和声明支持的服务端版本独立执行以下步骤,保存版本、候选提交、命令退出码和脱敏证据:
- 建立明确归属的隔离空库和最小权限账户,验证 TLS 与主机身份;不使用现有业务库。
- 按正式初始化入口完成配置;创建用户、域名、DNS 账户、服务器和任务,验证权限隔离。
- 从支持的旧版本数据库升级,检查数据、索引、默认值、归属和任务状态;重复执行不产生额外变更。
- 注入迁移中断,在恢复后确认重入/回滚;新版数据库被旧程序拒绝且原数据保持不变。
- 按该数据库的 CLI 备份恢复流程在另一隔离空库恢复;验证敏感配置和证书关联,篡改备份必须拒绝。
- 重启服务验证持久化,完成前后端业务回归;记录未执行、跳过和失败项,不汇总为通过。
MySQL/PostgreSQL 没有当前实机证据的格子保持待验收。本矩阵不授权清理共享数据库或同机其他服务。
五、MySQL 隔离迁移正式回归
测试入口为 backend/internal/database/mysql_integration_test.go;同目录的 mysql_integration_helpers_test.go 适配共享夹具 backend/internal/testsupport/mysqltest/server.go,供数据库和 CLI 正式 Go 测试复用,不需要辅助脚本,也不进入生产程序依赖。未显式提供程序目录时显示跳过,不得把常规 go test ./... 的结果当作实库通过。
本批 Windows 实际命令如下,两个版本分别执行;产物根可复用,但测试每次创建全新数据目录,不复用业务库:
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
安全和覆盖边界:
- 只接受绝对程序及产物目录,不接受外部 DSN;使用
--no-defaults,不会读取既有实例配置。数据库管理命令只作用于本次创建的随机端口与数据目录。 - 初始化不开放监听;首次启动在接收连接前设置随机密码。运行时仅绑定 loopback,强制 TLS,验证 CA 和 IP 身份;8.0 的额外 X 协议关闭。
- 迁移使用库级业务账户,不用管理账户替代最低权限检查;测试保留管理账户仅用于创建隔离库和正常关闭自己的进程。
- 每个历史起点及每个 DDL 中间状态升级后,比较表引擎、字段类型、默认值、字符集及全部索引。此比较证明升级结构与全新迁移一致,不单独证明业务设计本身完全正确。
- 冷重启用例关闭应用连接池、停止数据库、重启后重新打开连接。保留旧池的独立在线恢复测试见第六节,不能用冷重启结果代替。
- 测试正常结束会停止自己的进程,清空初始口令文件,保留日志和数据目录;产物已被 Git 忽略。非正常终止后应先核对具体进程归属,禁止批量停止所有 MySQL。
- 本批不是发布包部署、Web 初始化、备份恢复、Windows Service 或 Linux 运行验收;PostgreSQL 和 SQLite 剩余矩阵不得据此标记通过。
六、MySQL 在线连接池恢复
正式入口:backend/internal/database/mysql_recovery_integration_test.go;复用第五节隔离夹具。两个版本分别设置程序目录后运行:
go test -count=1 -v -timeout=8m -run '^TestMySQLReal(Migrations|PoolRecovery)$' ./internal/database
实现和行为边界:
- 锁定的 MySQL 驱动在 Windows 上没有有效的空闲套接字检查。复用连接之前通过驱动的
SessionResetter增加一次有界COM_PING;Linux 保留驱动原有检查,不增加这次往返。 - 单次探测最多 2 秒;调用者更短的截止时间或取消优先。探测失败关闭连接并返回
driver.ErrBadConn,让连接池在发送业务语句之前更换连接。 - 完整保留驱动的查询、写入、预编译、事务、参数转换和连接校验接口。不包装业务执行及提交错误,不新增 SQL 或事务重放逻辑。
checkConnLiveness默认开启;显式关闭时不启用上述额外检查,不保证失效空闲连接上的首次请求成功。连接仍可能在探测成功后断开,应用必须处理执行错误及提交结果不确定性。- 成本是 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 实库恢复;其门禁仍然保留。
七、MySQL 基本备份恢复与指定失败回滚
候选 7bfd400;正式入口为 backend/internal/cli/mysql_integration_test.go 和 mysql_commands_integration_test.go,复用严格 TLS、随机账户、全新实例的共享夹具。
修复前在 5.7.44 的真实数据库上复现两类错误:禁用空闲连接后,会话变量跨 SQL 语句丢失;DECIMAL 文本字节被作为十六进制数值恢复,出现数值越界。修复固定恢复连接,并依据字段类型导出精确文本;旧 DECIMAL 备份没有自动转换,应重新生成并验证备份。
新增测试覆盖:
MaxIdleConns=0时,记录并比较同一恢复脚本中的真实连接编号。- 两种空闲连接配置下,恢复子表在前、父表在后的关联数据,核对中文、特殊字符、二进制、DECIMAL、NULL、微秒时间和自增;恢复后外键仍生效。
- 无效 SQL 前的写入保留,失败后的写入不执行;提前取消不修改当前数据库。底层导入函数不承诺事务原子性,整库回滚由正式恢复命令负责。
- 同进程调用正式备份和恢复命令,先执行完整 MySQL 迁移,再验证成功恢复、SQL 导入失败后的回滚、证书恢复失败后的回滚;检查业务行、审计行、配置文件、加密凭据、证书文件和恢复前快照。
重跑原有 55 项及新增 10 项的命令如下。两个版本分别设置程序目录,产物根每次生成独立数据目录:
Set-Location D:\Desktop\Scert\backend
$env:SCERT_MYSQL_TEST_ROOT = 'D:\Desktop\Scert\artifacts\mysql-restore-session-20260927'
$env:SCERT_MYSQL_TEST_BIN = 'E:\DB\5.7\bin'
go test -json -p 1 -count=1 -timeout=8m -run '^TestMySQLReal' ./internal/database ./internal/cli
$env:SCERT_MYSQL_TEST_BIN = 'E:\DB\8.0\bin'
go test -json -p 1 -count=1 -timeout=8m -run '^TestMySQLReal' ./internal/database ./internal/cli
JSON 日志保存为 artifacts/mysql-restore-session-20260927/mysql57-7bfd400.jsonl、mysql80-7bfd400.jsonl,不纳入源码。
候选最终复测结果如下,均为 0 失败、0 跳过;子测试计数包含两种连接池场景及其嵌套用例:
| 实际版本 | 数据库包 | CLI 包 | 通过子测试 |
|---|---|---|---|
| MySQL 5.7.44 | 43.949 秒 | 11.350 秒 | 65 |
| MySQL 8.0.45 | 51.125 秒 | 16.803 秒 | 65 |
最终 8 个隔离测试实例均已退出,对应端口无监听;原有 MySQL 进程保持不变,全部初始化口令文件为空。保留目录中的测试数据、随机测试密钥和日志仅作为本地忽略产物,不提交或分发。
本批边界与剩余门禁:
- TLS 注册名只存在于测试进程,正式命令测试是同进程调用,不是独立发行二进制验收。Linux CLI 测试包仅交叉编译,未在 Linux 运行。
- 导出尚无跨表统一一致性快照;并发写入和 DDL 下的一致性不能据此宣称通过。
- 视图、触发器、生成列、更多 SQL 模式与对象清单完整性仍须验证,不能把已测试表类型扩展为任意 MySQL 对象支持。
- 当前仍使用自有 SQL 导出;官方工具互操作、独立 CLI、完整生产业务及服务重启验收必须补齐。PostgreSQL、SQLite 和其他 44 项整改不因本批局部通过而缩减。