SELECT o.order_no FROM pay_order o LEFT JOIN compensate_log c ON c.biz_no = o.order_no WHERE o.status = 'PAID' AND c.id IS NULL;
扣款成功后进程被发布重启,补偿日志表里没有这一笔,后面入账失败的补偿任务扫不到它,订单一直挂在扣款成功入账失败。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:代码先提交业务事务,再单独 insert 补偿日志。两步之间进程退出,业务落了库日志没写进去,补偿任务只认日志表,这笔就彻底丢了。
围绕「补偿日志同事务」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。同一份配置存在多处的,先确认改的是被加载的那一份。
新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。
处理上按这个顺序:补偿日志和业务更新放进同一个本地事务;日志表按业务单号加唯一键 重复写入直接失败;发布前先停流量 等在途事务跑完再重启;存量数据按业务表反查 补一批缺失日志。
确认没问题再收工,重启演练后业务表和补偿日志一一对应 反查 SQL 返回 0 行。
