mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-09-30 16:26:36 +08:00
2df061a19f
- Fix deadlock when updating tunnel entries with offline nodes - Add test file for tunnel entry SQLite operations - Update contract tests for entry port conflict and limiter sync - Add plan documents for SQLite deadlock fix and contract semantics
50 lines
2.8 KiB
Markdown
50 lines
2.8 KiB
Markdown
# 042 - SQLite 隧道编辑添加入口节点卡死排查
|
|
|
|
## Issue
|
|
- 现象:SQLite 数据库下,编辑已有隧道并新增入口节点时接口卡住;PostgreSQL 下同样操作正常。
|
|
- 初步判断:`tunnelUpdate` 在事务尚未提交时触发了额外 repository 读查询,SQLite 配置 `MaxOpenConns(1)`,容易在同一请求内形成自锁等待。
|
|
|
|
## Goal
|
|
- 找出 SQLite 与 PostgreSQL 行为差异的根因。
|
|
- 修复隧道编辑新增入口节点时的阻塞问题,同时不破坏现有的入口端口冲突校验。
|
|
- 补充最小回归测试,锁定“事务内校验不可再次占用根连接”的场景。
|
|
|
|
## Checklist
|
|
- [x] 复核 `tunnelUpdate` 在新增入口节点路径上的调用链,确认事务内哪些查询绕过了 `tx`。
|
|
- [x] 为相关 repository 查询补齐 `Tx` 版本,避免 SQLite 单连接下的自锁等待。
|
|
- [x] 调整 handler 中入口端口冲突校验,保证事务内全程复用同一个 `tx`。
|
|
- [x] 增加针对 SQLite 的回归测试,验证事务内校验不会阻塞。
|
|
- [x] 运行相关 handler/backend 测试并记录结果。
|
|
|
|
## Notes
|
|
- 重点关注 `validateTunnelEntryPortConflictsForNewEntries`:当前它在 `tx.Commit()` 前执行,但内部调用 `ListForwardsByTunnel` / `ListForwardPorts` / `HasOtherForwardOnNodePort` 等非事务查询。
|
|
- SQLite 在 `go-backend/internal/store/repo/repository.go` 中显式设置了 `SetMaxOpenConns(1)`,因此这种模式在 SQLite 下会比 PostgreSQL 更容易表现为“卡死”。
|
|
|
|
## 实际改动
|
|
- `go-backend/internal/store/repo/repository_control.go`
|
|
- 新增 `ListForwardsByTunnelTx`、`ListForwardPortsTx`、`HasOtherForwardOnNodePortTx`,并让原有非事务方法复用统一实现。
|
|
- `go-backend/internal/http/handler/mutations.go`
|
|
- `tunnelUpdate` 在事务内执行入口端口冲突校验时显式传入当前 `tx`。
|
|
- `validateTunnelEntryPortConflictsForNewEntries` 改为全程使用事务查询。
|
|
- 新增 `validateForwardPortAvailabilityTx`,避免事务内回落到根连接查询。
|
|
- `go-backend/internal/http/handler/tunnel_entry_sqlite_test.go`
|
|
- 新增 SQLite 回归测试,验证开启事务后执行新增入口校验不会阻塞。
|
|
|
|
## 测试结果
|
|
|
|
### 通过
|
|
```bash
|
|
cd go-backend && go test ./internal/http/handler/...
|
|
```
|
|
- 结果:通过。
|
|
|
|
### 额外检查
|
|
```bash
|
|
cd go-backend && go test ./tests/contract/...
|
|
```
|
|
- 结果:未全绿;当前失败集中在既有的入口端口语义合同用例:
|
|
- `TestIssue313_EntryPortCrossTunnelConflictContract`
|
|
- `TestTunnelUpdateChangesEntryNodeButLeavesOldForwardRuntimeContract`
|
|
- `TestTunnelUpdateEntryTransitionsCleanupForwardRuntimeContract`
|
|
- 备注:这些失败反映的是“新增/切换入口时端口校验预期”与现有合同用例之间的行为差异,不是本次 SQLite 事务自锁修复本身的编译或阻塞问题。
|