全部博文(389)
分类: Mysql/postgreSQL
2014-01-05 22:20:49
MySQL的无索引锁升级
在之前的一篇blog中我介绍了mysql主要使用了在index上加gap lock的方式来实现了锁定。如果要更新的栏位上
没有index,那是通过什么方式来实现锁定呢?
对于没有index的栏位,mysql只能通过全表扫描来处理数据,在dml中如果更新了非索引的栏位就会
导致把整张表都锁住,其他会话无法进行dml操作了.
例:
mysql> create table t3 (a int primary key,b int);
Query OK, 0 rows affected (0.01 sec)
mysql> select * from t3; --insert如下记录
+---+------+
| a | b |
+---+------+
| 1 | 1 |
| 2 | 3 |
| 3 | 8 |
+---+------+
3 rows in set (0.00 sec)
打开一个会话,在非索引栏位b上删除一行
mysql> use frank;
Database changed
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from t3 where b=1; --或是update语句.
Query OK, 1 row affected (0.00 sec)
打开另一个会话
mysql> use frank;
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t3 values(10,10);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> update t3 set b=9 where b=8;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
可以看出第一个会话已经把整张表都锁住,其他会话无法进行dml操作了,这种现像称之为无索引更新
锁升级
mysql> select * from t3;
+---+------+
| a | b |
+---+------+
| 1 | 1 |
| 2 | 3 |
| 3 | 8 |
+---+------+
3 rows in set (0.00 sec)
由于使用了MVCC机制,对于查询是没有任何问题.
从以上可以看出,对于非索引栏位的更新引起的锁定问题是比较严重的,并发性因此变得很不好.对于那些
需要经常update或是delete的栏位,使用索引相当重要.