定时任务用一条 insert 批量写 5000 条订单,落库后查 16 个片,数据全在 ds_00,其他片为空,按用户查却查不到。乍看像缓存或者权限的锅,追下去往往不是。
INSERT INTO t_order(order_no, user_id, amount) VALUES
('A001', 88123, 99.00), ('A002', 88124, 120.00);
追下去是这么回事:批量 SQL 的 values 里没有分片键列,中间件无法逐行计算路由,只能按第一条或默认片处理。整批数据被当成一个路由单元写进同一个片。
「批量写入路由」这类改动最怕改一半,回滚脚本先准备好,再动生产。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。
能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。报错里带路径的,先去看那个路径在不在、权限对不对。
同一份配置存在多处的,先确认改的是被加载的那一份。
具体做法是,批量写入前在应用层按分片键分组 每组一条 SQL;SQL 里显式带上分片键列 不要依赖默认值;单批控制在 500 条以内 避免跨片事务过大;写完抽样按分片键反查 确认落片正确。
验收就看一点,5000 条按 user_id 分散到 16 个片 抽样反查全部命中。
