首页 > 数据库 >MySQL生产事故一例

MySQL生产事故一例

时间:2022-10-28 14:31:51浏览次数:76  
标签:cannot 事故 一例 MySQL timestamp inserttime jdbcType null TIMESTAMP


背景

线上日志报错:

18:57:54.985 [http-nio-8082-exec-9] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: 
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'inserttime' cannot be null
### The error may exist in class path resource [mapping/VarMonitorMapper.xml]
### The error may involve com.aaa.dao.VarMonitorMapper.insert-Inline
### The error occurred while setting parameters
### SQL: insert into var_monitor (var_id, inserttime, insertby, updatetime, updateby) values (?, ?, ?, ?, ?)
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'inserttime' cannot be null
; Column 'inserttime' cannot be null; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'inserttime' cannot be null] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'inserttime' cannot be null

对应的建表语句:

inserttime timestamp default CURRENT_TIMESTAMP not null comment '插入时间',

分析

问题总结:
测试环境和生产环境 inserttime 字段的定义相同:​​​inserttime timestamp default CURRENT_TIMESTAMP not null comment '插入时间'​​​,差别之处在于版本号。
测试环境:

select version();
5.7.16

生产环境:

select version();
5.7.21-20-log

带着关键字​​timestamp default CURRENT_TIMESTAMP​​​和​​Column 'inserttime' cannot be null​​​搜索Google。找到​​MySQL案例一则​​。

测试环境:

show variables like '%explicit_defaults_for_timestamp%';
explicit_defaults_for_timestamp=OFF

生产环境:

show variables like '%explicit_defaults_for_timestamp%';
explicit_defaults_for_timestamp=ON

建表语句的意思是insert数据时,如果 inserttime 数据为空,则用系统default时间,这也是测试环境没有发现这个问题的原因。
生产环境里,​​​explicit_defaults_for_timestamp=ON​​​,即如果 inserttime 数据为空,则报错​​Column 'inserttime' cannot be null​​。注意:可以直接通过客户端如 dataGrip insert 一条 inserttime is null 的数据。

解决方法

  1. 修改生产参数配置,一来不建议,二来没有修改权限,需要联系DBA执行(还说服他们):
    ​​​set explicit_defaults_for_timestamp=OFF​
  2. mybatis使用insertSelective而不用insert,建议:
<insert id="insert" parameterType="com.aaa.model.VarMonitor">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into var_monitor (var_id, inserttime, insertby, updatetime, updateby)
values (#{varId,jdbcType=INTEGER}, #{inserttime,jdbcType=TIMESTAMP}, #{insertby,jdbcType=VARCHAR}, #{updatetime,jdbcType=TIMESTAMP}, #{updateby,jdbcType=VARCHAR})
</insert>

<insert id="insertSelective" parameterType="com.aaa.model.VarMonitor">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into var_monitor
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="varId != null">
var_id,
</if>
<if test="inserttime != null">
inserttime,
</if>
<if test="insertby != null">
insertby,
</if>
<if test="updatetime != null">
updatetime,
</if>
<if test="updateby != null">
updateby,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="varId != null">
#{varId,jdbcType=INTEGER},
</if>
<if test="inserttime != null">
#{inserttime,jdbcType=TIMESTAMP},
</if>
<if test="insertby != null">
#{insertby,jdbcType=VARCHAR},
</if>
<if test="updatetime != null">
#{updatetime,jdbcType=TIMESTAMP},
</if>
<if test="updateby != null">
#{updateby,jdbcType=VARCHAR},
</if>
</trim>
</insert>
  1. 修改DB设置,不建议:
    ​​​alter table var_monitor modify column inserttime timestamp default CURRENT_TIMESTAMP null comment '插入时间';​

参考

​MySQL案例一则​


标签:cannot,事故,一例,MySQL,timestamp,inserttime,jdbcType,null,TIMESTAMP
From: https://blog.51cto.com/u_15851118/5804871

相关文章

  • mysql的主从复制原理
    MySQL主从复制面试和原理1.什么事是主从赋值主从复制是用来建立一个主数据库master和一个一样的从数据库,主数据库一般是准实时update,inster,delete从数据库一般都是进行......
  • MySQL的使用
    MySQL基本信息:1.配置文件及目录 :/etc/mysql/mysql.conf.d,2.用户信息及目录 :/home/用户/.bashrc ===>使用mima命令查看用户信息一.MySQLl服务......
  • azure关闭mysql ssl
    创建mysql服务默认会开启ssl,导致连接报错ERROR3159(HY000):Connectionsusinginsecuretransportareprohibitedwhile--require_secure_transport=ON.解决办法:......
  • Linux环境下mysql数据库备份操作说明
    如下:一、 编写数据库备份shell脚本1、登录服务器,进入mysql安装目录。例:cd/usr/local/mysql2、创建目录dbBakShell和dbbak,用于放置数据备份脚本及备份文件mkdir d......
  • (Linux安装)Mysql5.7数据库
    下载地址:https://downloads.mysql.com/archives/community/ 1.解压tar-xvfmysql-5.7.26-linux-glibc2.12-x86_64.tar 2.再移动并重命名一下mvmysql-5.7.26-linu......
  • MySQL 5.0版本的安装步骤
    一、MYSQL的安装1、以管理员的身份运行“mysql_setup.exe”2、点击“Next”3、选择“Iacceptthetermsinthelicenseagreement”点击“Next”4、选择安装类型,“Typ......
  • Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class
    这是在弄那个政策查询系统的时候遇到的报错其实明眼就能看出来是mysql的版本问题,关键是怎么改首先mysql8版本以下的用的是:com.mysql.jdbc.Drivermysql8以上的用的是......
  • MySQL锁
    MySQL锁目录MySQL锁按照锁思想分类乐观锁悲观锁按照锁类型分类读锁(共享锁、S锁)写锁(排他锁、X锁)意向锁意向共享锁(ISLock)意向排他锁(IXLock)按照锁级别分类全局锁(数据库级别......
  • 【MySQL】Navicat15 安装
    #Navicat安装`提示`:鉴于之间已经出了MySQL的安装教程,在这了我也讲下,那个其实包含了两个知识点,既可以小白初次安装MySQL客户端,也面向想安装5.x和8.x两个版本的。---@[T......
  • Ubuntu 22.04 安装 MySQL
    本文记录了在Ubuntu22.04下安装MySQL8.0和5.7版本的步骤。下载文件在https://downloads.mysql.com/archives/community/发行地址中选择Linux-Generic操作......