diff --git a/docs/06-troubleshooting.md b/docs/06-troubleshooting.md index 49db000..946db2e 100644 --- a/docs/06-troubleshooting.md +++ b/docs/06-troubleshooting.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Troubleshooting wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Troubleshooting -wiki_revision: a169b2323323d9de6304e9b430ddbe9888ea1d25 -synchronized_at: 2026-08-15T07:16:25Z +wiki_revision: 1a452e9aafdfe01580f37f9179584b89516cf992 +synchronized_at: 2026-08-15T07:59:38Z # 故障排查 @@ -134,3 +134,21 @@ synchronized_at: 2026-08-15T07:16:25Z 正式数据库未备份时不得执行该结构迁移。需要回退版本时停止服务并从迁移前备份恢复,不把 JSONB 反向猜测为旧文本。 + + +## Sense 旧媒体路由迁移排错 + +旧库迁移出现 `约束 "uni_sense_media_routes_path" 不存在 (SQLSTATE 42704)`,表示旧 `sense_media_routes.path` 由 PostgreSQL 自动命名的唯一约束保护,而新 GORM 模型准备改用唯一索引;GORM 按推导名称删除旧约束时找不到实际名称。修正该名称后若继续出现 `source_ready ... contains null values (SQLSTATE 23502)`,表示非空旧表还缺少当前模型要求的运行态列。 + +工单 #95 的兼容迁移只在 PostgreSQL 旧表存在时执行:取得 ACCESS EXCLUSIVE 表锁,确认只有一个单列 `UNIQUE(path)` 约束,将实际约束名规范为 GORM 可识别名称;同时为旧路由初始化保守运行态 `source_ready=false`、`failure_count=0`、`last_error_code=''`,再继续 AutoMigrate。迁移不会把旧路由伪装成已就绪,服务启动后仍由对账恢复真实状态。复合约束、多重 path 约束或其他无法确认的唯一性结构会拒绝迁移并整体回滚。 + +处理步骤: + +1. 停止连接该数据库的全部 Sense 实例,并确认 Sense 与 MediaMTX 相关端口已释放。 +2. 使用 `backup-sense.bat` 生成 PostgreSQL custom-format 备份;非标准 PostgreSQL 安装目录需通过 `SENSE_POSTGRES_BIN` 指向包含 `pg_dump.exe`、`pg_restore.exe` 的目录。 +3. 使用 `pg_restore --list <备份文件>` 确认备份可读取,再部署包含 #95 的 Windows 包。 +4. 先运行 `migrate-sense.bat`;成功后确认旧路由数量不变、运行态列无空值、`path` 仍有唯一索引。 +5. 再启动 Sense,检查首页、`/healthz`、MediaMTX Control API 和视频服务对账;验证完成后使用 `stop-sense.bat` 停止。 + +如果迁移报告不支持的唯一性结构,不要手工删除约束或路由;在备份副本中核对实际约束和业务数据。正式迁移失败时保留错误并从迁移前备份恢复,不通过关闭唯一性绕过迁移。 +