Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MYSQL VS POLARDB 唯一索引死锁与应用设计

MYSQL VS POLARDB 唯一索引死锁与应用设计

作者头像
AustinDatabases
发布于 2022-05-19 01:01:07
发布于 2022-05-19 01:01:07
52700
代码可运行
举报
文章被收录于专栏:AustinDatabasesAustinDatabases
运行总次数:0
代码可运行

#issue 68021 MySQL unique check 问题 - 知乎 (zhihu.com)

事情的开始是这样的,最近和阿里云密切联系,也成为他们的大客户,(我们当然是大客户,BIG BIG BIG potato),也就和他们的核心的研发的同学有了密切的接触,这篇文字就是他们的顶尖人物写的关于MYSQL 唯一索引的问题的文字,也感谢他推送给我。

实际上在DBA 这个行业里面关于唯一索引的问题,一直是争论不休,但是对于开发本身,DBA 是缺乏说服力的,我们只能说,你这样做性能会受到损失, 当然这样说和 bull shit 也没有什么两样。

我们截取陈老师文字中关于伪代码的部分

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 find the B-tree page in the secondary index you want to insert the value to
     assert the B-tree page is latched
     equal-range = the range of records in the secondary index which conflict with your value 
     if(equal-range is not empty){
       release the latches on the B-tree and start a new mini-transaction
       for each record in equal-range
         lock gap before it, and the record itself (this is what LOCK_S does)
       also lock the gap after the last(equal-range)
       also (before Bug #32617942 was fixed) lock the record after last(equal-range)
       once you are done with all of the above, find the B-tree page again and latch it again
     }
     insert the record into the page and release the latch on the B-tree page.

我们直入主题,唯一索引在插入的时候

1 索引是有顺序的

2 唯一索引是有唯一性的

虽然我们使用的隔离级别是RC ,无论在MYSQL 还是POLARDB 是不会出现GAY LOCK,但是,但是 ,但是

你是唯一索引

我们需要确认的是

1 唯一索引在插入的时候会判断目前索引中是否有同样的值

2 插入时要避免同时有其他同样的值插入

3 插入时还要判断顺序,并且还要考虑插入时周围值的变动

基于这些考虑,锁必然是必不可少的。

我们来看这段伪代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
find the B-tree page in the secondary index you want to insert the value to
     assert the B-tree page is latched

第一步,找到你要插入数据的索引页面,并且给这个页面上 latch 锁

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
equal-range = the range of records in the secondary index which conflict with your value 
     if(equal-range is not empty){
       release the latches on the B-tree and start a new mini-transaction
       for each record in equal-range
         lock gap before it, and the record itself (this is what LOCK_S does)
       also lock the gap after the last(equal-range)
       also (before Bug #32617942 was fixed) lock the record after last(equal-range)
       once you are done with all of the above, find the B-tree page again and latch it again
     }

第二部是一个具有原子性的操作,

1 获取与你插入值有冲突的范围,(尤其对那些多个键值是唯一索引的情况)

2 如果你插入的键值的冲突范围并不为空

3 将撤销原有的栓锁,将锁的粒度变小

4 开始针对可能产生冲突的键值进行check (期间产生间隙锁) 2 如果没有冲突,数据插入到页面

在整个的操作过程中,是需要对插入的整体过程加GAP 锁,保证在判断后你插入数据前,不会有其他的数据插入到这个位置。

之所以是说后续,这里考虑的问题是多键值的唯一索引与单键值的索引,为什么要考虑这个问题,主要还是目前使用的 next-key lock 在位置索引中可能产生的范围的大小问题。

举例

在表设计时,我们可以对多列产生唯一索引,而根据上文中的描述,唯一的键值要插入到索引的情况下,是需要针对一段范围的数据进行锁定的,那么你的值越多,产生的范围会越大,导致出现死锁的概率就越大。

上文中从源代码的方面进行了阐述,如何对数据库的源代码进行改造,但使用者怎么办,如何去最大化的规避问题。

我们需要确认几点

1 数据插入索引是有序的

2 数据插入到唯一索引时尽量少进行上面范围的GAP LOCK

这里就基于范围的问题进行讨论,如何能在程序设计的基础上最大化的减小产生死锁的几率和范围。

如果有多个键值要进行唯一索引的处理时,需要通过HASH 算法(根据算法尽量避免由于HASH 算法导致的虽然值不同,但HASH 后值相同的可能性),通过将多个字段通过算法转换为 一个HASH 值,并且对这个HASH值的字段建立唯一索引。

这样的好处显而易见

1 降低上文中提到在MYSQL 或POLARDB 中唯一索引出现死锁的可能性

2 降低一个表上出现较大唯一索引的情况(一个表中包含索引的整体字节数是有限制的)

3 对应用友好和灵活,例如我今天是3个字段,明天可能是四个字段,那么实际上,产生这样的情况下,表的索引不必改动,改动的是应用程序中关于插入HASH 字段的算法中包含的字段的数量即可。否则你又会建立一个新的唯一索引。

其实数据库本身作为三大系统之一的系统,包容性应该是很高的,但基于数据库的对于数据的严谨性和逻辑性的问题,要求很高,导致使用数据库的过程中,需要对数据库本身的原理进行理解,尽量避免一些数据库本身无法在短时间满足的 性能 --- 功能 之间的矛盾,所以在设计应用程序时也应该有的放矢的进行有效设计。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入浅出MySQL 8.0 lock_sys锁相关优化
提示:公众号展示代码会自动折行,建议横屏阅读 「引言」 本文的目的是对 InnoDB 的锁模块做个简单的介绍,使读者对这块有初步的认识。 此外,我们在对MySQL 5.7做性能分析的时候发现lock_sys mutex成为热点瓶颈,官方在MySQL 8.0上对lock_sys锁也做了很多优化,本文针对一些重大的性能优化做一些介绍。 MySQL lock 与 latch区别(本文主要介绍lock) 「第一部分 简介」 1.1 lock相关数据结构
腾讯数据库技术
2021/03/09
2.4K0
原创|InnoDB事务锁系统及其实现
提示:公众号展示代码会自动折行,建议横屏阅读 「第一部分 前言」 InnoDB引擎支持行级别锁,实现了四种隔离级别,本文梳理了InnoDB事务系统及锁系统的原理和源码实现,并且对其中一些比较特别的feature做一个简单的介绍。 因为涉及的模块代码非常庞大,部分实现细节并未深入,如有错漏,欢迎指正。 在介绍InnoDB的事务系统和锁系统之前,有必要对一些基本概念做一个简单的回顾。 我们都知道事务的四大属性ACID,这些属性的保证与数据库中的几大模块紧密的耦合在一起: 为了保证原子性Atomicity,数据
腾讯数据库技术
2021/11/17
1.2K0
MYSQL基础知识和案例分享
· Mysql 5.1之前默认的存储引擎,支持包括全文索引、压缩、空间函数(GIS)等,不支持事务和行级锁。最大的缺陷是崩溃后无法安全恢复。
曲水流觞
2019/10/27
9760
MySQL大无语事件:一次生产环境的死锁事故,看看我怎么排查
今天要分享的是在生产环境中出现的一次算得上比较诡异的死锁事件, 不过庆幸的是没有产生较大的业务损失.
Java程序猿阿谷
2021/03/15
7.9K1
MySQL 中的 INSERT 是怎么加锁的?
来源:https://www.aneasystone.com/archives/2018/06/insert-locks-via-mysql-source-code.html
Java技术栈
2021/11/12
11.8K0
MySQL 死锁的详细分析方法
用数据库的时候,偶尔会出现死锁,针对我们的业务系统,出现死锁的直接结果就是系统卡顿、客户找事儿,所以我们也在想尽全力的消除掉数据库的死锁。出现死锁的时候,如果只是想解锁,用show full processlist看下kill掉就好了,如果想查找到详细的问题,一个办法是用show engine innodb status来查看简略信息或者开死锁日志,后期在MySQL日志里面慢慢分析。以上这写方法我们都用过,最近在看Innodb的书的时候发现另一种实时的分析方法,能最大限度的分析死锁的原因。
星哥玩云
2022/08/17
5630
死锁案例之四
一 前言 死锁,其实是一个很有意思也很有挑战的技术问题,大概每个DBA和部分开发同学都会在工作过程中遇见 。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。本文介绍一例三个并发insert 导致的死锁,根本原因还是在于insert 唯一键申请插入意向锁这个特殊的GAP锁。其实称呼插入意向锁 为 Insert Intention Gap Lock 更为合理。 二 案例分析 2.1 环境准备 Percona server 5.6 RR模式
用户1278550
2018/08/09
7920
【MySQL源码分析】浅谈Mysql的锁
MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。
桶哥
2019/06/04
2.5K0
【MySQL源码分析】浅谈Mysql的锁
MySQL的innoDB锁机制以及死锁处理
InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。行级锁与表级锁本来就有许多不同之处,innodb正常的select ID from table where id=1;不会上任何锁,接下来详细讨论InnoDB的锁问题;
星哥玩云
2022/08/16
1K0
MySQL的innoDB锁机制以及死锁处理
故障分析 | 从 Insert 并发死锁分析 Insert 加锁源码逻辑
即,死锁问题具有业务关联、机制复杂、类型多样等特点,导致当数据库发生死锁问题时,不是那么容易分析。
爱可生开源社区
2023/04/23
1.1K0
死锁案例之五
死锁其实是一个很有意思也很有挑战的技术问题,大概每个DBA和部分开发朋友都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。本文是源于生产过程中一个死锁案例。
用户1278550
2018/08/09
1.1K0
MySQL案例:insert死锁与唯一索引
死锁是每个 MySQL DBA 都经常会遇到的问题,之前也写过关于死锁的详细解析。多数时候死锁容易在 update 中发生,且一般是涉及到二级索引。而本次遇到的问题是发生在 insert 上的死锁,与常规的场景不太一样,因此单独拿出来分析一下。
王文安@DBA
2022/06/07
4.5K1
MySQL案例:insert死锁与唯一索引
死锁案例之三
一 前言 死锁其实是一个很有意思也很有挑战的技术问题,大概每个DBA和部分开发朋友都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。 二 背景知识 2.1 insert 锁机制 在分析死锁案例之前,我们先学习一下背景知识 insert 语句的加锁策略。我们先来看看官方定义:
用户1278550
2018/08/09
1.6K0
Mysql刨根:由Insert与uniqueKey的竞争引发死锁
通过前文《数据库温故:Mysql底层原理起底》我们已经学过了Mysql的事务隔离级别等基础知识,现在我们可以利用所学,来分析一下生产环境出现的死锁问题了。
后台技术汇
2023/09/25
7170
Mysql刨根:由Insert与uniqueKey的竞争引发死锁
MySQL知识体系(DS整理)
存储引擎(Storage Engine)是数据库管理系统中负责数据存储、检索和管理的核心组件,它决定了:
Him
2025/05/04
3230
死锁案例之七
死锁,其实是一个很有意思也很有挑战的技术问题,大概每个DBA和部分开发同学都会在工作过程中遇见 。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。
用户1278550
2018/08/09
5170
死锁案例之九
死锁,其实是一个很有意思也很有挑战的技术问题,大概每个DBA和部分开发同学都会在工作过程中遇见 。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。
用户1278550
2018/08/09
8170
MySQL 加锁和死锁解析
本文大多数都整理自《死锁-何登成 - 管中窥豹——MySQL(InnoDB)死锁分析之道》
星哥玩云
2022/08/18
1.1K0
MySQL 加锁和死锁解析
MySQL 死锁了,怎么办?
但是,实际上「插入意向锁」不是意向锁,而是特殊的间隙锁,属于行级锁,注意是「特殊」的间隙锁,并不是我们常说的间隙锁。
小林coding
2022/10/27
1.6K0
MySQL 死锁了,怎么办?
一文理解MySQL的锁机制与死锁排查
MySQL的并发控制是在数据安全性和并发处理能力之间的权衡,通过不同的锁策略来决定对系统开销和性能的影响。
全菜工程师小辉
2021/06/25
2.7K0
一文理解MySQL的锁机制与死锁排查
相关推荐
深入浅出MySQL 8.0 lock_sys锁相关优化
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档