深入理解MySQL数据库各种锁(总结)

MyISAM和InnoDB这俩存储引擎用锁的方式不一样。

InnoDB啊,它用的是行级锁。
意思就是精确到某一行去加锁。
这个锁啊, granularity很小。
所以你加个意向锁,这锁是表级的,但不会碍事。
比如你全表扫描,那意向锁就不管用了。
表级锁和行级锁这样,表级意向锁跟行级锁不冲突。

行锁有三种算法:记录锁,间隙锁,临键锁。
间隙锁有意思,它不锁具体值,锁的是值之间的间隔。
比如你插入个1 0,间隙锁会锁住(9 ,1 1 )这个范围。
不管1 0存在不存在,插入操作都要等。

共享锁就是读锁,多个事务可以同时持有。
排他锁就是写锁,写的时候别人不能读也不能写。
这个图里画的挺好:https://www.cnblogs.com/mysql-hang/articles/1 1 02 7 6 8 5 .
乐观锁呢,它就天真的多。
觉得别人不会改数据。
每次拿数据都当别人没动过。
所以读的时候不加锁。
写的时候才看,期间别人有没有改。
改了就重试。
这种适合读多写少的场景。
实现方式有:关闭自动提交,手动开事务。
这样一操作,就自动加锁了。
这就是悲观锁。
悲观锁就爱担心,觉得别人肯定要改。
所以查完数据立马加排他锁。
等你commit了,锁才释放。
这锁啊,就是排它锁。

MySQL 默认隔离级别是RR,为什么阿里等大厂会改成RC?

RR和RC核心区别在锁机制。
RR用Next-KeyLock,RC用RecordLock。

RR锁范围大。
RC锁粒度细。

RC锁冲突少。
RR锁等待多。

阿里双十一选RC。
5 8 .3 万笔每秒没问题。

RC死锁概率低。
RR容易死锁。

RC用ROW或MIXED binlog。
RR也行,但ROW是主流。

幻读问题不用管。
多数业务不敏感。

技术成熟了。
ROW好用多了。

大厂选RC为了啥?性能好,死锁少。

牺牲点隔离性。
换高并发和稳定。

怎么调优?业务特点决定取舍。

MySQL数据库的三级封锁实现原理简述mysql三级封锁

说白了,MySQL的三级封锁就是用共享锁和排它锁管住数据,防止别人乱改。
这事儿复杂在InnoDB存储引擎的实现细节上。

先说最重要的,共享锁(S锁)是多个读操作能同时进行,但排它锁(X锁)会独占数据,连读都不行。
去年我们跑那个电商系统时,库存表用共享锁,结果并发改价时死锁了——用行锁时,一个线程改A商品,另一个改B商品,居然互相卡着。
另外一点,InnoDB用MVCC技术实现快照读,所以读操作很多时根本不用锁,直接用快照就行,这个点很多人没注意。
还有个细节挺关键的,比如"SELECT FROM table WHERE id='1 ' LOCK IN SHARE MODE"这行代码,它会锁定整行数据,但别的事务还能读别的行。
我一开始也以为锁表是锁定整个表,后来发现不对。

等等,还有个事,隔离级别影响锁行为,比如可重复读(REPEATABLE READ)会隐式加锁,用起来要小心。
记住,高并发场景尽量用MVCC读,直接查快照比锁数据省事。

建议:别在热点数据上加锁,除非必要。
想试的话,先在测试环境看下加锁对QPS的影响。