1.是否支持行级锁
MyISAM
只有表级锁,而InnoDB
支持行级锁和表级锁,默认为行级锁。
(1)MySQL大致可以归纳为以下3种锁:
- 表级锁:开销小,加锁快;不会出现死锁;锁的粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁的粒度小,发生锁冲突的概率最低,并发度最高。
- 页面锁:开销 和加锁时间界于表锁和行锁之间;会出现死锁,锁定的粒度界于表锁和行锁之间,并发一般。
(2)表锁
MyISAM会在执行select语句前,会自动给涉及的表加读锁,在执行增删改操作前会自动给涉及的表加写锁。
- MySQL的表锁有两种模式:
- 表共享读锁
- 表独占写锁
- 读锁会阻塞写,写锁会阻塞读和写。
- 对MyISAM表的读操作,不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它线程的写操作。
- 对MyISAM表的写操作,会阻塞其它进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。
读锁的演示
窗口1执行
窗口2的语句被阻塞
关闭窗口1,窗口2才执行成功
执行unlock tables释放锁
释放后才成功
create table dept(
deptno int not null auto_increment,
dname varchar(20),
loc varchar(20),
primary key(deptno)
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
# 打开两个会话窗口
# 窗口1执行以下语句
lock table dept read;
select * from dept;
# 窗口2执行执行以下语句
select * from dept;
insert into dept values(null,'财务部','北京');
# 此时,窗口2的请求被阻塞,必须等待会话1释放锁后才能执行;
# 释放会话1的锁,并观察会话2的执行结果。
unlock tables;
写锁的演示
会话1加写锁,会话2读操作,会被阻塞
会话1 释放锁
# 会话1加写锁
lock table dept write;
delete from dept where deptno = 1;
# 会话2读操作,会被阻塞
select * from dept;
# 会话1 释放锁
unlock tables;
# 观察会话2 查询结果
注意:如果持有表锁的session异常终止的话(比如说执行了“ctrl+z”),那么该session是不会主动释放锁的,这时候我们可以重启mysql服务器,不推荐。可以通过show processlist 命令来查看线程ID,通过kill 【线程ID】
总结:MyISAM不适合写表的引擎,写锁后,其它线程不能做任何操作。