mysql线上bug的缩小版demo演练
2022/1/15 2:03:43
本文主要是介绍mysql线上bug的缩小版demo演练,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
CREATE TABLE`TB_TEST` (`Id`bigint(20) unsigned NOT NULL COMMENT'Id',
`UserId`bigint(20) NOT NULL DEFAULT'0'COMMENT'用戶id',`OrderId`bigint(20) NOT NULL DEFAULT'0'COMMENT'订单号',
PRIMARY KEY (`Id`),KEY`idx_user_order` (`UserId`,`OrderId`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Test'
insert into TB_TEST values(1,1,1);
insert into TB_TEST values(2,10,10);
insert into TB_TEST values(3,10,15);
insert into TB_TEST values(4,15,20);
线程1:begin 但是不commit
delete from TB_TEST where UserId = 10 and OrderId = 10;
线程2:begin 但是不commit
delete from TB_TEST where UserId = 10 and OrderId = 15;
线程1:执行
insert into TB_TEST values(5,10,12); 这个时候这个线程会等待
线程2:执行
insert into TB_TEST values(6,10,13);这个时候会出现死锁的现象
select * from information_schema.INNODB_TRX
出现死锁的原因是
如果一条sql用到了主键索引(mysql主键自带索引),mysql会锁住主键索引;
如果一条sql操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引.
解决方法
这个地方,代码的问题需要根据情况自己去修改,可以试着把索引去掉(有风险),或者在进行update的时候尽量避开非主键索引,我这里记录一下被锁后应该怎么去解决的方法,首先先用sql查询一下mysql的事务处理表
正常情况下的状态都是RUNNING,但是在被锁之后就会变成LOCK WAIT ,一旦出现这种情况,就得杀死这个进程,如果进程杀不死就只能重启Mysql服务了
杀死进程
经验教训
无论前台后台的程序,都不应该存在仅根据非主键的几个字段一查就要update/delete的场景。即使有,也应该改为先把要更新的记录查出来然后逐条按主键id更新。
这篇关于mysql线上bug的缩小版demo演练的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16MySQL资料:新手入门教程
- 2024-11-16MySQL资料:新手入门教程
- 2024-11-15MySQL教程:初学者必备的MySQL数据库入门指南
- 2024-11-15MySQL教程:初学者必看的MySQL入门指南
- 2024-11-04部署MySQL集群项目实战:新手入门教程
- 2024-11-04如何部署MySQL集群资料:新手入门指南
- 2024-11-02MySQL集群项目实战:新手入门指南
- 2024-11-02初学者指南:部署MySQL集群资料
- 2024-11-01部署MySQL集群教程:新手入门指南
- 2024-11-01如何部署MySQL集群:新手入门教程