MySQL MyISAM与表锁
在数据库中,除了CPU、内存、IO等的争用外,数据也是一种供许多用户共享的资源,如何保证数据并发的一致性、有效性是所有数据库必须解决的问题,锁冲突也是影响数据库并发性能的一个重要因素。MySQL中不同的存储引擎之间的锁机制不一定相同,例如MyISAM和MEMORY采用的是表锁,BDB采用的是页面锁,但野支持表锁,InnoDB默认是行锁,但也支持表锁。
MySQL锁大体分三种:
- 表锁:开销小,加锁快;不会出现死锁;锁粒度大,发生锁冲突几率高,并发度最低
- 行锁:开销大,加锁慢;会出现死锁;锁粒度小,发生锁冲突几率小,并发度最高
- 页锁:开销和加锁时间介于表锁和行锁之间;会出现死锁,锁粒度介于表锁和行锁之间
仅从锁的角度来讲,表锁使用于以查询为主,只有少量按索引条件更新数据的应用,如WEB应用;而行级锁更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。
MyISAM表锁
MyISAM只支持表锁,这也是早期MySQL的唯一支持的锁。而随着应用对事务完整性和并发性要求的不断提高,MySQL才开始开发基于事务的存储引擎,后来慢慢出现了支持页锁和BDB和支持行锁的InnoDB。
表锁有共享读锁和独占写锁两种模式。读锁与读锁是兼容的,读锁与写锁是互斥的,写锁与写锁是互斥的。也就是说,MyISAM表的一个连接的读操作是不会阻塞其它连接的读操作的,但是会阻塞其它连接的写操作,而一个连接的写操作会阻塞其它连接的读操作和写操作。
MyISAM在执行查询(SELECT)时会自动给涉及到的表加上读锁,在执行更新(UPDATE、DELETE、INSERT)等,会自动给涉及到的表加上写锁。但是我们也可以显示加锁/解锁: