结论
t_order_recent_detail 不更新时,不能只看数据库分表是否存在,要按“Canal 过滤器 → Kafka Topic → watchSaasOrder 消费 → 最近采购表写入”顺序排查。
本次确认:
- 预发存在 t_order、t_order_0~t_order_15,sid=9999 的订单落在 _15。
- 预发 Canal 修改后,t_order_15 的订单 INSERT/UPDATE 已进入 saas_recent_po。
- 线上 prod-saas 原过滤规则为 kzsaas\\.t_order,只匹配主表,不匹配订单分表。
- 线上 Canal 位点持续推进,说明 Canal 进程在运行;进程正常不等于过滤了所有分表。
关键业务规则
- 订单分片:sid % 16。
- sid=9999:9999 % 16 = 15,订单表和明细表分别为 t_order_15、t_order_detail_15。
- Canal 只需要监听订单表变更;watchSaasOrder 收到订单事件后,再查询对应的订单明细分表。
- 正常订单通常先以状态 0 插入,再更新为有效状态;消费者不能只验证 INSERT,还要验证后续 UPDATE。
代码依据
- zgj3.0/microservice/tools/src/Process/WatchSaasOrderProcess.php:消费 SAAS 订单 Topic,并调用订单监听服务。
- zgj3.0/microservice/tools/src/Services/Saas/SaasOrderWatchService.php:识别订单分表,按 sid 解析订单表和明细表,更新 t_order_recent_detail。
- zgj3.0/microservice/tools/src/Models/Saas/Order.php:查询历史订单时,订单表和明细表必须使用同一分片。
标准排查流程
1. 确认 Canal 配置
sudo grep -nE '^(canal.instance.filter.regex|canal.mq.topic|canal.mq.partition)' /opt/app/canal/conf/<instance>/instance.properties
订单分表规则应为:
canal.instance.filter.regex=kzsaas\\.t_order(_[0-9]+)?
2. 修改前备份并重启对应实例
sudo cp -a /opt/app/canal/conf/<instance>/instance.properties /opt/app/canal/conf/<instance>/instance.properties.bak.<timestamp>
sudo docker restart canal-server
不要删除 Canal 位点文件,不要重置 binlog,不要顺手重启 Kafka 或 ZooKeeper。
3. 验证消息链路
- Canal 日志确认过滤器已加载,并出现 start successful、find start position。
- Kafka Topic 确认出现目标分表的 INSERT 和后续 UPDATE。
- 消费组位点应持续接近 Topic 末端;少量实时延迟不等于消费中断。
- 若消息已消费但数据库不更新,继续查 watchSaasOrder 运行版本、异常日志、明细表查询结果和事务回滚。
分支与发布经验
- bugfix 分支必须从 develop 创建,不能从 staging 创建。
- 重建同名远端分支时使用 --force-with-lease,并保留旧分支指针作为备份。
- Canal 配置变更与 watchSaasOrder 代码发布必须一起验证;只改其中一侧不能证明链路恢复。
相关文档
- zgj3.0/docs/线上Canal分表配置修改手册.md
- zgj3.0/microservice/tools/src/Services/Saas/SaasOrderWatchService.php