最近遇到了一个奇怪的问题:一个业务在测试环境通过mybatis框架写入时间到timestamp(3)字段类型中,是带了毫秒的。但上线后timestamp(3)的数据毫秒丢失了,全部为000.
环境差异对比:
测试环境:mysql 5.6.23
访问方式:直连
线上环境:mysql 5.7.18
访问方式:访问proxysql代理
* 首先确认的表结构都是一样的,可以确定的是环境导致的,具体是mysql版本,还是加了proxysql导致的?
* 再一个可以确认的是mysql 5.6和5.7.18都是支持timestamp的精度配置,具体是从MySQL 5.6.4开始都支持了。
如下在线下环境复现,数据库版本在5.7.18,表结构如下:
CREATE TABLE `sb1` (
`dt` timestamp(3) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
手动直连mysql执行:`insert table sbtest.sb1('2020-10-15 19:04:11.123')`
通过proxysql连进来执行:`insert table sbtest.sb1('2020-10-15 19:04:11.124')`
结果显示是正常的,都带了毫秒了:
root 17:10: [sbtest]> select * from sb1;
+-------------------------+
| dt |
+-------------------------+
| 2020-10-15 19:04:11.123 |
| 2020-10-15 19:04:11.124 |
+-------------------------+
2 rows in set (0.00 sec)
这可以说明,proxysql也是支持的。
此时出现另一种可能,到线上环境时insert的SQL并没有带毫秒。立即到线上proxysql查看日志,确认sql确实是没有带毫秒的。那基本就可以确认,是由于程序到线上环境中自己把毫秒去掉了。那有可能的原因是程序所在的环境不一样,如框架版本、环境配置等。
最后检查程序环境、程序都是一样的。这就奇怪了!!!
不过,重新整理下,直连可以,使用proxysql就不行了,那主要还是因为经过proxysql后导致。那会不会因为mybatis通过proxysql后就认为后端不支持timestamp带毫秒就不带了呢?
突然想到proxysql对外会提供一个数据库的版本号,默认是5.5.30. 果断开始测试,将proxysql中的`mysql-server_version`从`5.5.30`改为`5.6.23`.
再使用程序通过proxysql写入timestamp时间,发现带了毫秒了。
####结论:
mybatis框架登录mysql后,会自动识别mysql的版本,判断当前版本是否支持timestamp带毫秒,如果是5.6.4以前版本,就自动将毫秒去掉,避免写入异常;如果是5.6.4以上版本就自动带上毫秒。
文章最后更新时间:
2020年10月16日 17:38:28