MYSQL 根据唯一索引键更新死锁问题

mysql 死锁问题及死锁权重分析

问题发生过程:
1、生产发现死锁一次

语句为sql1:UPDATE table set data = '123' where business_no = 'ABC';

该行数据的id=1, business_no = 'ABC'

tablbe 字段

id:主键 business_no为唯一索引字段,其他字段暂时无意义

2、查找发生死锁问题原因

上述sql在一个事务内,死锁必定有两把锁。

最开始对锁的理解就是锁主键、不清楚是否有其他锁参与。

网上搜索发现update的where条件为唯一索引时候,sql会同时获取两把锁,先获取唯一索引business_no的锁,再获取主键id的锁,所以必定同一时刻有先获取id锁,再获取唯一主键锁的sql。

查找代码返现同一时刻,另外一个事务2执行了以下sql

sql2:UPDATE table set data = '123' where id = 1;

sql3:UPDATE table set data = '123' where business_no = 'ABC';

现在发现了死锁原因:

但是现象不复核预期

sql 1 先唯一键锁、后 主键锁

sql2 先主键锁 、sql3后唯一键锁

理论是sql1 和 sql3 都有可能发生死锁,因为sq1在一个sql内,sql2、slq3是分开的,

按预期sql3发生死锁错误的概率最大,但是代码发生了8次死锁全部是sql1发生了死锁。

3、为啥sql1发生死锁

第一步怀疑有其他sql参与了,但是没找到疑点sql。

网上搜索发现了一个死锁权重的概念。

大概意思是发生死锁根据算法确定权重,权重小的事务会回滚。

感觉问题快找到了,猜想sql1事务内只有一个事务(他基本就是小权重的事务)。

那接下来分析日志验证:

事务2还执行了以下sql。

sql4:UPDATE table2 set data2 = '123' where id = 1;

在sql2和sql3之前还有sql4。

那猜测有事务4 中sql5 UPDATE table2 set data2 = '345' where id = 1;

让后搜索日志发现同一时间有有sql5。

接下来实际验证:

开启事务1:

执行:sql2:UPDATE table set data = '123' where id = 1;

执行sql4:UPDATE table2 set data2 = '123' where id = 1;

开启事务2:

执行slq1:UPDATE table set data = '123' where business_no = 'ABC';

开启事务3:

执行sql5:UPDATE table2 set data2 = '345' where id = 1;

事务1:

执行slq3:UPDATE table set data = '123' where business_no = 'ABC';

发现必sql1必死锁异常且回滚,问题解决。

4、问题总结

msql行级锁加锁的过程。

mysql发生死锁回滚的机制。

相关推荐
仲芒7 分钟前
[24年单独笔记] MySQL 引擎架构
笔记·mysql·架构
ChatInfo12 分钟前
Etsy 把 1000 个 MySQL 分片迁进 Vitess:425TB 数据背后的真正问题不是性能,而是运维规模
数据库·人工智能·mysql
SPC的存折36 分钟前
6、MySQL设置TLS加密访问
linux·运维·服务器·数据库·mysql
老苏畅谈运维36 分钟前
DBA分析 ORA 报错的利器,errorstack让 Oracle 错误现原形
数据库·oracle·dba
紫青宝剑1 小时前
向量数据库 Milvus
数据库·milvus
雪碧聊技术1 小时前
数据库系统基础知识
数据库
Elastic 中国社区官方博客1 小时前
如何使用 LogsDB 降低 Elasticsearch 日志存储成本
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索·可用性测试
Dreamboat-L1 小时前
HBase远程访问配置(详细教程)
大数据·数据库·hbase
刘~浪地球1 小时前
数据库与缓存--Redis 集群架构与优化
数据库·redis·缓存
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.1 小时前
MySQL 主从架构中的使用技巧及优化
android·mysql·架构