Mysql学习笔记-锁
锁机制
锁分类
- 按操作类型:
-
- 读锁(共享锁、S锁):对同一个数据,多个读操作可以同时进行,互不干扰。
-
- 写锁(互斥锁、X锁):如果当前写操作没完成,则服务进行其他读操作和写操作。
- 按操作范围
-
- 表锁:一次性对一张表加锁,如MyISAM引擎默认使用表锁,开销小加锁块;无死锁,锁范围大,容易发生锁冲突,但并发小。
-
- 行锁:一次性对一条数据加锁,如InnoDB引擎默认使用行锁,开销大加锁慢,锁范围较小,不易发生锁冲突,并发高(小概率引起并发问题:脏读、幻影读、不可重复读)
MyISAM的表锁
lock table 表 read/write 手动给表加锁
show open tables 查看加锁的表,返回1 代表某表被加了锁。
show status like 'table%':分析数据库中的表加锁情况。 返回的Table_locks_imediate :可立即获取的锁数,Table_lock_waited :需要等待的表锁数,如果该值越大,说明存在越大的锁竞争。
unlock tables 当前会话释放所有锁
- 如果一个会话session1对A表加了Read锁,则当前会话只能对A读不能对A写,同时当前会话也不能对其他表执行读操作。其他会话session2能对A读,如果进行写操作需要等待session1持有的读锁释放。session2也能对其他表执行读写操作。
- 如果会话session1对表加了写锁,则session1可以对表A进行任何操作(增删改查),其他会话session2需要等session1释放之后才能对表A执行增删改查
- 在获得 锁的过程中,lock table 命令可能会锁定比你指定的更多的表。这是因为,如果你的表中有trigger,那么为了功能能正常进行,在trigger中涉及的表也会被lock
MyISAM表级锁的锁模式
- 在执行查询语句前,会自动给所涉及的表加读锁。
- 在执行更新操作(DML)前,会有以下情况
-
- 对MyISAM表的读操作(加读锁),不会阻塞其他会话对同一表的读请求,单会阻塞对同一表的写请求,只有当读锁释放后,其他会话才可以执行写操作。
-
- 对MyISAM表的写操作加写锁,会阻塞其他会话对同一表的读和写操作,只有当写操作释放后,才会执行其他会话的读写操作。
InnoDb的行锁
set autocommit=0 关闭数据库的自动提交 begin或start transaction 开启事务。
- 如果会话1对某条数据进行DML操作(增删改),未提交前,则其他会话2需要等待会话1结束事务(提交或回滚)后才能进行DML操作。
- 表锁是通过 unlock tables解锁,也可以通过事务解锁,行锁是通过事务解锁
- 如果对表的DML操作没有经过索引或索引时效的情况 ,则行锁会转换为表锁。
- 行锁的一种特殊情况:DML操作范围更新或删除时,Mysql会给满足范围条件但不存在的数据加间隙锁(和行锁一致)。
- 缺点:比表锁性能损耗大,优点:并发能力强,效率高。
- 可以通过
select xxx from xxx for update 对查询语句进行加锁
InnoDb行锁分析
show status like '%innodb_row_lock': 查询数据库的行锁情况
Innodb_row_lock_current_waits:当前正在等待锁的数量;
Innodb_row_lock_time:等待总时长,系统启动到现在;
Innodb_row_lock_time_avg,Innodb_row_lock_time_max:等待的平均时长和最长时长。
Innodb_row_lock_time_waits:总共等待的次数