SELECT count(*), sum(amount) FROM refund_flow
WHERE order_no IN (SELECT order_no FROM refund_task
  WHERE batch_no = 'B20260301');
# 先 dry-run 再执行

运维把退款补偿脚本重跑了一次,脚本里没有去重条件,退款表同一批 order_no 又插了一遍,五个用户余额合计多退 5000。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,脚本按日期范围捞订单直接退款,没有先查退款流水。第一次跑完流水已经写了,第二次照样从订单表出发,重复的部分没有任何拦截。

围绕「补偿脚本幂等」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。

接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

处理上按这个顺序:执行前按订单号查退款流水 已存在的跳过;退款表按 order_no 加唯一索引 让重复插入失败;脚本加 dry-run 参数 先打印影响条数和金额;跑完核总金额 和预期差一分都停下来。

改完只确认一件事:dry-run 打印的条数和实际需要退的一致 正式跑完 refund_flow 条数不再增加。

作者 9823189