mysql数据库锁MDL锁的解释

我们系统中有一张表,查询概率非常高。
最近需要给这个表添加一个字段。
但在添加字段时,发现系统中有几家公司出现操作超时的情况。
那么原因是什么呢?查资料发现这是数据库的MDL+事务锁导致的。

MDL锁是表级元数据锁。
表级锁分为数据锁和元数据锁。
通常当我们谈论锁定时,我们通常指的是添加的数据锁。
和数据锁一样,元数据锁也分为读锁和读写锁。

MDL不需要显式使用,在表操作时会自动添加。
当表增删改查时,自动加MDL读锁;当修改表结构增减字段时,会自动加上MDL写锁。

MDL锁的存在其实是为保证数据的一致性。
想象一下,如果没有MDL锁,当一个查询迭代表数据时,另一个线程执行ALTERTABLEtDELETECOLUMN'col_1'来删除列col_1。
如果结果中包含该列数据,那么查询结果就会出现偏差。

:表示正常执行。

:表示被阻塞,即无法进一步执行。

步骤12正常执行。
执行步骤2时,会请求客户表MDL的SHARED_READ锁。

第4步也会保持阻塞状态,因为EXCLUSIVE锁和SHARE_READ锁是互斥的,并且EXCLUSIVE锁的优先级更高,所以第4步也会保持阻塞状态。

第五步:提交事务并释放表上的SHARE_READ锁。
然后可以执行操作6和7。

如果先运行事务二,然后运行事务三,则会成功,因为alterdataddl语句与things无关。

因此,我们在开发过程中,需要避免大事务操作,防止锁持有时间过长。

避免使用的MySQL字段mysql不能使用的字段

MySQL需要避免的字段MySQL是一种广泛使用的关系数据库管理系统,提供了大量的功能和特性来满足不同的应用需求。
虽然MySQL很强大,但是我们在使用它的时候还是需要注意一些字段。
这些字段在MySQL中会带来一些问题,并且会在实际应用中引起问题,因此应该避免使用。
1、自增ID自增ID是MySQL中非常常见的字段类型,它是使用AUTO_INCRMENT关键字来实现的。
虽然自动增长ID非常方便,但也存在一些问题。
如果您在多台服务器上运行MySQL,则可能会与自动增长的ID发生冲突。
而且当有大量插入操作时,自动增加ID很容易导致表锁和性能问题。
因此,如果可能的话,最好使用其他字段而不是自增ID。
2.TIMESTAMP将时间戳存储为TIMESTAMP字段也很常见,但这也存在一些问题。
TIMESTAMP字段只能存储从1970年到2038年的时间戳。
这意味着如果我们的应用程序需要存储更早或更晚的时间戳,我们必须使用其他字段类型。
此外,如果多个TIMESTAMP字段存储在同一个表中,这可能会导致性能问题,因为它们将同时更新,从而导致表锁定。
3.TEXT和BLOB类型TEXT和BLOB类型用于存储大文本和二进制数据。
然而,这些字段很容易导致性能问题,因为它们消耗大量内存和CPU。
此外,如果这些字段用于索引或序,则需要额外的操作来处理它们。
因此,如果可能,应避免使用TEXT和BLOB类型。
4.ENUM类型ENUM类型用于关联一个字段中的多个值。
然而,这也会导致一些问题。
如果我们需要添加或删除ENUM值,我们需要修改原始表。
并且在执行查询操作时,ENUM类型需要额外的操作来检查每个值。
因此,如果可能的话,应避免使用ENUM类型。
针对上述问题,我们可以采用以下解决方案:1.选择适合分布式环境的ID生成策略,例如使用Twitter的Snowflake算法或UUID。
2.对于需要存储较早或较晚时间戳的应用程序,可以使用DATETIME或DATE字段类型。
3.对于大文本或二进制数据,可以将它们存储在单独的表中,并使用外键进行管理。
4.如果需要关联多个值,则必须创建额外的关联表,而不是使用ENUM类型。
综上所,MySQL虽然很强大,但是在使用的时候我们还是需要注意某些字段类型,以免出现意想不到的问题。
通过避免使用上述MySQL字段类型,可以提高应用程序的性能和稳定性,从而在应用程序开发中发挥重要作用。

mysql解决可提交读、可重复读、幻读

我认为这张图很好地概括了这一点。
一般的互联网项目中,基本都会使用Innodb引擎,通常只涉及到行级锁。
但如果在没有索引的情况下执行SQL语句,可能会导致表锁,不建议这样做。
性能非常低,可能会导致全表扫描等。
行锁的具体实现算法有以下几种MySQL特有的锁:RecordLock:锁定单行记录,通常是唯一索引或主键GapLock(锁定区间):锁定一个区间,但不包括其本身。
对于开放间隔锁,只有RR级别才会有间隔锁。
间隔锁的唯一目的是防止间隔数据被插入,因此间隔锁。
GapLocksNext-不会锁定的keyLock:与GapLock的区别在于它包含自身,并且是一个左侧打开、右侧闭合的间隙。
只有RR级别有锁定规则。
两个“原则”,两个“优化”,一个“bug”。
原理一:上锁的基本单位是下面的钥匙锁。
希望大家还记得下面的钥匙锁是前开后关的区间。
原则2:只有在搜索过程中可访问的对象才会被锁定。
优化一:对于索引等价查询,锁定唯一索引时,next-keylock退化为行锁。
优化2:对于索引的等价查询,当向右移动且最后一个值不满足相等条件时,下一个锁退化为空间锁。
一个错误:对唯一索引的范围查询将访问第一个不满足条件的值。
举例说明上述原理:创建表并插入数据:INSERTINTOt(id,c,d)VALUES(0,0,0);INSERTINTOt(id,c,d)VALUES(5,5,10);INSERTINTOt(id,c,d)VALUES(10,10,10);INSERTINTOt(id,c,d)VALUES(15,15,15);INSERTINTOt(id,c,d)VALUES(20,20,20);INSERTINTOt(id,c,d)VALUES(25,25,25);示例1:锁定表由于字段d没有建立索引,因此涉及该字段的查询将被锁定。
锁全表,因为d字段没有索引,所以执行事务1会导致全表被锁,后续所有操作都会等待整个表的锁被释放。
示例2:主键/。
索引记录锁的唯一ID字段是主键。
此外,事务1的查询命中了唯一的记录。
默认添加Next-keyLock,间隔为(0,5)。
但根据优化1,只能记录。
被寻求。
对索引/主键的等效查询将退化为行锁,因此只有记录5将被锁定。
示例3:由于表t中没有id=7的记录,因此锁定主键/唯一索引上的空格。
,我们使用上面的方法。
如果判断锁定规则:根据原则1,锁定单元为下一个keylock,事务1的锁定范围为(5,10];同时,根据优化2.,这就是等价的query(id=7)和id=10不满足查询条件,Next-keylock退化为空格锁,所以最终锁定的范围为(5,10),SO。
交易2将被阻止。
交易3将成功执行。
例4:普通索引上的字段间隙锁c是普通索引。
事务1执行时,默认在区间(0.5]上加间隙锁,根据优化。
2,非唯一索引/主键会继续向右移动,找到10,所以最终的锁是(0,5]的Next-Key锁+(5,10)的间隙锁,所以事务2阻塞,事务3成功。
示例5:Next锁间隔-Keyby事务1的间隔锁和行锁默认是(0,5),根据优化2它会向右遍历,找到10个不符合查询条件的就退出,变成间隙锁,所以事务1的锁是。
(0,5]的Next-Key锁+(5,10)的间隙锁。
这两个锁与间隙锁冲突。
行锁,而事务2请求的Next-Keylock锁和事务1是一样的,但是c=5的行锁和事务1冲突,所以如果在updatetsetd=1000wherec=6char中更改就会出现死锁;此时产生的间隙锁为(5,10),间隙锁与间隙锁不冲突,不会造成死锁。
例6:共享锁锁覆盖索引事务1有覆盖索引,不会返回。
这种情况下lockinsharemode只会锁段c的索引,而事务2则为主键加了行锁,所以两者不存在冲突。
例7:当主键/唯一索引的范围查询开始执行时,需要找到id=10的第一行,所以应该是Next-KeyLock(5,10]。
根据优化1,等价主键id条件上的值,退化为行锁,仅添加id=10的行的行锁,直到行。
发现id=15,所以必须加上Next-KeyLock(10,15],这样事务3就冲突了。
例8:在普通索引上,范围查询开始执行时,找到第一行符合条件的10并加锁Next-KeyLock(5,10)由于不是唯一索引,因此不会降级,稍后继续搜索并在找到行时停止。
15,所以应该加上Next-KeyLock(10,15],因为是范围查询,所以锁不会降级。
快照读:通过MVCC实现,该技术不仅可以保证innodb的可重复读取,还可以并且可以防止鬼读,但是虽然读取到的数据是一致的,但是数据都是历史数据。
简单的select操作(不包括select...lockinsharemode、select...forupdate)当前读:为了保证数据的一致性,同时读到的数据是最新的数据。
InnoDB提供了以下锁定,它是通过空间锁定和行锁定相结合来实现的。
lect...lockinsharemodeselect...forupdateinsertupdatedelete自己理解:简单的select就是快照读,快照读实现可验证读,可重复读和幽灵读通过MVCC+ReadView实现,当前读实现通过中序锁实现。
为了说明具体原理,下面介绍一下MVCC和ReadView的概述。
读,所以简单的选择是通过乐观锁实现的,读目前是通过悲观锁实现的:https://www.sohu.com/a/302045871_411876https://www.jianshu.com/p/d1aba64b5c03https。
.://www.jianshu.com/p/32904ee07e56