理解mysql锁(2)表级锁定
MyISAM 存储引擎使用的锁定机制完全是由 MySQL 提供的表级锁定实现。
mysql的表级锁定主要有两种:写锁和读锁
对write写锁,MySQL使用的表锁定方法原理如下:
* 如果在表上没有锁,在它上面放一个写锁。
* 否则,把锁定请求放在写锁定队列中。
对read读锁,MySQL使用的表锁定方法原理如下:
* 如果在表上没有写锁定,把一个读锁定放在它上面。
* 否则,把锁请求放在读锁定队列中。
当一个锁定被释放时,锁定可被写锁定队列中的线程得到,然后是读锁定队列中的线程。这意味着,如果你在一个表上有许多更新,SELECT语句将等待直到没有更多的更新。
可以通过检查table_locks_waited和table_locks_immediate状态变量来分析系统上的表锁定争夺:
session A显示地给t1表加读锁定mysql> lock table t1 read;Query OK, 0 rows affected (0.00 sec)自己的读操作未被阻塞:mysql> select * from t1;+------+| i |+------+| 1 || 2 || 5 |+------+3 rows in set (0.00 se)session B其他进程的读操作也未被阻塞:mysql> select * from t1;+------+| i |+------+| 1 || 2 || 5 |+------+3 rows in set (0.00 sec)session Amysql> update t1 set i=3 limit 1;ERROR 1099 (HY000): Table 't1' was locked with a READ lock and can't be updatedsession Bmysql> update t1 set i=3 limit 1;直接被阻塞了session A解除读锁mysql> unlock tables;Query OK, 0 rows affected (0.00 sec)session B在session A释放锁定资源后,session B获得了资源,更新成功mysql> update t1 set i=3 limit 1;Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0session A获取读锁的时候增加local选项mysql> lock table t1 read local;Query OK, 0 rows affected (0.00 sec)session B其他session的insert 未被阻塞mysql> insert into t1 values(6);Query OK, 1 row affected (0.00 sec)然而,其他session的update被阻塞了mysql> update t1 set i=3 limit 1;直接被阻塞鸟session A这次加写锁mysql> unlock tables;Query OK, 0 rows affected (0.00 sec)mysql> lock table t1 write;Query OK, 0 rows affected (0.00 sec)自己的session可以继续读:mysql> select * from t1;+------+| i |+------+| 3 || 2 || 5 || 6 |+------+4 rows in set (0.00 sec)session B:其他session的读被阻塞了mysql> select * from t1;直接被阻塞鸟session A释放锁定资源mysql> unlock tables;Query OK, 0 rows affected (0.00 sec)session B其他session可以获得资源了mysql> select * from t1;+------+| i |+------+| 3 || 2 || 5 || 6 |+------+4 rows in set (0.00 sec)session A通过DDL获取write_allow_read类型的写锁定mysql> alter table t1 add constraint t1_pk primary key(i);Query OK, 4 rows affected (0.07 sec)Records: 4 Duplicates: 0 Warnings: 0session B其他session的读未被阻塞mysql> select * from t1;+---+| i |+---+| 2 || 3 || 5 || 6 |+---+4 rows in set (0.00 sec)