龙空技术网

ProxySQL疑难杂症-丢失毫秒精度问题

空山细兩 465

前言:

现在同学们对“mysql当前毫秒”可能比较关切,姐妹们都需要学习一些“mysql当前毫秒”的相关知识。那么小编也在网络上收集了一些对于“mysql当前毫秒””的相关资讯,希望兄弟们能喜欢,各位老铁们快快来了解一下吧!

Author

Date

Version

WangJ

2022-9-29

1.0

ProxySQL保存TimeStamp(3)丢失毫秒精度问题问题描述使用ProxySQL代理MYSQL(5.7.x)负载均衡。在MySql上创建表,指定字段类型为datetime(3)或timestamp(3)。使用mysql-connector-8.0.x版本。使用JDBC写入datetime(3)字段数据,或通过mybatis影射的mapper文件insert datetime类型的数据时,发现并没有保存毫秒值。如果jdbc直接连接到mysql,而不是通过ProxySQL中间的代理,则可以写入datetime(3)的毫秒值。所以,最后定位在问题出在ProxySQL上。解决通过上述的测试,JDBC连接到ProxySQL写入datetime(3)后没有毫秒值,而直接通过JDBC连接到目标mysql,则可以保存datetime(3)的毫秒值,所以问题就出在ProxySQL的代理层。现在看ProxySQL的全局变量,设置正确的目标mysql版本,如mysql版本为5.7.36,则设置:注意,必须要设置Mysql的版本号为3节数字,如5.7.22,而不能仅是5.7。否则依然不会保存毫秒值。

Admin> update global_variables set variable_value='5.7.36' where variable_name='mysql-server_version';Query OK, 1 row affected (0.01 sec)Admin> select * from global_variables where variable_name='mysql-server_version';+----------------------+----------------+| variable_name | variable_value |+----------------------+----------------+| mysql-server_version | 5.7.36 |+----------------------+----------------+1 row in set (0.01 sec)Admin> LOAD MYSQL VARIABLES TO RUNTIME;Query OK, 0 rows affected (0.01 sec)Admin> SAVE MYSQL VARIABLES TO DISK;Query OK, 147 rows affected (0.15 sec)Admin> select * from global_variables where variable_name='mysql-server_version';+----------------------+----------------+| variable_name | variable_value |+----------------------+----------------+| mysql-server_version | 5.7.36 |+----------------------+----------------+1 row in set (0.01 sec)

截图:

设置后,让mysql生效,则再次写入datetime(3)后,已经可以正常保存毫秒值了。完美解决。配置完成后,再次使用JDBC或mybatis保存数据,则可以出现正确的毫秒值。创建表

create table test_1(id int,dt1 datetime(3),dt2 timestamp(3));
JDBC代码
//mysql-connector-8.0.x版本Class.forName("com.mysql.cj.jdbc.Driver");//连接到ProxySQL的代理地址String url = "jdbc:mysql://yourProxySQLIP:yourProxySQLPort/qbms?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8" +"&zeroDateTimeBehavior=CONVERT_TO_NULL";Connection con = DriverManager.getConnection(url, "yourUserName", "yourPassword");String sql = "insert into test_1(id,dt1,dt2) values(?,?,?)";PreparedStatement pst = con.prepareStatement(sql);pst.setInt(1, 4);//datetime(3)类型字段pst.setTimestamp(2, new Timestamp(System.currentTimeMillis()));//timestamp(3)类型字段pst.setTimestamp(3, new Timestamp(System.currentTimeMillis()));int rows = pst.executeUpdate();System.err.println(rows);pst.close();con.close();

MyBatis影射,查询影射:

<resultMap id="BaseResultMap" type="com.bijian.sc.qbms.api.domain.bbb.StrokeV2"><id column="id" jdbcType="VARCHAR" property="id"/><result column="ts" jdbcType="TIMESTAMP" property="ts"/></resultMap>

写入,可选的指定类型:

问题原因

国外参考地址:

MySQL8官网相关说明:

默认情况下,ProxySQL设置连接的mysql版本为5.5。而mysql5.5默认不支持保存毫秒,所以,在ProxySQL的C语言程序MySQL_Protocol.cpp 处理时,删除了毫秒值:

只需要将正确的被代理的mysql版本号,配置到ProxySQL的全局变量中,并生效即可。

标签: #mysql当前毫秒