开发说查询一张表老是丢数据,sql是这样的:select * from CLICK where id >= xxx and id < xxx;

id是主键,自增字段。

经常丢失最大id附近的一些数据。

写个sql复现这种情况,select id from CLICK where id >= (select max(id)-100 from CLICK)
and id < (select max(id) from CLICK);

正常情况应该是会查到100条记录。但循环执行这个sql发现有时只能查到99条。找到那个丢失的id,select * from CLICK where
id=“丢失的id”;发现数据是正常的。

怀疑是不是表损坏了,check table后是正常的。

到底什么原因呢?

打开binlog看数据插入的情况,发现max(id)先于max(id)-1插入了,这是什么情况?仔细看binlog,原来这两个数据插入不是一个线程执行的。

这样大概能猜测到原因了:

线程1从计数器获得自增的max(id)(这儿假设是99),去插入数据。之后线程2从计数器获得max(id)(这儿应该是100),去像同一个表插入数据。

线程2的速度比线程1快,所以线程2先插入了id=100的数据,线程1还没有执行完。

这时去查询:select id from CLICK where id >= (select max(id)-100 from CLICK) and id
< (select max(id) from CLICK);

就会发现少了id=99的那条记录。

简单表示一下:

找到原因,那个开发的问题就很好解决了:select * from CLICK where id >= xxx and id < (select
max(id)-100 from CLICK);

其实线程间的速度差距是很微小的,应该在微妙或者毫秒级别,一般是感觉不到这种差距的。

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信