MySQL 5.7添加索引时报1067错误:ts字段默认值无效
临时解决MySQL 5.7中因
0000-00-00日期默认值导致的索引添加错误 我完全理解你的处境——维护一个运行了10年的老应用,不敢轻易改动依赖已久的表结构,但又必须完成索引添加操作。这个1067错误本质是MySQL 5.7的严格模式(STRICT_TRANS_TABLES)和NO_ZERO_DATE规则在起作用,它们不允许0000-00-00作为date类型的默认值。下面是两个不破坏现有表结构的临时解决方案,你可以根据自己的场景选择:
方案一:临时调整会话级SQL模式(推荐)
这个方案不需要修改表结构,只是临时绕过当前会话的日期检查,对其他业务连接无影响:
- 先查看当前会话的SQL模式,记录下来后续要恢复:
SELECT @@SESSION.sql_mode; - 临时移除导致错误的模式规则:
(如果你的sql_mode里还有SET SESSION sql_mode = REPLACE(REPLACE(@@SESSION.sql_mode, 'STRICT_TRANS_TABLES', ''), 'NO_ZERO_DATE', '');NO_ZERO_IN_DATE,也可以一起替换掉) - 执行你的索引添加语句:
(顺便提一句,索引名里用逗号不太规范,换成下划线会更符合MySQL的命名习惯)ALTER TABLE `dbname`.`processes_history` ADD INDEX `idx_pid_execid_ts` (`p_id`, `exec_id`, `ts`); - 恢复原来的会话SQL模式,把第一步查到的值填回去:
SET SESSION sql_mode = '你记录的原sql_mode值';
方案二:临时修改字段默认值(适合无法修改SQL模式的场景)
如果你的环境不允许调整SQL模式,可以临时修改ts字段的默认值为合法日期,完成索引添加后再改回:
- 先确认当前
ts字段的默认值(做个备份):SHOW CREATE TABLE `dbname`.`processes_history`; - 临时修改默认值为一个合法的日期,比如
1970-01-01:ALTER TABLE `dbname`.`processes_history` ALTER COLUMN `ts` SET DEFAULT '1970-01-01'; - 执行索引添加语句:
ALTER TABLE `dbname`.`processes_history` ADD INDEX `idx_pid_execid_ts` (`p_id`, `exec_id`, `ts`); - 改回原来的默认值:
注意:这个操作建议在业务低峰期执行,避免短暂的默认值变化影响新插入的数据。ALTER TABLE `dbname`.`processes_history` ALTER COLUMN `ts` SET DEFAULT '0000-00-00';
这两个方案都不会改动现有数据和长期的表结构,只是临时绕过检查来完成索引添加。优先推荐方案一,因为它的侵入性更低,不会影响表字段的任何属性。
内容的提问来源于stack exchange,提问作者Imnotapotato
相关产品推荐
相关产品推荐

