explicit_defaults_for_timestamp是从5.6.6引入的一个新参数,默认是off。
作用:对TIMESTAMP类型列的默认值和NULL值的处理,是否启用非标准特性。
默认情况下,explicit_defaults_for_timestamp被禁用,即启用非标准特性。
什么是非标准特性?
标准特性:如果没有显示声明为 NOT NULL,则默认声明为 NULL (除timestamp外的其他数据类型)
非标准特性:如果没有显示声明为 NULL,则默认声明为 NOT NULL(timestamp)
当explicit_defaults_for_timestamp=0时,默认状态,即启用非标准特性
测试1:
id=1的行,往timestamp列插入null值时,会自动为该列设置为current time
id=2的行,插入时未指定值的timestamp列中被插入了0000-00-00 00:00:00(非表中第一个timestamp列)
id=3的行,插入时未指定值的第一个timestamp列中被插入了current time值
当explicit_defaults_for_timestamp=1时,即启用标准特性
测试2:
id=1的行,如果timestamp列指定not null属性,在非stric sql_mode模式下,如果插入的时候该列没有指定值,那么会向该列中插入0000-00-00 00:00:00,并且产生告警
★
通过对 explicit_defaults_for_timestamp的了解,排查一个问题
★
架构如下:
现象:
二级从库复制频繁中断,一级从库正常
日志:
2017-08-18 14:17:47 357305 [ERROR] Slave SQL: Error 'Column 'modified' cannot be null' on query. Default database: 'jpos'. Query: 'insert into activity_account_sum(id,activity_id,income_number,expend_number,created,modified) values(0,584126,0,0,'2017-08-18 14:17:46',null)', Error_code: 1048
2017-08-18 14:17:47 357305 [Warning] Slave: Column 'modified' cannot be null Error_code: 1048
2017-08-18 14:17:47 357305 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000233' position 879369308
初步分析:
通过日志信息可知,modified字段插入了null值,与表声明的not null冲突,导致错误引起复制中断。
具体分析:
解决:
explicit_defaults_for_timestamp跟其他参数正好相反,NULL或NOT NULL需要十分注意,最好的方式就是规范话,统一为NOT NULL 再加上默认值,即便如此,跨版本之间也容易出现问题,所以新版本上线前新引入的参数一定要有所了解,不然一不小心就会入坑。