Mysql的锁机制之表锁
锁是计算机协调多个进程或线程并发访问某一资源的机制.
在数据库中,除传统的计算资源(如CPU,RAM,I/O等)的争用外,数据也是一种供许多用户共享的资源,如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言现得尤其重要,也更加复杂.
按照对数据库的操作分为读锁和写锁
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响.
写锁(排他锁):当前写操作没有完成前,它会阻断其他写锁和读锁.
按对数据操作的粒度分为表锁和行锁。
表锁:开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般
MyISAM表锁
读锁
MyISAM存储引擎只支持表锁,新建book表,存储引擎为MyISAM.
写锁
为book表添加写锁;
MyISAM在执行查询语句之前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的表加写锁.
MySQL的表级锁有两种模式:
表共享读锁(Table Read Lock)
表独占写锁(Table Write Lock)
锁类型 | 可否兼容 | 读锁 | 读锁 |
读锁 | 是 | 是 | 是 |
写锁 | 是 | 否 | 否 |
结论:对MyISAM表进行操作,会有以下情况
1.对MyISAM表的读操作(加读锁),不会阻塞其他进程对同意表的读请求,但会阻塞对同一表的写请求.只有当读锁释放后,
才会执行其他进程的写操作.
2,对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其他进程的读写操作.
读锁会阻塞写,但是不会阻塞读。而写锁则会把读和写都阻塞.
看看哪些表被锁了
SHOW OPEN TABLES;
分析表锁定
Table_locks_immediate 和Table_locks_waited状态变量记录MySQL内部表级锁定的情况,
Table_locks_immediate 产生表级锁定的次数,表示可以立即获取锁的查询次数,每次立即获得则加1
Table_locks_waited 出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,没等待一次锁则加1),此值高则说明存在着较严重的表级锁定争用情况.
MyISAM的读写锁调度是写优先,这也是MyISAM不适合做写为主表的引擎.因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞.
如果 Table_locks_immediate / Table_locks_waited > 5000,最好采用InnoDB引擎,因为InnoDB是行锁而MyISAM是表锁,对于高并发写入的应用InnoDB效果会好些.