首页 >> 基础教程

MySQL全局锁类型及使用场景总结

       MySQL 中的全局锁主要用于对整个数据库实例施加只读限制,确保操作期间数据的一致性(例如备份)。主要有以下几种:

  1. FLUSH TABLES WITH READ LOCK (FTWRL)

    1. 作用: 这是最经典、最严格的全局读锁。

      1. 关闭所有打开的表。

      2. 对整个数据库实例施加全局读锁。所有数据库的所有表都变为只读状态,阻止任何写操作(INSERTUPDATEDELETEDDL等)和显式/隐式的事务提交

      3. 阻止新的写连接尝试(新连接可以建立,但执行写操作会被阻塞)。

    2. 特点:

      1. 严格性: 会阻塞所有正在进行的数据修改语言(DML)和DDL操作,并等待它们完成(或超时)后才获得锁。

      2. 阻塞新事务: 获得锁后,会阻止新事务的启动(无论是读还是写事务)。

      3. 释放方式: 必须显式使用 UNLOCK TABLES 命令释放。持有锁的会话断开也会自动释放。

      4. 存储引擎无关: 作用于整个 MySQL 服务器层,对所有存储引擎生效。

    3. 主要用途: 获取全局一致性读视图(例如,配合 SHOW MASTER STATUS 记录二进制日志位置做一致性备份)、在非事务性存储引擎(如 MyISAM)上做一致性备份(虽然现在推荐用 InnoDB 和在线备份工具)。

    4. 风险: 长时间持有会严重阻塞所有写入操作,影响业务可用性

  2. SET GLOBAL read_only = ON

    1. 作用: 将整个 MySQL 实例设置为只读模式。

      1. 阻止普通用户账户(没有 SUPER 权限)执行写操作(INSERTUPDATEDELETEDDL)和事务提交。

      2. 不会影响具有 SUPER 权限的用户(通常是管理员)的写操作。

    2. 特点:

      1. 非严格锁: 它不阻塞正在进行的写操作。它只是阻止新的非 SUPER 用户的写操作尝试。已经开始的写事务可以继续执行直到提交。

      2. 不影响现有连接: 已经建立的连接,如果正在执行写操作且尚未完成,可以继续执行。

      3. 释放方式: 使用 SET GLOBAL read_only = OFF 解除。

      4. 存储引擎无关: 作用于整个 MySQL 服务器层。

    3. 主要用途: 进行数据库维护、防止应用在特定时段(如迁移、报表生成)意外写入数据。通常与 super_read_only 结合使用。

    4. 风险: 较低,因为 SUPER 用户仍可写入。如果单独使用,不足以完全阻止写入(管理员可能误操作)

  3. SET GLOBAL super_read_only = ON

    1. 作用: MySQL 5.7.8 引入。在 read_only=ON 的基础上,进一步限制具有 SUPER 权限的用户。

      1. 设置 super_read_only=ON 会自动将 read_only 设置为 ON

      2. 阻止所有用户(包括 SUPER 用户)执行写操作和事务提交。

    2. 特点:

      1. 最严格的管理性锁: 真正实现整个实例的只读,无人能写(除非先关闭 super_read_only)。

      2. 非严格锁(同 read_only): 同样不阻塞正在进行的事务,只阻止新的写操作尝试。

      3. 释放方式: 使用 SET GLOBAL super_read_only = OFF 解除(这也会将 read_only 设置为 OFF,除非显式设置了 read_only=ON)。

      4. 存储引擎无关: 作用于整个 MySQL 服务器层。

    3. 主要用途: 高可用环境(如主从切换时确保原主库绝对不可写)、需要绝对保证无任何写入的维护场景。是保护主库避免意外写入的推荐方式。

    4. 风险: 最低(在阻止写入方面),但仍需注意设置后管理员也无法直接写入

  4. mysqldump 使用 --lock-all-tables 选项

    1. 作用: 当使用 mysqldump 工具备份数据并指定 --lock-all-tables 或 -x 选项时,在备份开始前,mysqldump 会自动执行 FLUSH TABLES WITH READ LOCK 来获取全局读锁。

    2. 特点: 本质上是工具自动调用了 FTWRL。

    3. 用途: 为使用非事务存储引擎的表或在特定场景下获取一致性备份。对于 InnoDB 表,强烈推荐使用 --single-transaction 选项(基于 MVCC 获取一致性视图)代替 --lock-all-tables,以避免全局锁。

  5. MySQL Locking Service (GET_LOCK()) - 间接/应用层全局锁

    1. 作用: 使用函数 GET_LOCK('lock_name', timeout) 可以获取一个用户命名的锁。如果锁名相同(如 'global_lock'),并且多个客户端尝试获取,则只有一个客户端能成功,其他客户端会被阻塞(直到超时或锁释放)。

    2. 特点:

      1. 这不是 MySQL 内置的用于数据库一致性的全局锁,而是提供给应用程序使用的协作式锁

      2. 锁的作用域是整个 MySQL 服务器实例(同一个锁名在整个实例内唯一)。

      3. 锁的生命周期与会话绑定(会话结束或显式 RELEASE_LOCK() 释放)。

      4. 需要应用程序逻辑来实现基于此锁的全局协调。

    3. 用途: 实现应用层面的全局互斥逻辑(例如,防止多个实例同时执行某个后台任务)。



最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29
备案号:蜀ICP备2023042032号-1