MySQL锁机制:
锁是计算机协调多个进程或线程并发访问某一资源的机制
锁的分类:
- 按对数据的操作类型分类:读锁、写锁
- 按对数据操作的粒度分类:表锁、行锁
读锁(共享锁):针对同一份数据,多个读操作可以同时进行,而不会互相影响
写锁(排他锁):当前写操作没有完成前,它会阻断其它写锁和读锁
本章着重介绍行、表锁
表锁(偏读):偏向MyISAM存储引擎,开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低
手动增加表锁:
- lock table 表名字 read(write),表名字2 read(write),其它;
- 查看表上加过的锁:show open tables ;
- 释放表锁:unlock tables ;
简言之读锁会阻塞写,但不会阻塞读,而写锁会把读和写都阻塞 show status like‘table%’;
MyISAM的读写锁调度是写优先,这也是MyISAM不适合做写为主表的引擎,因为写锁后,其它线程就不能做任何操作,大量的更新会使查询很难得到锁,从而造成永久阻塞
行锁(偏写):偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度也最高
InnoDB与MyISAM的最大不同点:
- 支持事务
- 采用了行级锁
补充
索引失效,行锁会变表锁
无索引,行锁升级为表锁
间隙锁:
- 什么是间隙锁:当我们用范围条件,而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁,对于键值在条件范围内,但并不存在的记录,叫做“间隙(GAP)”
- 间隙锁的危害:因为query执行过程中,通过范围查找的话,它会锁定整个范围内所有的索引键值,即使这个键值并不存在,间隙锁有一个比较致命的弱点,就是当锁定一个范围键值以后,即使某些不存在的·键值也会被无辜锁定,造成在锁定时,无法插入锁定键值范围内的任何数据,在某些场景下这可能会对性能造成很大的伤害。
如何锁定一行:
begin;
select * from test_innodb_lock(表名) where a=8(行) for update;
commit ;
分析行锁定:show status like‘innodb_row_lock%’;