锁的分类 乐观锁(S):读锁又叫共享锁,允许其他事物读不允许写 1 2 3 4 mysql8版本 SELECT * FROM USER FOR SHARE mysql8之前的版本 SELECT * FROM USER lock in share mode 悲观锁(X):写锁又叫排他锁,不允许
锁的分类乐观锁(S):读锁又叫共享锁,允许其他事物读不允许写
悲观锁(X):写锁又叫排他锁,不允许其他事物读和写
共享锁和共享锁之间不阻塞,共享锁和排他锁之间阻塞,排他锁和排他锁之间阻塞。 表锁:对表进行加锁,颗粒度大效率高并发低;MYISAM只有表锁 页锁:DBD引擎独有的。 行锁:InnoDB特有的,锁的是索引并不是行数据本身(索引项),当操作数据(update/delete)不是索引的时候,RR模式下会升级为表锁,RC不会升级; 意向锁:InnoDB引擎为了提高判断效率,对数据行加锁(锁的是索引那里)的时候引入了意向锁的概念
间隙锁(Gap Look):对操作的区间加一个开区间锁,RR隔离级别独有的,解决了幻读的问题 临键锁(Next-key Look):间隙锁+行锁组成的一个闭区间, 锁相关命令
关于RR级别行锁升级为表锁的原因? 在RR隔离界级别下,为了防止出现不可重复读和幻读情况,在遍历聚集索引的时候,为了防止其他事物操作数据(不可重复读)和间隙被插入问题(幻读),导致数据不一致,因此会在所有扫描到的索引记录和间隙加上锁。 这并不是对整张表加锁,而是精确地对命中范围内的记录和间隙加锁。当然,如果部分记录已被其他事务加锁,也可能导致当前事务出现等待或死锁。 MYISM和InnDB在锁上的区别MYISM在select的时候加表读锁,inster,update,delete的时候加表写锁; InnoDB在执行select(非串行化隔离级别)的时候不加锁,在inster,update,delete的时候加行锁; 虽然在锁的性能开销上行锁更大, 但是整体使用上效率远远高于MYISM的表锁,也要使用得当,否则会出现死锁现象反而降低性能 锁等待分析
对对应的状态进行分析,对于等待长次数高的,需要分析为什么会有这么多等待,然后优化。 查看近期的死锁日志:show engine innodb status;
实际开发中注意事项减少锁的范围颗粒度 降低事物隔离级别 进来用索引,防止锁升级 控制事物大小,设计锁资源的最后执行 MVCC(Multi-Version Concurrency Contorl)多版本并发控制对同一行数据有不同的版本控制,可重复读和读已提交都是通过MVCC实现的; undolog版本链和read view(一致性视图)机制: 不同事物会开启不同的版本链,在隐藏字段trx_id中存储,回滚标记roll_pointer,RR级别下,开启事物会生成 read view,后续操作不会改变(RC每次都生成新的read view); 这个read view是有,当前未提交的事物trx_id数组(数组里id最小的为min_id),和已创建的最大的事物trx_id(max_id)组成,任何事物查询都需要从版本链里最新数据逐一和read view对比从而获得最终的快照数据;
比对规则:
若X<=trx_id>=Y,分为两种情况:
删除数据其实是update的一种特情况,首先会从版本链复制一份最新的,然后trx_id改成删除的trx_id,同时该记录的头信息标记delete_flag写成true,后续查询不返回; 注意: begin/start transaction不是事物的起点,当执行修改操作或者排他锁的时候才会事物申请一个真正的事物id。 |
2021-06-02
2021-06-05
2022-06-27
2024-07-31
2024-02-19