提交 351c0c10 authored 作者: 陈泽健's avatar 陈泽健

fix(performance): MySQL version 字段透传修复 + P2 待办全闭环验证记录

- performance_executor._build_target_resource_summary() result[mysql] 补透传
  version 字段(monitor 采样已含 SELECT 'version', VERSION(),汇总层遗漏)
- ReportPanel.vue 两处 (v${mysql.version}) 加 || '' 兜底,历史报告不再显示
  vundefined(Vue mustache 与 JS 模板串对 null 渲染行为差异)
- HANDOFF: P2 三项待办全闭环——①导出文件名 5.60 页面实测(Word/JSON=任务名
  + PDF=打印窗口 title,print() 阻塞渲染进程实测坑记录)②Word 导出结构解析
  (18 章节/10 表/8 图/MSO 兼容全通过)③快照表分页确认 a1ef3ffa 已修复无需改动
- 部署 5.60:后端 scp+重启 healthy,前端 dist 95 文件;历史报告显示(v)兜底,
  新执行报告带真实版本号(5.44 实测采集输出 version 8.0.28)
- 本地拆表套件 14 passed + 前端 build 通过
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
上级 75870a5e
...@@ -2,13 +2,77 @@ ...@@ -2,13 +2,77 @@
> **生成时间**: 2026-09-08 > **生成时间**: 2026-09-08
> **当前分支**: `platform-auto-test` > **当前分支**: `platform-auto-test`
> **最近提交**: `ea2a90cb` perf(performance): 大JSON列垂直拆表闭环 MySQL 1038 + 登录汇总透出(已推送 origin/platform-auto-test) > **最近提交**: 本会话 `P2 待办全闭环 + MySQL version 透传修复`(hash 回填见下方新节;前一提交 `4b8d773b` docs 回填 / `ef5bdd1d` scalar 修复,均已推送 origin/platform-auto-test)
> **会话窗口**: 性能测试 — 2026-09-08 P3 待办闭环:performance 大 JSON/TEXT 列垂直拆表(7 个从表 + 双写 + 读优先从表 + 启动回填 + 零回归)+ **部署 5.60 验证闭环** > **会话窗口**: 性能测试 — 2026-09-08 续2:P2 待办全闭环(导出文件名实测 / Word 结构解析 / 快照表分页确认)+ 顺手修复 MySQL vundefined 显示瑕疵 + 部署 5.60
> **状态**: ✅ 已提交推送 `ea2a90cb` + 已部署 5.60(12 张从表建成 + 存量回填 101 行 + 修复启动回填 ResourceClosedError,本地全量 437 passed) > **状态**: ✅ **P0/P1/P2 待办全部闭环**。导出三格式文件名页面实测通过;Word 导出结构 18 章节/10 表/8 图完整;快照表分页确认此前已修复无需改动;MySQL version 透传修复已部署(历史报告显示 `(v)` 兜底,新执行报告带真实版本号)。本地拆表套件 14 passed + 前端 build 通过
--- ---
## ⚡ 最新会话更新(2026-09-08 续)— 拆表部署 5.60 验证闭环 + 启动回填 ResourceClosedError 修复 ✅ ## ⚡ 最新会话更新(2026-09-08 续2)— P2 待办全闭环 + MySQL vundefined 修复 ✅
### A. P2-1 导出文件名页面实测 ✅(5.60 报告页,Chrome DevTools a.download 钩子捕获)
| 导出格式 | 实测文件名 / 标题 | 结论 |
|----------|------------------|------|
| Word | `混合场景100虚拟用户_c0b2cb.doc` | ✅ = 任务名(`sanitizeFilename` 清洗后),blob 下载 `a.download` 属性捕获验证 |
| JSON | `混合场景100虚拟用户_c0b2cb.json` | ✅ = 任务名 |
| PDF | 打印窗口 `document.title` = `混合场景100虚拟用户_c0b2cb` | ✅ 「另存为 PDF」默认文件名来源即窗口标题(`ReportPanel.vue` `exportPdfFromReport()``r.summary.taskName`) |
**实测坑**:PDF 导出触发 `window.print()` 后打印对话框会**阻塞该渲染进程所有页面的 JS 执行**(evaluate_script 120s 超时、Escape 无法解除)——验证 PDF 时应读取新窗口的 RootWebArea 标题(a11y 快照不依赖 JS),随后直接 `close_page` 关闭打印窗口恢复。
### B. P2-2 Word 导出结构解析 ✅(页面内 DOMParser 解析导出 HTML 3.27MB)
| 维度 | 结果 |
|------|------|
| 章节结构 | ✅ h1×1 + h2×18(执行摘要→核心指标→分位数→状态码→4 张趋势→执行机/目标机/Java/MySQL→接口统计→快照数据),与 `buildReportHtml()` 逐节对应 |
| 表格 | ✅ 10 张全结构正确(摘要 9×2 / 核心指标 metric-grid / 分位数 5×2 / 状态码 5×3 / 执行机 2×3 / 目标机 2×3 / Java 进程 8×7 / MySQL 3×4 / 接口统计 5×9 / 快照 51×5) |
| 图表 | ✅ 8 张全部 base64 PNG + `width="700"` |
| Word 兼容 | ✅ `xmlns:o`/`xmlns:w` 命名空间 + `[if gte mso]` 条件注释 + `@page A4 22mm/16mm` 页边距 |
| 快照表 | 51 行 = 表头 + 前 50 个采样点(`slice(0, 50)` 设计行为,报告共 1804 采样点) |
### C. P2-3 快照表最后 section 分页 ✅(确认无需改动——`a1ef3ffa` 已修复)
- 5.60 线上导出 HTML DOM 实测:`.section-break` **元素 0 个**、快照表 `div class="section"`(无 break);CSS 中残留的 `.section-break { page-break-before: always }` 定义为 AI 报告章节分页所用,无副作用;
- 该优化已在 `a1ef3ffa`(AI 分析文档格式优化)中随手上过:`<div class="section section-break">``<div class="section">`,注释「文档最后 section,不强制分页以免前页未满留白」;
- 长表分页策略符合最佳实践:`table { page-break-inside: auto }` + `tr { page-break-inside: avoid }`(行不拆分、表格自然跨页),50 行快照表**不应**`.keep-together`(整表超过一页高度时会产生更大空白)。
### D. 顺手修复:MySQL `vundefined` 显示瑕疵(本会话新发现)
**现象**:报告页与 Word 导出中 MySQL 监控标题显示 `MySQL umysql(vundefined)`(导出)/`(v)`(页面)。
**双层根因**
1. **后端**`target_resource_monitor.py` 采样**有** version(`_MYSQL_CMD` 首行 `SELECT 'version', VERSION()`,5.44 实测输出 `version\t8.0.28`),但 `performance_executor._build_target_resource_summary()` 构建 `result["mysql"]`**遗漏透传 version 字段** → 报告 API `mysql.version=None`
2. **前端**`ReportPanel.vue` JS 模板串 `(v${mysql.version})` 对 null/undefined 渲染字面量(Vue mustache `{{ }}` 对 null 渲染空串,故页面只是 `(v)` 不明显)。
**修复**(2 文件):
- `backend/app/executors/performance_executor.py``result["mysql"]``"version": mysql_latest.get("version")`
- `frontend/src/views/performance/ReportPanel.vue`(2 处):`(v${mysql.version || ''})` / `(v{{ ...mysql.version || '' }})` 兜底。
**验证**
- 5.44 目标机实测采集命令输出 `version 8.0.28`(采集端正常,佐证根因在汇总层);
- 后端部署后容器内 grep 命中 `3228: "version": mysql_latest.get("version")`
- 历史报告(version 已持久化为 None)页面与 Word 导出均显示 `(v)`,无 `vundefined`
- **注意**`target_resource_summary` 在执行结束时构建并持久化(`performance_executor.py:1222`),version 仅**新执行**的报告有真实值(如 `v8.0.28`),历史数据无法回补;
- 本地拆表套件 14 passed + 前端 `npm run build` 通过。
### E. 部署 5.60 ✅
| 项 | 结果 |
|----|------|
| 后端 | ✅ `performance_executor.py` scp 覆盖 + `docker restart` → Up (healthy),`/health` 200(`backend/scripts/deploy_mysql_version_560.py`) |
| 前端 | ✅ `deploy_frontend_only.py` 上传 95 文件 + 重启容器 healthy |
### F. 遗留待办(更新)
| # | 任务 | 优先级 | 说明 |
|---|------|--------|------|
| 1 | Word/PDF 实际客户端呈现 | P3(人工) | 结构/样式层已全部程序化验证,如需最终确认可在本机 Word/WPS 打开导出文件人工过目(封面/目录/分页/斑马纹) |
| 2 | 跟踪其他窗口 progress | — | recorder/projects 为其他窗口工作,合并时注意冲突 |
| 3 | 远端备份清理(可选) | P3 | 5.60 `backend/app/*.bak_20260908_*` 旧文件备份,稳定后可清理 |
---
## ⚡ 会话更新(2026-09-08 续)— 拆表部署 5.60 验证闭环 + 启动回填 ResourceClosedError 修复 ✅
### A. 部署状态核验(拆表代码此前未部署) ### A. 部署状态核验(拆表代码此前未部署)
...@@ -62,6 +126,25 @@ ...@@ -62,6 +126,25 @@
**md5 对比方法论**:Windows 工作区文件为 CRLF,`git show` 输出为 LF,与 Linux 远端直接 md5 比对会全部误报不一致——需按「git blob 内容 × LF/CRLF 变体」逐一匹配远端 md5(本次远端 5 文件全部命中 `b21f2fe9` 的 CRLF 变体,由此断定未部署)。部署脚本上传本地文件原样字节(CRLF),Python 运行不受换行符影响,与历史部署习惯一致。 **md5 对比方法论**:Windows 工作区文件为 CRLF,`git show` 输出为 LF,与 Linux 远端直接 md5 比对会全部误报不一致——需按「git blob 内容 × LF/CRLF 变体」逐一匹配远端 md5(本次远端 5 文件全部命中 `b21f2fe9` 的 CRLF 变体,由此断定未部署)。部署脚本上传本地文件原样字节(CRLF),Python 运行不受换行符影响,与历史部署习惯一致。
### F. 提交推送闭环 ✅(/GitCommit 三重门控)
| Commit | 类型 | 内容 |
|--------|------|------|
| `ef5bdd1d` | `fix(performance)` | 3 文件 +521/-12:① `_migrate_legacy_executions()` 双 scalar 修复(本节 B);② **补提交 `test_performance_satellite_tables.py` 14 用例**;③ 本 HANDOFF 进度记录 |
| `4b8d773b` | `docs(performance)` | HANDOFF 待办勾掉 + `ef5bdd1d` hash 回填 |
- **⚠️ 发现并修复漏提交**`ea2a90cb` 提交信息声称「新增 test_performance_satellite_tables.py 14 用例」但文件实际未入库(`git show ea2a90cb:backend/tests/...` 不存在)——本次经 `git status` 复核发现并随 `ef5bdd1d` 补交。教训:提交前用 `git show <hash> --stat` 核对声明文件与实际入库清单是否一致。
- **范围隔离**`backend/data/test_platform.db`(按约定不提交)、`backend/tmp/` + `tmp/`(gitignored)、projects 模块 / `diag_544_*` / `lzzsh_*`(其他窗口在途)均未混入。
- 推送:`f60a2914..ef5bdd1d..4b8d773b` platform-auto-test → origin ✅
### G. 剩余待办(会话收尾)
| # | 任务 | 优先级 | 说明 |
|---|------|--------|------|
| 1 | 跟踪其他窗口 progress | — | recorder/projects 为其他窗口工作(工作区大量未跟踪文件),合并时注意冲突 |
| 2 | 远端备份清理(可选) | P3 | 5.60 `backend/app/*.bak_20260908_*` 5 个旧文件备份,稳定运行数日后可清理 |
| 3 | 性能模块功能待办 | — | **无 P0/P1**;历史可选 P2(导出文件名页面实测、Word 实际呈现人工确认)见下文旧节 |
--- ---
## ⚡ 会话更新(2026-09-08)— P3 待办闭环:performance 大 JSON 列垂直拆表 ✅ ## ⚡ 会话更新(2026-09-08)— P3 待办闭环:performance 大 JSON 列垂直拆表 ✅
......
...@@ -3225,6 +3225,7 @@ class PerformanceExecutor: ...@@ -3225,6 +3225,7 @@ class PerformanceExecutor:
"bytesSentMb": mysql_latest.get("bytesSentMb"), "bytesSentMb": mysql_latest.get("bytesSentMb"),
"bufferPoolHitRate": mysql_latest.get("bufferPoolHitRate"), "bufferPoolHitRate": mysql_latest.get("bufferPoolHitRate"),
"uptime": mysql_latest.get("uptime"), "uptime": mysql_latest.get("uptime"),
"version": mysql_latest.get("version"),
"series": mysql_series, "series": mysql_series,
} }
if java_process_stats: if java_process_stats:
......
...@@ -644,7 +644,7 @@ ...@@ -644,7 +644,7 @@
<div class="target-host-info"> <div class="target-host-info">
<el-tag size="small" type="info" effect="plain">MySQL {{ report.targetResourceSummary.mysql.container }}</el-tag> <el-tag size="small" type="info" effect="plain">MySQL {{ report.targetResourceSummary.mysql.container }}</el-tag>
<span class="target-host-hint">MySQL 容器 {{ report.targetResourceSummary.mysql.container }}v{{ report.targetResourceSummary.mysql.version }}</span> <span class="target-host-hint">MySQL 容器 {{ report.targetResourceSummary.mysql.container }}v{{ report.targetResourceSummary.mysql.version || '' }}</span>
</div> </div>
<el-row :gutter="12" class="metrics-row"> <el-row :gutter="12" class="metrics-row">
...@@ -1279,7 +1279,7 @@ function buildReportHtml(r: PerformanceReportResponse): string { ...@@ -1279,7 +1279,7 @@ function buildReportHtml(r: PerformanceReportResponse): string {
const mysql = targetRs?.mysql const mysql = targetRs?.mysql
const mysqlHtml = mysql?.available ? `<div class="section keep-together"> const mysqlHtml = mysql?.available ? `<div class="section keep-together">
<h2>MySQL 服务监控</h2> <h2>MySQL 服务监控</h2>
<p class="sub-desc">MySQL ${mysql.container}(v${mysql.version})</p> <p class="sub-desc">MySQL ${mysql.container}(v${mysql.version || ''})</p>
${buildMetricGrid([ ${buildMetricGrid([
{ label: '线程连接数', value: String(mysql.threadsConnected), color: mysql.threadsConnected > 100 ? '#f56c6c' : '#409eff' }, { label: '线程连接数', value: String(mysql.threadsConnected), color: mysql.threadsConnected > 100 ? '#f56c6c' : '#409eff' },
{ label: '活跃线程', value: String(mysql.threadsRunning), color: mysql.threadsRunning > 20 ? '#f56c6c' : '#409eff' }, { label: '活跃线程', value: String(mysql.threadsRunning), color: mysql.threadsRunning > 20 ? '#f56c6c' : '#409eff' },
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论