Mysql锁机制总结

按锁的粒度可以分为全局锁、表级锁、行锁、间隙锁、临键锁

按锁的属性可以分为共享锁、排他锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qgZhziKP-1683457767173)(images/image-20230209024448188.png)]

全局锁

  • 加全局读锁的命令:Flush tables with read lock (FTWRL)
  • 此命令会使整个库处于只读状态
  • 使用场景:做全库逻辑备份

表级锁(MyISAM 默认)

  • 表锁语法是lock tables xxx read/write,用
  • 元数据锁(表的结构、字段、数据类型、索引等)(metadata lock,MDL),由server层实现,不需要显示的加,增删改查会加mdl读锁,对表结构进行变更时会加mdl写锁,读读不互斥,读写、写写互斥。

行级锁(InnoDB 默认)

  • 共享锁(Share Lock即S Lock,读锁、S锁): 一个事务对一个数据对象加了S锁,可以对这个数据对象进 行读取操作,但不能进行更新操作。并且在加锁期间其他事务只能对这个数据对象加S锁,不能加X锁。
SELECT * FROM t WHERE ... LOCK IN SHARE MODE 
  • 排他锁(eXclusive Lock即X Lock,写锁,X锁): 一个事务对一个数据对象加了X锁,可以对这个对象进行 读取和更新操作,加锁期间,其他事务不能对该数据对象进行加X锁或S锁。
SELECT * FROM t WHERE ... FOR UPDATE

默认情况下innodb用的是隐式加锁。Innodb存储引擎在执行update、delete、insert语句时会隐式加排它锁,而对于select不会加任何锁。

意向共享锁 IS/意向排他锁 IX

  • 意向共享锁 IS/意向排他锁 IX 属于表锁,取得意向共享锁/意向排他锁是取得共享锁/排他锁的前置条件。

  • InnoDB行锁是给索引项加锁来实现的。这样的实现方式意味着当一个事务对表的某一行加锁后,后面的每个需要对该表加持表锁的事务都需要遍历整个索引树才能知道自己是否能够进行加锁,这样就会很浪费时间和损耗数据库性能。

  • 于是有了意向锁(Intention locks)的概念:如果当事务A加锁成功之后就设置一个状态告诉后面的人,已经有人对表里的行加了一个排他锁了,你们不能对整个表加共享锁或排它锁了,那么后面需要对整个表加锁的人只需要获取这个状态就知道自己是不是可以对表加锁,避免了对整个索引树的每个节点扫描是否加锁,而这个状态就是我们的意向锁。

间隙锁和临键锁

间隙锁(Gap lock):间隙锁是在事务加锁后其锁住的是表记录的某一个区间(开区间),当表的相邻ID之间出现空隙则会形成一个区间,比如表里面的数据id 为 1,7,10 ,那么会形成以下几个间隙区间,(负无穷,1),(1,7),(7,10),(10,正无穷)。

  • 作用:用于阻止其他事务在该间隙内插入新记录,而自身事务是允许在该间隙内插入数据的,防止幻读问题。
  • 触发条件: 查询条件必须命中索引,范围查询,或者等值查询未命中记录(若命中,则会升级为行锁)。间隙锁只会出现在REPEATABLE_READ(重复读)的事务级别中。在RU和RC隔离级别下没有间隙锁。

临键锁(Next-Key Lock):临键锁是行锁+间隙锁,即临键锁是是一个左开右闭的区间,比如(3,5]。

  • InnoDB在RR隔离级别下,如果你使用select … in share mode或者select … for update语句,那么InnoDB会使用临键锁,因而可以防止幻读;但即使你的隔离级别是RR,如果你这是使用普通的select语句,那么InnoDB将是快照读,不会使用任何锁,因而还是无法防止幻读

数据库乐观锁和悲观锁

  • 乐观锁实现:在表中设计一个版本字段 version,第一次读的时候,会获取 version 字段的取值。然后对数据进行更新或删除操作时,会执行UPDATE … SET version=version+1 WHERE version=version。此时如果已经有事务对这条数据进行了更改,修改就不会成功。

  • 悲观锁实现:

数据库死锁

数据库的死锁:两个或多个事务在同一资源上相互占用,并请求锁定对方的资源。

场景:

  • 事务1:UPDATE T SET xxx WHERE ID = 1; UPDATE T SET xxx WHERE ID = 2;
  • 事务2:UPDATE T SET xxx WHERE ID = 2; UPDATE T SET xxx WHERE ID = 1;

预防死锁

  • 不同程序尽量约定以相同的顺序访问表
  • 在同一个事务中,尽可能做到一次锁定所需要的所有资源
  • 在事务中,如果要更新记录,应该申请足够级别的锁,比如排他锁。

解决死锁

  • 一般InnoDB会自动检测到,使一个事务回滚,另一个事务继续;
  • 设置超时等待参数innbdb_lock_wait_timeout
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Mysql锁机制是用来处理并发访问数据库时的问题,特别是在使用InnoDB引擎支持事务的情况下。锁机制可以按照锁的粒度分为表级锁和行级锁。表级锁是对整张表进行加锁,实现简单,消耗的资源较少,加锁快速,不容易出现死锁。而行级锁则是对当前操作的行进行加锁,锁定粒度更小,可以提高并发性,但加锁的代价较高。 MySQL的InnoDB存储引擎默认的事务隔离级别是RR(可重复读),这是通过行级锁和多版本并发控制(MVCC)一起实现的。在正常读取数据时,不会加锁,而在写入数据时才会进行加锁操作。 MVCC是通过一些技术实现的,包括隐藏字段、Read View和Undo log。隐藏字段用于存储数据版本信息,Read View用于控制事务的隔离级别,而Undo log则用于记录事务对数据的修改操作,以便在需要回滚时进行恢复。 总结起来,Mysql锁机制包括表级锁和行级锁,用于处理并发访问数据库时的问题。而MVCC则是InnoDB存储引擎实现事务隔离级别的一种机制,通过隐藏字段、Read View和Undo log来实现数据的一致性和并发控制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Mysql锁机制+MVCC](https://blog.csdn.net/qq_45901741/article/details/120245265)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [MySQL之锁和事务](https://download.csdn.net/download/weixin_38739919/13683140)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [mysql锁机制和mvcc](https://blog.csdn.net/u014618114/article/details/115534734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Guanam_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值