202 lines
5.8 KiB
Markdown
202 lines
5.8 KiB
Markdown
# PostgreSQL / MySQL Host Failure-Path Checklist
|
||
|
||
日期:2026-03-28
|
||
作者:Senior Backend Engineer
|
||
用途:给 QA / CTO 一份可直接执行的宿主机检查清单,用最短路径补齐 PostgreSQL / MySQL failure-path 可审计证据。
|
||
|
||
配套文档:
|
||
|
||
- `QA_RUNTIME_ENVIRONMENT.md`
|
||
- `FAILURE_PATH_EVIDENCE_TEMPLATE.md`
|
||
- `FAILURE_PATH_EVIDENCE_SAMPLE.md`
|
||
- `USABLE_EVIDENCE_LEDGER.md`
|
||
- `USABLE_RELEASE_GATE.md`
|
||
|
||
## 1. 适用边界
|
||
|
||
- 当前只覆盖 CLI 的 `connect` / `query` failure-path。
|
||
- 当前不替代 `SMOKE_RUNBOOK.md` 的 happy-path。
|
||
- 当前目标是把宿主机执行步骤、预期断言和回填顺序收敛成一份可执行 runbook。
|
||
|
||
## 2. 前置条件
|
||
|
||
- 宿主机具备 `docker` 与 `docker compose`
|
||
- 已拉取当前仓库并进入项目根目录
|
||
- 已准备可执行 CLI:
|
||
- `./target/release/dbtool`
|
||
- 或 `./target/debug/dbtool`
|
||
- 或 `cargo run -q -p dbtool-cli -- <args>`
|
||
- 宿主机可记录:
|
||
- UTC 时间
|
||
- binary path
|
||
- `dbtool --version`
|
||
- commit SHA / branch
|
||
|
||
## 3. 执行前准备
|
||
|
||
### 3.1 启动数据库
|
||
|
||
```bash
|
||
docker compose -f docker-compose.demo.yml up -d postgres mysql
|
||
./examples/scripts/bootstrap-postgres.sh
|
||
./examples/scripts/bootstrap-mysql.sh
|
||
```
|
||
|
||
### 3.2 固定 CLI 路径
|
||
|
||
```bash
|
||
export DBTOOL_BIN=./target/release/dbtool
|
||
test -x "$DBTOOL_BIN"
|
||
"$DBTOOL_BIN" --version
|
||
git rev-parse HEAD
|
||
git branch --show-current
|
||
```
|
||
|
||
若当前只构建了 debug binary,可改成:
|
||
|
||
```bash
|
||
export DBTOOL_BIN=./target/debug/dbtool
|
||
```
|
||
|
||
### 3.3 固定密码环境变量
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=dbtool
|
||
```
|
||
|
||
## 4. 统一断言规则
|
||
|
||
每条场景都至少检查:
|
||
|
||
- `status`
|
||
- `state`
|
||
- `error.kind`
|
||
- 输出中不泄露真实密码
|
||
|
||
| Scenario ID | Driver | 失败类型 | 预期 |
|
||
| --- | --- | --- | --- |
|
||
| `PG-CONN-AUTH-001` | postgres | 错误密码 | `status=error`, `state=error`, `error.kind=authentication` |
|
||
| `PG-CONN-NET-001` | postgres | 不可达端口 | `status=error`, `state=error`, `error.kind=connection` |
|
||
| `PG-QUERY-SQL-001` | postgres | 坏 SQL / 不存在对象 | `status=error`, `state=error`, `error.kind=query` |
|
||
| `MY-CONN-AUTH-001` | mysql | 错误密码 | `status=error`, `state=error`, `error.kind=authentication` |
|
||
| `MY-CONN-NET-001` | mysql | 不可达端口 | `status=error`, `state=error`, `error.kind=connection` |
|
||
| `MY-QUERY-SQL-001` | mysql | 坏 SQL / 不存在对象 | `status=error`, `state=error`, `error.kind=query` |
|
||
|
||
## 5. 执行顺序
|
||
|
||
### 5.1 PostgreSQL 错误密码
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=wrong-password
|
||
"$DBTOOL_BIN" connect --driver postgres --host 127.0.0.1 --port 55432 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD --result-format json
|
||
```
|
||
|
||
- Scenario ID:`PG-CONN-AUTH-001`
|
||
|
||
### 5.2 PostgreSQL 不可达端口
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=dbtool
|
||
"$DBTOOL_BIN" connect --driver postgres --host 127.0.0.1 --port 59999 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD --result-format json
|
||
```
|
||
|
||
- Scenario ID:`PG-CONN-NET-001`
|
||
|
||
### 5.3 PostgreSQL 坏 SQL
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=dbtool
|
||
"$DBTOOL_BIN" query --driver postgres --host 127.0.0.1 --port 55432 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD --file examples/sql/postgres/failing_query.sql --result-format json
|
||
```
|
||
|
||
- Scenario ID:`PG-QUERY-SQL-001`
|
||
|
||
### 5.4 MySQL 错误密码
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=wrong-password
|
||
"$DBTOOL_BIN" connect --driver mysql --host 127.0.0.1 --port 53306 --database qa_demo --username dbtool --password-env DBTOOL_PASSWORD --result-format json
|
||
```
|
||
|
||
- Scenario ID:`MY-CONN-AUTH-001`
|
||
|
||
### 5.5 MySQL 不可达端口
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=dbtool
|
||
"$DBTOOL_BIN" connect --driver mysql --host 127.0.0.1 --port 59998 --database qa_demo --username dbtool --password-env DBTOOL_PASSWORD --result-format json
|
||
```
|
||
|
||
- Scenario ID:`MY-CONN-NET-001`
|
||
|
||
### 5.6 MySQL 坏 SQL
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=dbtool
|
||
"$DBTOOL_BIN" query --driver mysql --host 127.0.0.1 --port 53306 --database qa_demo --username dbtool --password-env DBTOOL_PASSWORD --file examples/sql/mysql/failing_query.sql --result-format json
|
||
```
|
||
|
||
- Scenario ID:`MY-QUERY-SQL-001`
|
||
|
||
## 6. 每条证据必须回填的字段
|
||
|
||
- Date (UTC)
|
||
- Operator
|
||
- Host
|
||
- Execution Path
|
||
- Binary Path
|
||
- Binary Version
|
||
- Commit SHA
|
||
- Branch
|
||
- Driver
|
||
- Scenario ID
|
||
- Command
|
||
- Exit Code
|
||
- Key Output
|
||
- Verdict
|
||
|
||
推荐直接复制 `FAILURE_PATH_EVIDENCE_TEMPLATE.md`,首次执行可对照 `FAILURE_PATH_EVIDENCE_SAMPLE.md`。
|
||
|
||
如需减少人工抄录,可直接运行:
|
||
|
||
```bash
|
||
scripts/qa/run-failure-path-evidence.sh ./target/release/dbtool all ./tmp/failure-path-evidence
|
||
```
|
||
|
||
当前 helper 会:
|
||
|
||
- 自动校验 `status` / `state` / `error.kind`
|
||
- 对可检测到的密码泄露模式直接判 `fail`
|
||
- 对 `unknown-*` 或空 traceability 字段直接判 `fail`
|
||
- 在 sidecar / host 两条路径下统一保留同一组 host / binary / version / commit / branch 标签
|
||
|
||
但回填前仍需人工复核 scenario、traceability 字段与输出摘要。
|
||
|
||
## 7. 回填顺序
|
||
|
||
1. 先把 6 条原始执行记录贴到 issue / 评论
|
||
2. 再同步 `USABLE_EVIDENCE_LEDGER.md`
|
||
3. 再同步 `USABLE_RELEASE_GATE.md`
|
||
4. 若 6 条都满足预期,再把 failure-path blocker 从 `unverified` / `未满足` 移除
|
||
|
||
## 8. 异常处理规则
|
||
|
||
- 若 `status` 不是 `error`,先视为 contract 回归候选
|
||
- 若 `state` 不是 `error`,先视为 shared app / CLI 映射回归候选
|
||
- 若 `error.kind` 偏离矩阵预期,先拆 defect issue
|
||
- 若输出出现真实密码或敏感值,立即按安全缺陷处理
|
||
|
||
## 9. 清理
|
||
|
||
```bash
|
||
export DBTOOL_PASSWORD=dbtool
|
||
docker compose -f docker-compose.demo.yml down -v
|
||
```
|
||
|
||
## 10. 完成标准
|
||
|
||
- 6 条场景全部留档
|
||
- 每条都有 traceability 字段
|
||
- 每条都断言 `status` / `state` / `error.kind`
|
||
- `USABLE_EVIDENCE_LEDGER.md` 与 `USABLE_RELEASE_GATE.md` 已同步
|