mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-09-28 07:36:38 +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
2.8 KiB
2.8 KiB
042 - SQLite 隧道编辑添加入口节点卡死排查
Issue
- 现象:SQLite 数据库下,编辑已有隧道并新增入口节点时接口卡住;PostgreSQL 下同样操作正常。
- 初步判断:
tunnelUpdate在事务尚未提交时触发了额外 repository 读查询,SQLite 配置MaxOpenConns(1),容易在同一请求内形成自锁等待。
Goal
- 找出 SQLite 与 PostgreSQL 行为差异的根因。
- 修复隧道编辑新增入口节点时的阻塞问题,同时不破坏现有的入口端口冲突校验。
- 补充最小回归测试,锁定“事务内校验不可再次占用根连接”的场景。
Checklist
- 复核
tunnelUpdate在新增入口节点路径上的调用链,确认事务内哪些查询绕过了tx。 - 为相关 repository 查询补齐
Tx版本,避免 SQLite 单连接下的自锁等待。 - 调整 handler 中入口端口冲突校验,保证事务内全程复用同一个
tx。 - 增加针对 SQLite 的回归测试,验证事务内校验不会阻塞。
- 运行相关 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.gotunnelUpdate在事务内执行入口端口冲突校验时显式传入当前tx。validateTunnelEntryPortConflictsForNewEntries改为全程使用事务查询。- 新增
validateForwardPortAvailabilityTx,避免事务内回落到根连接查询。
go-backend/internal/http/handler/tunnel_entry_sqlite_test.go- 新增 SQLite 回归测试,验证开启事务后执行新增入口校验不会阻塞。
测试结果
通过
cd go-backend && go test ./internal/http/handler/...
- 结果:通过。
额外检查
cd go-backend && go test ./tests/contract/...
- 结果:未全绿;当前失败集中在既有的入口端口语义合同用例:
TestIssue313_EntryPortCrossTunnelConflictContractTestTunnelUpdateChangesEntryNodeButLeavesOldForwardRuntimeContractTestTunnelUpdateEntryTransitionsCleanupForwardRuntimeContract
- 备注:这些失败反映的是“新增/切换入口时端口校验预期”与现有合同用例之间的行为差异,不是本次 SQLite 事务自锁修复本身的编译或阻塞问题。