MySQL 锁

server/2024/9/23 6:30:45/

在MySQL中,锁机制是用于协调多个并发事务对同一资源的访问,确保数据的一致性和完整性。不同的锁类型和粒度适应不同的应用场景,通过合理运用锁机制,可以最大限度地提升数据库的并发性能和数据一致性。

一、MySQL中的锁分类

MySQL中的锁大致可以分为以下几类:

  1. 全局锁(Global Lock)
  2. 表级锁(Table-level Lock)
  3. 行级锁(Row-level Lock)
  4. 页面锁(Page-level Lock)(InnoDB使用)
  5. 意向锁(Intention Lock)
  6. Gap锁和Next-Key锁(InnoDB特有)

每种锁的粒度、适用场景和性能开销都有所不同。

二、全局锁(Global Lock)

全局锁 是一种作用于整个数据库的锁,MySQL中最常用的全局锁命令是 FLUSH TABLES WITH READ LOCK(简称 FTWRL)。该命令会使整个数据库进入只读状态。

FLUSH TABLES WITH READ LOCK;

当这个命令执行后,所有表都被锁定成只读模式,直到解锁为止。全局锁的常见用途是做数据备份,当需要进行一致性备份时,可以通过全局锁确保备份期间数据不会发生任何修改。

全局锁的特点:
  • 阻止所有的写操作,整个库处于只读模式。
  • 适合静态数据备份场景。
  • 不适用于高并发的生产环境,因为全局锁会显著影响数据库的性能,甚至导致系统停顿。
使用全局锁的风险:
  • 备份期间所有对数据库的写操作都会被阻塞。
  • 对于长时间运行的事务,全局锁可能导致应用程序超时或出现死锁现象。

三、表级锁(Table-level Lock)

表级锁 是MySQL最简单的一种锁机制,它对整个表进行锁定,通常分为两种类型:表共享读锁(Table Read Lock)表独占写锁(Table Write Lock)

1. 表共享读锁(Table Read Lock)

读锁允许多个事务同时读取一个表,但阻止写操作。表共享读锁的基本特点是:

  • 多个事务可以同时对同一个表进行读操作。
  • 任何一个事务申请写锁时,必须等待所有读锁释放。

使用方式:

LOCK TABLES table_name READ;
2. 表独占写锁(Table Write Lock)

写锁会阻止任何其他事务对表进行读和写操作。只有获得写锁的事务可以操作表,其他事务必须等待该锁释放。

使用方式:

LOCK TABLES table_name WRITE;
表级锁的特点:
  • 适合对数据表的整体操作,比如导入大量数据或进行表结构变更。
  • 开销较小,锁定机制简单,但并发性较差。
  • 在MyISAM存储引擎中,默认使用表级锁。对于高并发写操作时,表级锁可能成为性能瓶颈。
使用表级锁的注意事项:
  • 表级锁可能导致大量事务等待,从而影响系统性能。
  • 表级锁不适合对表频繁进行并发读写操作的场景。

四、行级锁(Row-level Lock)

行级锁 是粒度最细的锁,它只针对数据表中的某一行进行加锁。行级锁使得不同事务能够对同一个表中的不同行进行并发操作,从而提高了并发性。

行级锁常见于支持事务的存储引擎,如InnoDB。在InnoDB中,行级锁通常通过两阶段锁定协议自动管理,开发者不需要显式加锁或解锁。

行级锁的特点:
  • 具有较高的并发性,多个事务可以并发操作同一表的不同行。
  • 锁开销较大,因为需要记录和管理每一行的锁信息。
  • 适用于多用户高并发的环境,尤其是频繁的写操作。
InnoDB中的行锁操作:
  • 行级锁在执行INSERTUPDATEDELETE等操作时自动加锁。
  • 在查询时,如果使用了索引,InnoDB会锁住特定的行;如果没有索引,InnoDB可能退化为全表扫描,锁住所有行。
BEGIN;
UPDATE employees SET salary = salary + 1000 WHERE emp_no = 12345;
COMMIT;

以上事务中,InnoDB会对符合条件的行加上行级锁,其他事务在没有解锁前无法修改该行数据。

行级锁的问题:
  • 死锁问题:由于不同事务可能互相等待对方的锁,可能发生死锁。
  • 锁升级:如果多个行锁无法满足需求,InnoDB可能会将行锁升级为表级锁。

五、页面锁(Page-level Lock)

页面锁 是介于表级锁和行级锁之间的一种锁机制,它锁定的是数据页(通常是多个连续的记录)。MySQL中的BDB(Berkeley DB)存储引擎支持页面锁,但InnoDB主要使用行级锁,因此页面锁在InnoDB中不常用。

页面锁的特点是:

  • 并发性比表级锁高,但低于行级锁。
  • 开销和锁定时间介于行级锁和表级锁之间。
  • 使用页面锁可能会引发“锁升级”,即锁住的页范围较大时,最终会变成表级锁。

由于页面锁粒度较大,因此当多个事务并发操作不同页时,可能导致锁争用,降低并发性能。现代应用场景中,页面锁不常见。

六、意向锁(Intention Lock)

意向锁 是InnoDB的一种内部锁机制,用于实现行级锁和表级锁之间的兼容性。它表明一个事务计划对表中的某些行进行加锁。

意向锁有两种:

  1. 意向共享锁(IS,Intention Shared Lock):事务打算给某些行加共享锁。
  2. 意向排他锁(IX,Intention Exclusive Lock):事务打算给某些行加排他锁。

意向锁的存在使得InnoDB能够在获取行锁时,与其他事务的表级锁进行兼容检测。例如,如果一个事务已经对某些行加了共享锁,另一个事务要对整个表加排他锁时,会先检测意向锁情况。

意向锁的机制确保了行锁和表锁之间的兼容性判断,而不会导致全表加锁的开销过大。

七、Gap锁和Next-Key锁(InnoDB特有)

Gap锁(间隙锁,Gap Lock)Next-Key锁 是InnoDB存储引擎为避免幻读问题而设计的锁机制。

1. Gap锁(间隙锁)

Gap锁是InnoDB在可重复读(REPEATABLE READ)隔离级别下使用的一种特殊锁定机制。它不仅锁定已经存在的记录,还锁定记录之间的“间隙”。这样可以防止其他事务在间隙中插入新记录,避免幻读问题。

例如:

SELECT * FROM employees WHERE emp_no BETWEEN 100 AND 200 FOR UPDATE;

在上述查询中,InnoDB不仅会锁住符合条件的记录,还会锁住emp_no在100到200之间的间隙,防止其他事务插入emp_no在该范围内的记录。

2. Next-Key锁

Next-Key锁是Gap锁与行锁的结合体,锁定了一个记录以及记录之间的间隙。它同样用于防止幻读,确保在同一事务中多次查询时,查询结果一致。

Gap锁和Next-Key锁的特点:
  • 用于解决可重复读隔离级别下的幻读问题。
  • 提高了并发控制的准确性,但增加了锁的开销。
  • 可能导致锁争用,特别是在频繁插入新记录的场景下。

八、锁的并发控制与性能优化

  1. 锁的选择:根据不同场景选择合适的锁类型。在读多写少的场景中,使用表级锁能够简化锁管理,提高读操作的性能;而在高并发写入场景中,行级锁的并发性更好。

  2. 避免死锁:死锁是并发事务中的常见问题,通常可以通过以下几种方式避免:

    • 保持一致的锁定顺序。
    • 尽量减少事务持有锁的

时间。

  • 使用合理的事务隔离级别,降低锁的争用。
  1. 使用索引:在InnoDB中,行级锁依赖索引。如果查询不使用索引,可能会导致全表扫描,从而加锁更多的行,降低并发性。

  2. 监控锁情况:可以通过SHOW ENGINE INNODB STATUS查看锁的使用情况,及时发现锁争用或死锁问题。

总结

MySQL的锁机制种类丰富,包含全局锁、表级锁、行级锁、页面锁以及InnoDB引擎特有的Gap锁、Next-Key锁和意向锁。每种锁适用于不同的场景,选择合适的锁类型可以在保证数据一致性的同时,尽量提高数据库的并发性能。通过合理使用锁机制,配合良好的索引设计和事务管理,可以显著提升MySQL数据库的性能和稳定性。


http://www.ppmy.cn/server/114765.html

相关文章

逻辑一键导入导出,解决企业多环境数据迁移的难题

在当今复杂多变的商业环境中,系统间的数据迁移、备份与共享成为了确保业务连续性和一致性的关键环节。随着企业规模的不断扩大和业务的日益复杂化,JVS逻辑引擎作为一款集高效、灵活、可扩展性于一身的决策支持系统,还通过其独特的导入导出功能…

自然语言处理系列六十一》分布式深度学习实战》TensorFlow深度学习框架

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 自然语言处理系列六十一分布式深度学习实战》TensorFlow深度学习…

OpenCV结构分析与形状描述符(14)拟合直线函数fitLine()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 拟合一条直线到2D或3D点集。 fitLine 函数通过最小化 ∑ i ρ ( r i ) \sum_i \rho(r_i) ∑i​ρ(ri​)来拟合一条直线到2D或3D点集&#xff0c…

【机器学习】梯度提升和随机森林的概念、两者在python中的实例以及梯度提升和随机森林的区别

引言 梯度提升(Gradient Boosting)是一种强大的机器学习技术,它通过迭代地训练决策树来最小化损失函数,以提高模型的预测性能 随机森林(Random Forest)是一种基于树的集成学习算法,它通过组合多…

如何用720VR全景摄影拍摄星空

1. 选择合适的地点和时间 远离光污染:找到一个远离城市灯光污染的地方,如乡村、山顶或专门的天文观测点。 天气条件:选择晴朗的夜晚,没有云层遮挡,空气质量良好。 月相选择:避免满月等亮光的时段&#xf…

20240910软考架构-------软考146-150答案解析

每日打卡题146-150答案 146、【2018年真题】 难度:一般 给定关系R(A,B,C,D,E)与S(A,B,C,F,G),那么与表达式等价的SQL语句如下:select (1) from R, S where (2) 。 (1)A.…

[算法]排序——快速排序(QuickSort)多种实现方式(C语言)

前言 快速排序算法是托尼霍尔(Tony Hoare)在1962年提出来的,他是快速排序之父,是1980年图灵奖得主。本篇文章将介绍通过递归的不同写法的方法和非递归的方法来实现简单的快速排序。 一、快速排序的基本思想 快速排序是一种 二叉树…

动态扩容Linux根目录:/dev/mapper/centos-home分配部分空间给/dev/mapper/centos-root

1 查看磁盘空间 首先确保/dev/mapper/centos-home有足够的空间分配给根目录,可以使用命令查看: # df -h可以看到home目录还是比较空闲的,因此,可以将/home空间的分配给根目录一些。 /dev/mapper/centos-root是50G,基本…