记一次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)之后,一切正常。