一、介绍
数据库锁机制简单来说,就是数据库为了保证数据的一致性,使各种共享资源在被访问时变得有序而设计的一种原则。
MySQL的锁机制比较简单,最显著的特点是不同的存储引擎支持不同的锁机制。InnoDB支持行锁,有时也会升级为表锁,MyISAM只支持表锁。
- 表锁的特点是开销小,加锁快,不会出现死锁;锁粒度大,发生锁冲突的概率并发度相对低。
- 行锁的特点就是开销大,加锁慢;会出现死锁;锁粒度大,发生锁冲突的概率低,并发度也相对行锁较高。
二、InnoDB的锁类型:
- 读锁(共享锁)
- 写锁(排他锁)
- 意向锁
- MDL锁
1.读锁:
简称S锁,一个事务获取了一个数据行的读锁,其它事务能获得该行对应的读锁,但不能获得写锁,即一个事务在读取一个数据行时,其它事务也可以读,但不能对数据进行增删改的操作。
读锁有两种select方式的应用,第一种是自动提交模式下的select查询语句,不需加任何锁,直接返回查询结果,这就是一致性非锁定读。第二种就是通过select .....lock in share mode在被读取的行记录或行记录的范围上加一个读锁,让其它事务可以读,但是要想申请加写锁,那就会被阻塞。
2.写锁:
简称X锁,一个事务获取了一个数据行的写锁,其它事务就不能再获取该行的其他锁,写锁优先级最高。
写锁的应用就很简单了,一些DML语句的操作都会对行记录加写锁。
比较特殊的就是select for update,它会对读取的行记录上加一个写锁,则其它任何事务就不能对被锁定的行上加任何锁了,要不然会被阻塞。
3.MDL锁。
MDL锁即meta data lock,用于保证表中元数据的信息。
在会话A中,表开启了查询事务后,会自动获得一个MDL锁,会话B就不可以执行任何DDL语句的操作。
不能执行为表中添加字段的操作,会用MDL锁来保证数据之间的一致性。
会话A:
root@localhost:mysql3306.sock [(none)]>begin;
Query OK, 0 rows affected (0.00 sec)
root@localhost:mysql3306.sock [(none)]>use qq;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
root@localhost:mysql3306.sock [qq]>select * from qt;
+------+------+
| id | name |
+------+------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
| 5 | ee |
| 6 | ff |
| 7 | gg |
| 8 | hh |
+------+------+
8 rows in set (0.00 sec)
会话B:
root@localhost:mysql3306.sock [qq]>begin;
Query OK, 0 rows affected (0.00 sec)
root@localhost:mysql3306.sock [qq]>alter table qt add num tinyint(1) not null default 0;
root@localhost:mysql3306.sock [(none)]>show full processlist G;
*************************** 1. row ***************************
Id: 12
User: root
Host: localhost
db: qq
Command: Sleep
Time: 199
State:
Info: NULL
*************************** 2. row ***************************
Id: 13
User: root
Host: localhost
db: qq
Command: Query
Time: 233
State: Waiting for table metadata lock
Info: alter table qt add num tinyint(1) not null default 0
*************************** 3. row ***************************
Id: 14
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: starting
Info: show full processlist
3 rows in set (0.00 sec)
ERROR:
No query specified
4.意向锁
在MySQL存储引擎InnoDB中,意向锁是表级锁。而且有两种意向锁的类型,分别为意向共享锁和意向排他锁。
- 意向共享锁(IS)是指在给一个数据行加共享锁前必须取得该表的IS锁。
- 意向排他锁(IX)是指在给一个数据行加排他锁前必须取得该表的IX锁。
其实意向锁的作用跟MDL类似,都是防止在事务进行过程中,执行DDL语句的操作而导致的数据不一致。