读书人

懂得mysql锁(2)表级锁定

发布时间: 2012-11-10 10:48:50 作者: rapoo

理解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)



读书人网 >Mysql

热点推荐