Laravel 报SQLSTATE[22007]无效日期格式1292错误 无代码改动自恢复
故障根因分析
核心判断
这次无代码改动、无人工干预的批量invalid datetime format报错,本质是夏令时切换产生的不存在时间窗口触发的数据库严格校验报错,所有现象、配置信息都能完全对应。
现象匹配依据
- 报错时间窗口和夏令时跳空段完全重合
- 应用配置的时区为
Africa/Tunis,2021年突尼斯的夏令时切换规则为3月14日凌晨2点整将时钟拨快1小时,时间直接从1:59:59跳转至3:00:00,中间覆盖的2021-03-14 02:00:00至2021-03-14 02:59:59这整小时的时间点,在该时区的现实时间序列中根本不存在 - 记录的报错起始时间刚好为2021-03-14 02:00:00,最后一条报错时间为2021-03-14 02:58:46,跨过整个不存在的时间窗口后,系统没有经过任何人工操作就自动恢复正常运行,完全匹配时间特征
- 应用配置的时区为
- 报错类型和数据库规则完全对应
- 所用的MariaDB 10.3.27版本默认开启严格SQL模式,当应用层传入的datetime值属于当前时区下不存在的跳空时段时,数据库会直接抛出
1292 Incorrect datetime value类的非法格式错误,不会做静默兜底转换 - 从日志可见,所有报错触发场景都是应用自动更新
updated_at、last_activity这类框架自动生成时间戳的字段,没有特殊业务逻辑介入
- 所用的MariaDB 10.3.27版本默认开启严格SQL模式,当应用层传入的datetime值属于当前时区下不存在的跳空时段时,数据库会直接抛出
长期稳定运行却突发故障的原因
这类报错不是持续性的代码缺陷,仅会在每年夏令时切换的1小时空窗期内触发。此前系统连续稳定运行超过一年,是因为此前的运行周期从未碰到过这个特定的时间窗口,所以没有暴露问题。
补充说明:日志中看到的SQL语句存在时间值未加单引号的异常表现(比如
set last_activity = 2021-03-14 02:00:00,而非字符串包裹的'2021-03-14 02:00:00'),是数据库驱动层在处理跳空时段特殊时间值时的解析副作用,不是引发报错的核心原因。
内容的提问来源于stack exchange,提问作者Haythem Dridi
相关产品推荐
相关产品推荐

