fix(fam-core): 修复 sync_identity_map 增量同步 1062 主键冲突导致游标卡死
Oracle→NAS 增量同步反复报 (1062, "Duplicate entry '1073-汤圆' for key 'uq_video_raw_uid'"),整批失败、游标永不推进,同步状态页卡在"同步中"。 根因:sync_identity_map 以 Oracle person_identity_map.id(代理自增键) 作 NAS 主键,但 Oracle 库重建/恢复后这个 id 会被复用——实测 Oracle 现在 的 id=744 对应 (1073,'汤圆'),NAS 上 id=744 还是旧的 (1302,'人物E')。 upsert 先按 PK id 命中旧行,UPDATE 成 (1073,'汤圆') 后与已存在的同名行 在 uq_video_raw_uid 上二次冲突。 修复:镜像表改为 NAS 本地自增 id 主键,业务键 (video_id, raw_uid) 唯一, Oracle 的 id 只落 oracle_id 列做溯源;upsert 的 UPDATE 子句不再改写 video_id/raw_uid 这两个键列,只更新 oracle_id/canonical_name/source 等。 ddl.sql 同步更新表定义。 已在 NAS 上完成现网迁移(ADD COLUMN oracle_id -> 回填 -> 主键改自增)并 验证:补拉同步成功恢复,游标正常推进,手动触发同步验证通过。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -390,8 +390,12 @@ def upsert_sync_model_calls(rows: List[Dict]) -> int:
|
||||
def upsert_sync_identity_map(rows: List[Dict]) -> int:
|
||||
"""批量 upsert Oracle 传来的 person_identity_map 增量(幂等,重复覆盖)。
|
||||
|
||||
甲骨文不稳定,提取出的有效数据(含闭集人物识别结果/纠错记录)都要同步到
|
||||
NAS 防丢失——这张表跟 sync_people/sync_model_calls 走一样的镜像模式。
|
||||
v2 修复 (2026-08-29):不再以 Oracle 的 person_identity_map.id 作为 NAS 主键。
|
||||
该 id 只是 Oracle 端代理主键,一旦 Oracle 库重建/恢复,id 会被复用(实测出现
|
||||
id=744 同时对应 NAS 上的 (1302,'人物E') 与 Oracle 现在的 (1073,'汤圆')),
|
||||
旧写法会先按 id 撞主键、再 UPDATE 成新组合,触发 uq_video_raw_uid 二次冲突
|
||||
报 1062。现改为:NAS 本地自增 id 做主键,业务键 (video_id, raw_uid) 唯一,
|
||||
Oracle 的 id 只落 oracle_id 列作溯源参考。
|
||||
"""
|
||||
if not rows:
|
||||
return 0
|
||||
@@ -402,11 +406,10 @@ def upsert_sync_identity_map(rows: List[Dict]) -> int:
|
||||
for r in rows:
|
||||
cur.execute(
|
||||
"""INSERT INTO sync_identity_map
|
||||
(id, video_id, raw_uid, canonical_name, source, updated_at, synced_at)
|
||||
(oracle_id, video_id, raw_uid, canonical_name, source, updated_at, synced_at)
|
||||
VALUES (%s,%s,%s,%s,%s,%s, NOW())
|
||||
ON DUPLICATE KEY UPDATE
|
||||
video_id=VALUES(video_id),
|
||||
raw_uid=VALUES(raw_uid),
|
||||
oracle_id=VALUES(oracle_id),
|
||||
canonical_name=VALUES(canonical_name),
|
||||
source=VALUES(source),
|
||||
updated_at=VALUES(updated_at),
|
||||
|
||||
Reference in New Issue
Block a user