【MySQL 锁全解】:从行锁到死锁,一次讲透所有面试考点

【MySQL 锁全解】:从行锁到死锁,一次讲透所有面试考点 你好我是fengxin_rou这是我的个人主页fengxin_rou的主页❄️欢迎查看我的专栏我的专栏《Java后端学习》、《JAVASE基础》、《JUC并发》、《redis》、《JVM虚拟机》、《MYSQL》、《黑马点评》、《rabbitmq》、《JavaWebAI的talis学习系统》、《苍穹外卖》目录前言mysql里有哪些锁行锁什么时候变表锁临键锁怎么解决幻读什么是死锁产生条件、怎么排查和避免死锁死锁定义产生条件MySQL 排查死锁避免死锁总结前言通过专栏《MYSQL》前面的学习知道了事务和索引相关的知识现在我们进入锁学习的阶段mysql里有哪些锁在MYSQL里把锁分为三类全局锁、表锁、行级锁全局锁在使用了flush tables with read lock语句之后全库都会进入只读状态数据库执行增删改和修改表结构的操作时都会被阻塞主要用于在全表进行备份时防止其他事务修改表的数据表级锁表锁使用lock tables语句就会给表上锁限制其他线程访问这张表这里对线程有两种限制方式1.读锁 lock tables 表名 read本线程可读不能写其他线程可读不能写2.写锁 lock tables 表名 write本线程可读可写其他线程读写全都阻塞元数据锁对表上一个MDL锁如果是对表进行CRUD操作会对表上MDL读锁如果是修改表的结构就会对表上一个MDL写锁MDL锁的作用是防止线程在操作表时其他线程影响表的结构和数据意向锁当执行插入、更新、删除操作需要先对表加上「意向独占锁」然后对该记录加独占锁。意向锁用于确定这个表是否有行级锁两类意向锁意向共享 IS后续要加共享行锁(S锁)意向独占 IX后续要加独占行锁增删改都会触发、X锁行级锁InnoDB 引擎是支持行级锁的而 MyISAM 引擎并不支持行级锁。记录锁Record Lock分为S读锁和X写锁满足读写互斥和写写互斥已有锁加 S 锁加 X 锁S 锁允许阻塞X 锁阻塞阻塞间隙锁(Gap Lock)只存在于可重复读隔离级别是为了解决可重复读(RR)隔离级别下的幻读现象。临键锁(Next-key Lock)记录锁 间隙锁合体会锁定一个范围并锁定这个范围的数据InnoDB有哪些锁呢行级锁、表锁、意向锁行锁什么时候变表锁这里不是有一个升级阈值一样的规定所谓 “行锁变表锁”是看起来像锁表本质是锁了全表所有行 / 大范围间隙效果等价于表锁。InnoDB 行锁依托索引生效无索引 / 索引失效时会全表扫描行操作就会查询全表然后给所有行加锁效果等价于表锁临键锁怎么解决幻读因为临建锁 间隙锁 记录锁利用这两个锁的机制就可以大幅度的减少幻读的发生锁住查到的真实数据行记录锁 不让别人修改已有数据锁住数据前后的空白间隙间隙锁 区间内无法插入新记录范围查询会锁定一整个左开右闭区间 别的事务插不进区间空位自然不会凭空多出数据大幅规避幻读什么是死锁产生条件、怎么排查和避免死锁死锁定义两个事务互相持有对方的锁并且自身不会主动释放锁互相陷入等待的循环就是锁产生条件互斥性一把锁只有一个事务可以拿到请求并保持持有锁的同时去请求另一把锁不可剥夺锁不能被抢走只能主动释放循环等待A等B的锁B等A的锁MySQL 排查死锁查看最近死锁日志show engine innodb status;日志里看阻塞 SQL、持有锁、等待锁、事务执行顺序定位冲突语句避免死锁统一访问顺序所有事务按相同顺序操作表、操作行杜绝循环等待。缩小事务范围事务尽量短小尽早提交减少锁持有时间。合理使用索引保证更新语句走索引锁定行数越少锁冲突越少。避免事务内等待交互不要事务中途等待用户操作、接口调用防止长时间占锁。总结主要是了解了mysql里面所有的锁的定义行锁与表锁并不是字面意思上的转换而是效果上在全盘扫描时实现了锁全表的现象临键锁解决幻读从临键锁的组成来分为锁数据(记录锁)和锁数据前后的空白间隙间隙锁以及死锁的相关知识