ALTER TABLE coupons MODIFY expire_at DATETIME NOT NULL; SELECT MAX(expire_at) FROM coupons;
设计表时给到期时间用了 timestamp,算到 2038 年之后的值直接报越界。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,timestamp 用四字节存 Unix 时间戳,上限到 2038 年初,datetime 范围更大且与时区无关。
「MySQL 时间类型选择」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。
临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。
处理上按这个顺序:超出范围的字段改为 datetime;需要时区转换的场景仍可用 timestamp;迁移时校验已有数据。
改完只确认一件事:原来越界的日期能正常写入,历史数据时间值保持不变。