Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

73 строки
8.7 KiB

  1. <!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>database-review · Code Review</title><style>*{box-sizing:border-box}body{margin:0;background:#edf2f7;color:#203248;font:16px/1.75 "Microsoft YaHei","Segoe UI",sans-serif}header{background:#0c2b47;color:white;padding:22px max(24px,calc((100vw - 1160px)/2))}header a{color:#c1e6ff;margin-right:24px}main{max-width:1200px;margin:24px auto 60px;padding:36px;background:white;border-radius:12px;box-shadow:0 6px 24px #1028400c}h1{font-size:30px;line-height:1.4;margin-top:0}h2{font-size:22px;margin:36px 0 14px;border-bottom:2px solid #dbe8f2;padding-bottom:8px}h3{font-size:18px}p{margin:13px 0}a{color:#126fba;text-decoration:none}a:hover{text-decoration:underline}table{border-collapse:collapse;width:100%;margin:18px 0;font-size:14px;table-layout:auto}th,td{padding:11px 13px;border:1px solid #dce5ed;text-align:left;vertical-align:top;overflow-wrap:anywhere}th{background:#edf5fc}tr:nth-child(even){background:#f9fbfd}code{font:13px/1.5 Consolas,monospace;background:#edf2f7;padding:2px 5px;border-radius:4px;overflow-wrap:anywhere}pre{padding:18px;overflow:auto;background:#edf2f7;border-radius:8px}pre code{padding:0}img{max-width:100%;height:auto}details{padding:12px;background:#f7f9fc;margin:12px 0}.gallery{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}figure{margin:0;border:1px solid #dce5ed;border-radius:8px;overflow:hidden;background:#f8fafc}figure img{display:block;width:100%;height:300px;object-fit:contain;background:#e8eef3}figcaption{padding:12px;font-size:14px;color:#37526b}footer{color:#657c91;font-size:13px;margin-top:36px}li{margin:8px 0}@media(max-width:760px){main{margin:0;padding:20px;border-radius:0}.gallery{grid-template-columns:1fr}table{display:block;overflow:auto}h1{font-size:25px}header{padding:16px}}@media print{body{background:white}main{margin:0;box-shadow:none;max-width:none}header{display:none}figure{break-inside:avoid}h2{break-after:avoid}}</style></head><body><header><a href="index.html">审查总报告</a><a href="live/html/index.html">真实 E2E</a><a href="frontend-e2e/html/index.html">模拟接口回归</a></header><main><h1 id="数据库迁移与清理独立复核">数据库迁移与清理独立复核</h1>
  2. <p>复核日期:2026-09-05。本附录只读取迁移文件、全量 DDL、<code>tools/review-db.py</code> 和执行 JSON,并做静态比较;没有再次连接数据库、执行迁移或修改业务数据。实际执行证据来自主审查生成的 <a href="database-migration.json">database-migration.json</a> 和 <a href="cleanup.json">cleanup.json</a>。</p>
  3. <h2 id="结论与原始缺陷">结论与原始缺陷</h2>
  4. <p>原 034 为运行、运行成员和事件建立独立唯一索引,再以组合外键引用。主执行者在目标 KingbaseES <code>V008R006C009B0014</code> 的隔离 schema 验证发现,该版本要求外键目标为显式 <code>UNIQUE</code> 约束,仅有独立唯一索引时创建步骤表失败,报外键没有匹配唯一约束(SQLSTATE <code>42830</code>)。这会阻断新步骤事实表部署。</p>
  5. <p>修复新增 <code>20260905_035_teaching_step_run_kingbase_constraints.sql</code>:在 005 基础结构和 033 后执行,以 035 替代 034;历史 034 文件保持原样。035 使用系统目录判断并创建三个 <code>_aggregate_fk</code> 显式唯一约束,再幂等建立步骤表和查询索引。它不包含业务行更新、删除或历史事实回填。</p>
  6. <p>部署文档已同步为当前开发库执行 033、035;其他环境必须独立核对迁移状态。035 含 <code>DO $$...$$</code>,执行客户端必须正确识别 dollar quote,不能简单按分号切分。</p>
  7. <h2 id="035-与全量-ddl-一致性">035 与全量 DDL 一致性</h2>
  8. <p>独立比较 <code>035</code> 与 <code>database/unreal_tran_full.sql</code> 的步骤表定义,除 <code>IF NOT EXISTS</code> 和空白格式外完全一致。</p>
  9. <table>
  10. <thead>
  11. <tr>
  12. <th>对照项</th>
  13. <th>结果</th>
  14. </tr>
  15. </thead>
  16. <tbody>
  17. <tr>
  18. <td>父表聚合 UNIQUE 约束</td>
  19. <td>3 个;名称与列顺序一致:运行 <code>(id, assignment_id)</code>、运行成员 <code>(id, run_id)</code>、事件 <code>(id, run_id, assignment_id)</code></td>
  20. </tr>
  21. <tr>
  22. <td>步骤表外键</td>
  23. <td>4 个:任务、运行归属、运行成员归属、事件归属;均为 <code>RESTRICT</code></td>
  24. </tr>
  25. <tr>
  26. <td>步骤活动唯一键</td>
  27. <td>2 个:<code>(run_id, step_code, delete_token)</code> 和 <code>(run_id, step_order, delete_token)</code></td>
  28. </tr>
  29. <tr>
  30. <td>CHECK 约束</td>
  31. <td>11 个,覆盖顺序、目标进度、状态、尝试/失败次数、证据来源、时间、回填标记、版本和软删除字段</td>
  32. </tr>
  33. <tr>
  34. <td>步骤查询索引</td>
  35. <td>3 个,按任务状态、运行当前步骤和最近事件查询</td>
  36. </tr>
  37. </tbody>
  38. </table>
  39. <p>父表新增组合唯一键都包含已有主键 <code>id</code>,不改变既有行的业务唯一性。步骤表字段和四个外键引用列一致,未发现本次修复会破坏既有业务行或放松运行归属校验的问题。</p>
  40. <h2 id="实际执行与恢复验证边界">实际执行与恢复验证边界</h2>
  41. <p><a href="database-migration.json">database-migration.json</a> 记录的目标为开发环境 <code>unreal_tran/public</code>,迁移前记录时间为 <code>2026-09-05T11:22:17.562488</code>。执行文件指纹与复核时工作区文件一致:</p>
  42. <table>
  43. <thead>
  44. <tr>
  45. <th>文件</th>
  46. <th>SHA-256</th>
  47. </tr>
  48. </thead>
  49. <tbody>
  50. <tr>
  51. <td><code>20260904_033_teaching_command_receipt.sql</code></td>
  52. <td><code>3b62137942c54d2fc50f6ee9975d20c44f8d2b240d8fff0c153970052e5b8d43</code></td>
  53. </tr>
  54. <tr>
  55. <td><code>20260905_035_teaching_step_run_kingbase_constraints.sql</code></td>
  56. <td><code>53d0baae9b90e37172277dd5e346542cce3d95b02595dc94e742c4ecaa8e3c31</code></td>
  57. </tr>
  58. </tbody>
  59. </table>
  60. <p>执行工具先读取本地开发配置并核对数据库/schema,再执行以下路径:</p>
  61. <ol>
  62. <li>在专用隔离 schema 建立最小父表,首次完整执行 033、035,再完整重跑。</li>
  63. <li>在另一专用隔离 schema 模拟“033 回执表已提交、035 首个父表唯一约束已提交”的中断状态,再完整执行和重跑。</li>
  64. <li>隔离检查成功后,切回 <code>public</code> 执行 033、035。</li>
  65. </ol>
  66. <p>JSON 中上述各路径的无效记录和孤儿记录检查均为 0。当前执行工具也会在迁移后检查出现非零结果时抛错,避免继续报告成功。隔离验证证明的是这两个增量在最小父表上的首次、重复和指定中断点恢复;它不是全量建库脚本、任意中断点或历史数据回填的验收。</p>
  67. <p>此执行记录只证明所列开发环境已迁移,不表示其他开发实例、测试库或生产库已执行。</p>
  68. <h2 id="备份与测试数据清理">备份与测试数据清理</h2>
  69. <p>执行前的 <code>database-before.json</code> 位于工作区 <code>.codex-tmp/review-20260905/</code>,复核确认文件存在。它保存任务、运行、运行成员、事件四张相关表的既有数据以及列、索引元数据,是本次扩展式迁移的本地对照快照;不是整库物理备份,也未据此宣称完成整库恢复演练。报告不复制快照中的业务明细或连接凭据。</p>
  70. <p>清理工具按 <code>UTE2E-REVIEW-</code> 测试任务前缀选取记录,并排除迁移前快照已有任务 ID。删除在同一事务中按外键依赖顺序执行:先步骤事实、命令回执及运行附属测试数据,再事件、干预/故障关联、运行成员、运行、教学成员和任务。<code>ut_teaching_run.member_id</code> 引用的教学成员在运行删除之后处理。</p>
  71. <p>测试用户按本轮时间及测试标识筛选,临时管理员另按本地记录的精确 ID、用户名和非保护身份确认。清理撤销其会话,并软删除角色关系、凭证与用户,同时停用用户、递增令牌版本;并非物理删除所有审计记录。临时管理员明文凭据文件在清理后移除。</p>
  72. <p>复核读取的清理记录中,四张快照表既有行的 <code>originalRowsUnchanged</code> 均为 <code>true</code>,<code>remainingActiveTestUsers</code> 为 0。该比较只覆盖这四张表的快照既有行,不代表逐字比较了整库全部数据。重复截图测试后的最终清理时间、任务列表和数量以最新 <a href="cleanup.json">cleanup.json</a> 为准,本附录不固定清理数量。</p>
  73. <p>未发现当前执行记录反映出误删既有业务数据或约束损坏。复核提出的清理验收建议已落实:工具写出记录后,若任一既有行对照不一致或仍有活动测试用户,就以错误退出。主任务负责最终清理和主报告汇总。</p><footer>2026-09-05 · 开发环境审查 · 图片可点击查看原尺寸</footer></main></body></html>