[{"createTime":1735734952000,"id":1,"img":"hwy_ms_500_252.jpeg","link":"https://activity.huaweicloud.com/cps.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=201905","name":"华为云秒杀","status":9,"txt":"华为云38元秒杀","type":1,"updateTime":1735747411000,"userId":3},{"createTime":1736173885000,"id":2,"img":"txy_480_300.png","link":"https://cloud.tencent.com/act/cps/redirect?redirect=1077&cps_key=edb15096bfff75effaaa8c8bb66138bd&from=console","name":"腾讯云秒杀","status":9,"txt":"腾讯云限量秒杀","type":1,"updateTime":1736173885000,"userId":3},{"createTime":1736177492000,"id":3,"img":"aly_251_140.png","link":"https://www.aliyun.com/minisite/goods?userCode=pwp8kmv3","memo":"","name":"阿里云","status":9,"txt":"阿里云2折起","type":1,"updateTime":1736177492000,"userId":3},{"createTime":1735660800000,"id":4,"img":"vultr_560_300.png","link":"https://www.vultr.com/?ref=9603742-8H","name":"Vultr","status":9,"txt":"Vultr送$100","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":5,"img":"jdy_663_320.jpg","link":"https://3.cn/2ay1-e5t","name":"京东云","status":9,"txt":"京东云特惠专区","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":6,"img":"new_ads.png","link":"https://www.iodraw.com/ads","name":"发布广告","status":9,"txt":"发布广告","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":7,"img":"yun_910_50.png","link":"https://activity.huaweicloud.com/discount_area_v5/index.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=aXhpYW95YW5nOA===&utm_medium=cps&utm_campaign=201905","name":"底部","status":9,"txt":"高性能云服务器2折起","type":2,"updateTime":1735660800000,"userId":3}]
开发说查询一张表老是丢数据,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);
其实线程间的速度差距是很微小的,应该在微妙或者毫秒级别,一般是感觉不到这种差距的。