适用于AWS RDS与只读副本(RR)的MySQL最佳内部错误处理方案咨询
看起来你这套CRM的数据库管控流程设计得挺严谨啊——用JSON约束读写、限制JS开发者直接操作库,还有自己的错误追踪表,确实能避开不少坑。不过只读副本上线后错误追踪失效的问题,确实挺头疼的,我给你几个实际可行的思路:
方案一:让只读副本的错误上报指向主库
MySQL其实支持跨实例的存储过程调用,你可以调整副本上的错误处理逻辑,当存储过程触发未处理错误时,不是写入本地的错误表,而是通过主库的一个专用存储过程来写入主库的错误表。
具体操作步骤:
- 在主库上创建一个专门接收错误的存储过程,比如
sp_report_error,参数包含错误代码、错误信息、调用来源(标记是哪个只读副本)、时间戳这些必要字段。 - 在只读副本上,修改原有错误处理逻辑,用
CALL 主库域名.数据库名.sp_report_error(...)的方式调用主库的存储过程。这里要注意给副本的数据库账号配置访问主库的权限,AWS RDS的主副本来默认在同一个VPC里,网络连通性一般没问题。 - 务必确保副本上的错误处理逻辑不会尝试写本地表,全部转向主库的跨实例调用。
小提醒:这种跨实例调用会有一点点延迟,但对于错误上报场景来说完全可以接受,而且不会影响副本的只读性能。
方案二:利用AWS RDS原生日志工具+自定义解析
如果不想改动太多数据库层面的逻辑,也可以基于RDS的日志系统来做错误收集:
- 开启RDS MySQL的错误日志(必要时也可以开慢查询日志辅助排查),存储过程的未处理错误会被记录在错误日志里。
- 把RDS的日志导出到AWS CloudWatch Logs,然后写个简单的Lambda函数,定期解析日志里的错误条目,把符合条件的错误信息写入主库的错误追踪表。
- 这种方式不需要改副本上的任何代码,缺点是日志解析需要做字符串匹配,不如直接调用存储过程精准,但胜在快速落地,不用动数据库原有逻辑。
方案三:调整只读副本的使用策略
如果你的只读副本主要是用来分担简单读请求的压力,可以考虑把容易触发错误的复杂查询(比如涉及存储过程的调用)路由回主库。这样错误还是会被主库的错误追踪系统捕获,副本只处理低风险的读请求。不过这个方案适合复杂查询占比极低的场景,不然可能会增加主库的压力。
关于是否放弃错误表的建议
你提到担心改用日志系统就要放弃现有的错误表,其实完全没必要——不管用上面哪种方案,最终都可以把错误信息归集到原来的错误表里,保持你熟悉的追踪流程不变。错误表的结构化特性太香了,比如你要统计某个存储过程的错误频次、筛选特定时间段的报错,直接写SQL就能搞定,比查日志效率高多了,所以尽量保留这个机制。
总结一下:优先考虑方案一,它最贴合你现有的架构,改动最小,能完美延续原来的错误追踪体验;如果不想动数据库代码,方案二是低成本的替代方案;方案三适合临时过渡或者业务场景特殊的情况。
备注:内容来源于stack exchange,提问作者Floobinator

