记一次Mysql更新问题的排查

表结构如下:

mysql> desc daily_change;
+------------+---------------------+------+-----+---------------------+----------------+
| Field      | Type                | Null | Key | Default             | Extra          |
+------------+---------------------+------+-----+---------------------+----------------+
| dc_id      | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| date       | date                | NO   | MUL | NULL                |                |
| today      | decimal(20,8)       | NO   |     | NULL                |                |
| yesterday  | decimal(20,8)       | NO   |     | NULL                |                |
| diff       | decimal(20,8)       | NO   |     | NULL                |                |
| diff_rate  | decimal(2,2)        | NO   |     | NULL                |                |
| dc_created | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| dc_updated | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
+------------+---------------------+------+-----+---------------------+----------------+

现象:
脚本会计算每天的统计情况,计算每天的使用量、昨日的使用、差值和波动比例,然后写到表里。
测试过程中,发现表里记录的diff_rate和更新语句里的diff_rate不一致。
好多记录的diff_rate都是0.99或-0.99,与实际值不一致;有一些记录的值又是对的。

一开始怀疑是不是有其他脚本有更新逻辑,查了下binlog日志,没找到其他更新请求。

在mysql命令行里做了如下测试。

update daily_change set diff_rate = 0 where dc_id = 1;
select * from daily_change where dc_id = 1; // diff_rate变成了0
update dail_change set diff_rate = 3.52 where dc_id = 1;
select * from daily_change where dc_id = 1; // diff_rate变成了0.99

这真是见鬼了,看来不是有其他脚本更新,我的更新sql是没问题的,看来是mysql自己的问题。

看了下diff_rate字段的类型,decimal(2,2)。

decimal(a,b)

参数说明

a指定指定小数点左边和右边可以存储的十进制数字的最大个数,最大精度38。
b指定小数点右边可以存储的十进制数字的最大个数。小数位数必须是从 0 到 a之间的值。默认小数位数是 0。

一下明了了,字段类型导致的锅。
改成decimal(20,2)之后,一切正常。

标签: mysql

添加新评论