锁机制[MySQL]:全局 / 表级 / 行级锁 三类锁的核心用法

4 阅读3分钟

锁的机制

目录

  • 一、为什么需要锁?
  • 二、全局锁
  • 三、表级锁 [重点]
  • 四、行级锁(InnoDB 独有)[重点]
  • 五、总结

一、为什么需要锁?

锁的本质是解决并发冲突

  • 多个客户端同时读写同一份数据时,必须有规则保证数据一致性。
  • 锁就是这套规则的实现,不同的锁对应不同的并发控制策略。

加锁范围分为全局锁、表级锁和行锁3类。

二、全局锁

  • 作用:锁住整个数据库,让它变成只读。

  • 命令:

    • 加锁:flush tables with read lock;
    • 解锁:unlock tables;(或断开会话自动释放)
  • 缺点:所有写操作(insert/update/delete/alter)都会被阻塞,业务几乎停摆。

  • 典型场景:全库逻辑备份(比如 mysqldump 不加参数时),防止备份过程中数据被修改,导致备份文件不一致。

  • 替代方案:InnoDB 下用 mysqldump --single-transaction,利用 MVCC 做一致性快照,不阻塞业务。

三、表级锁

表级锁有四种,逐个分析:

1、表锁(lock tables

  • 共享读锁(read):

    • lock tables <table_name> read;
    • 自己能读,不能写;别人能读,不能写。
    • 自己也不能访问其他表。
  • 独占写锁(write):

    • lock tables <table_name> write;
    • 自己能读能写;别人啥都干不了。
  • 释放表锁unlock tables;

  • 使用场景:MyISAM 引擎备份、维护;InnoDB 尽量别用,因为粒度太粗,并发性能差。

2、元数据锁(MDL)

  • 特点自动加的,不需要手动调用
  • 读锁:CRUD 操作时自动加,防止表结构被改。
  • 写锁:alter table 等 DDL 时自动加,防止别人读写数据。
  • 在事务提交后释放MDL
  • 坑点:长事务持有 MDL 读锁时,DDL 操作会被阻塞,进而阻塞后续所有查询。
  • 解决办法:变更前先查长事务,必要时 kill 掉。

3、意向锁

  • 作用快速判断表中是否有记录被加了行锁,避免加表锁时全表扫描。
  • 加行级共享锁前 → 先加「意向共享锁」
  • 加行级独占锁前 → 先加「意向独占锁」
  • 意向锁之间不冲突,只和显式表锁冲突。

4、AUTO-INC 锁(自增锁)

  • 作用:保证自增主键(AUTO_INCREMENT)的值是连续递增的。

  • 传统模式:插入语句执行完才释放锁,并发插入会被阻塞。

  • 轻量模式(MySQL 5.1.22+):

    • 通过 innodb_autoinc_lock_mode 控制。
    • mode = 0:采用auto_inc锁,sql执行结束后释放锁。
    • mode=2:申请到自增值就释放锁,并发性能最好,但主从复制时 binlog 格式要设为 row,否则会数据不一致。

四、行级锁(InnoDB 独有)

行级锁是 InnoDB 高并发的关键,粒度小,只锁需要的记录。

1、共享锁(S 锁)与独占锁(X 锁)

  • 共享锁(S):读读兼容,读写互斥。

    -- 对读取的记录加共享锁
    select ... lock in share mode;
    
  • 独占锁(X):读写、写写都互斥。

    -- 对读取的记录加独占锁
    select ... for update;
    
  • 注意:必须在事务中使用,事务提交后锁才释放。

2、三种行锁类型

  • Record Lock(记录锁) :锁单条记录,比如 where id = 1 for update
  • Gap Lock(间隙锁) :锁一个范围的记录(不包含记录本身),防止幻读。
  • Next-Key Lock:Record Lock + Gap Lock 的组合,是 InnoDB 默认的行锁算法,在可重复读隔离级别下用来解决幻读。

五、总结

  • 全局锁:全库只读,备份用,InnoDB 尽量不用。

  • 表级锁:

    • 显式锁:lock tables,MyISAM 用,InnoDB 少用。
    • MDL:自动加,防表结构和数据操作冲突,长事务是坑。
    • 意向锁:行锁的「预告」,加速表锁判断。
    • 自增锁:管自增,轻量模式性能好但要注意主从。
  • 行级锁:InnoDB 高并发核心,S/X 锁 + 三种行锁类型,解决并发和幻读。