SELECT mask(phone) m, count(*) c
FROM users GROUP BY m HAVING c > 1;

两条用户记录手机号只差中间四位,脱敏后都变成 138****0000,唯一索引冲突,合并账号的脚本直接报 1062。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:脱敏值被写进了有唯一约束的列,不同原值映射到同一个掩码。迁移脚本没考虑碰撞,也没有先做去重。

「脱敏唯一约束冲突」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。同一份配置存在多处的,先确认改的是被加载的那一份。

新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。

处理上按这个顺序:唯一约束留在原始列或哈希列 不放掩码列;迁移前统计碰撞 按原值分组;碰撞记录先人工确认再合并;加断言 掩码列不允许唯一索引。

确认没问题再收工,碰撞查询返回零行 合并脚本不再报 1062。

作者 9823189