MySQL:MyISAM锁
1.简介
MyISAM只支持表级锁。
MyISAM在执行查询(SELECT)前,会自动给涉及的所有表加读,在执行(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁。
服务器锁状态
Table_locks_immediate:立即授予表锁请求的次数。
Table_locks_waited:无法立即授予表锁请求且需要等待的次数。
# 查看锁状态信息
show status like 'table_locks%';
常用命令
# 锁定写
lock tables demo write;
# 锁定写支持并发插入
lock tables demo read local;
# 锁定写支持别名
lock tables demo as d write;
# 解锁
unlock tables;
注意
- 一次锁定所有用到表。
- 如果需要使用别名,锁定时也要使用别名锁定。
- read锁定只能读(SELECT),write只能写(UPDATE、DELETE、INSERT等)否则会出现报错。
2.读写冲突演示
锁冲突演示,注意:这里手写锁定表只是为了演示需要。
3.并发插入
通过concurrent_insert控制:
- 0: 不允许并发插入
- 1: 如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录(默认配置)。
- 2: 无论MyISAM中有没有空洞,都允许在表尾并发插入记录。
# 整理空间碎片,收回因删除记录而产生的中间空洞
OPTIMIZE TABLE table_name;
演示
注意:已提前将concurrent_insert值设置为2,方便演示
4.MyISAM锁调度
注意:
- MyISAM写比读优先,可能会有大量更新操作,使查询操作很难获得读锁造成阻塞。
- 需要长时间运行的查询操作,可能会使写进程“饿死”。
修改MyISAM的调度行为
- 指定启动参数low-priority-updates。
- 执行命令SET GLOBAL low_priority_updates=1,使该连接发出的更新请求优先级降低。
- 通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。
- 修改max_write_lock_count在一个表的读锁达到这个值后,MySQL就会暂时将写请求的优先级降低,给读进程一定获得锁的机会。
5.参考
- 《深入浅出MySQL第2版》
- Server Status Variables