mysql 写入阻塞_SQL 优化之数据库写入堵塞的紧急解决方案

博客讲述了在用户登录时,由于大量用户同时访问push.bind API,导致`user_bind_push`表操作堵塞。问题源于`push_id`字段未建立索引,从而影响服务响应。为解决此问题,采取临时措施将SQL操作写入文件,等待请求完成后再执行,确保服务正常且不丢失数据。此外,建议在框架层面实现类似紧急任务的处理机制,以备不时之需。
摘要由CSDN通过智能技术生成

业务场景还是关于推送的,推送是针对我们自己的系统用户,所以需要一张表user_bind_push来绑定用户id和SDK里的唯一标识token。在用户登录的时候会访问一个push.bind的api接口,在该接口中会先删除和该手机设备里的token绑定的数据,然后绑定目前登录的用户id和推送SDK里面的token。

$sql = "DELETE FROM `user_bind_push` WHERE `push_id` = '{$token}'";

M()->execute($sql);

$sql = "INSERT INTO `user_bind_push` SET `uid`={$uid}, `push_type`={$push_type}, `push_id`={$push_id}, `device`='{$device}', `app_version`={$appVersion}, `build`='{$build}',`channel`='{$channel}'";

M()->execute($sql);

之前三个月一直运行的好好的,但是前几天由于做了一次广播推送,这样一时间同时登录的用户就多了。导致访问该接口却无法获取返回值。

打开数据库通过show processlist发现对该表的操作就出现堵塞了,已经有900多条。

是什么导致了这个问题呢?原来是push_id没有加入到索引(低级错误)。

这个时候为了防止出现数据库出现异常情况,就立即将该api里的两次SQL的执行给注释掉了,而是写入文件,等之前的请求都执行完了(也把索引给加上了),再把把代码恢复,并且将写入文件的SQL执行,既保证了服务的正常,也不会丢失数据。

$sql = "DELETE FROM `user_bind_push` WHERE `push_id` = '{$token}'";

//M()->execute($sql);

file_put_contents('todo.sql',$sql.";\n",FILE_APPEND);

$sql = "INSERT INTO `user_bind_push` SET `uid`={$uid}, `push_type`={$push_type}, `push_id`={$push_id}, `device`='{$device}', `app_version`={$appVersion}, `build`='{$build}',`channel`='{$channel}'";

//M()->execute($sql);

file_put_contents('todo.sql',$sql.";\n",FILE_APPEND);

其实我们应该在框架就应该把这种把SQL堵塞写入文件的紧急任务封装起来,发现问题了,方便立即切换。

我们的库一直还是一主多从,写入的压力都放在了主库上,但是发现在该表发生堵塞的时候,其他的有写操作的api对客户端提供的服务正常,比如留言等,在show processlist看到有堵塞只是user_bind_push这一张表的,并没有影响到其他表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值