MySQL锁机制
内部锁
- MySQL在自身服务器内部执行内部锁,以管理多个会话对表内容的争用。
- 内部锁又可以分为行锁和表锁。
外部锁
- MySQL为客户会话提供选项来显式地获取表锁,以阻止其他会话访问表。
- 可以使用LOCK TABLE和UNLOCK TABLES语句来控制锁定。
LOCK TABLES table_name [READ|WRITE] # 加锁
UNLOCK TABLES # 解锁
FLUSH TABLES WITH READ LOCK # 锁定数据库所有表
为了保证备份的一致性,所有备份方法都使用 FLUSH TABLES WITH READLOCK,然而如果表上存在长时间运行的事务,这种做法可能会带来危险。
行锁
- 行级锁是细粒度的。只有被访问的行会被锁定。
- 这允许通过多个会话同时进行写访问,使其适用于多用户、高度并发和OLTP的应用程序。
- 只有InnoDB支持行级锁。
表锁
- MySQL对MyISAM、MEMORY和MERGE表使用表级锁,一次只允许一个会话更新这些表。
- 这种锁定级别使得这些存储引擎更适用于只读的或以读取操作为主的或单用户的应用程序。
read、共享锁
- 当一个表被锁定为READ时,多个会话可以从表中读取数据而不需要获取锁。
- 此外,多个会话可以在同一个表上获得锁,这就是为什么READ锁也被称为共享锁。
- 当READ锁被保持时,没有会话可以将数据写入表格中(包括持有该锁的会话)。
- 如果有任何写入尝试,该操作将处于等待状态,直到READ锁被释放。
write、排他锁
- 当一个表被锁定为WRITE时,除持有该锁的会话之外,其他任何会话都不能读取或向表中写入数据。
- 除非现有锁被释放,否则其他任何会话都不能获得任何锁。
- 这就是为什么WRITE锁被称为排他锁。如果有任何读取/写入尝试,该操作将处于等待状态,直到WRITE 锁被释放。
锁队列
- 除共享锁(一个表可以有多个共享锁)之外,没有两个锁可以一起加在一个表上。
- 如果一个表已经有一个共享锁,此时有一个排他锁要进来,那么它将被保留在队列中,直到共享锁被释放。
- 当排他锁在队列中时,所有后续的共享锁也会被阻塞并保留在队列中。
- 当 InnoDB 从表中读取/写入数据时会获取元数据锁。
- 如果第二个事务请求 WRITE LOCK,该事务将被保留在队列中,直到第一个事务完成。
- 如果第三个事务想要读取数据,就必须等到第二个事务完成。
总结
- 读锁(read)会阻塞写,但是不会阻塞读;
- 写锁(write)会把读和写都阻塞
相关文章
blog.csdn.net/qq_34377273/article/...
www.cnblogs.com/jkko123/p/10451240...
本作品采用《CC 协议》,转载必须注明作者和本文链接