MySQL进阶09 — 锁机制3

概述

本章,您将学习到 MySQL 8 中有关锁机制的知识,内容包括:

  • 锁机制的分类
  • 演示 InnoDB 存储引擎的行锁
  • 演示 InnoDB 存储引擎的表锁
  • 锁的查看
  • 有关乐观锁、全局锁和死锁的内容
  • MVCC

由于内容较多,本文档仅说明锁的查看。

查看事务以及事务的锁

查看当前 MySQL 实例的所有事务:

select * from information_schema.innodb_trx;

查看正在上锁的事务:

# 8.0.13 版本之前的语句
select * from information_schema.innodb_locks;

# 8.0.13 以及 8.0.13 版本之后
select * from performance_schema.data_locks;

查看等待锁的事务:

# 8.0.13 版本之前
select * from information_schema.innodb_lock_waits;

# 8.0.13 以及 8.0.13 版本之后
select * from performance_schema.data_lock_waits;

输出信息说明

use locks;

set autocommit=0;

start transaction;

select * from information_schema.innodb_trx\G;
*************************** 1. row ***************************
                    trx_id: 421393993788632
                 trx_state: RUNNING
               trx_started: 2025-12-15 20:01:42
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 0
       trx_mysql_thread_id: 23
                 trx_query: select * from information_schema.innodb_trx
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 0
          trx_lock_structs: 0
     trx_lock_memory_bytes: 1128
           trx_rows_locked: 0
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
       trx_schedule_weight: NULL
1 row in set (0.00 sec)

rollback;

\G 表示将输出的各列以单行方式进行垂直展现:

  • trx_id - 事务的唯一 ID 号
  • trx_state - 事务的执行状态,允许的状态值有 RUNNING、LOCK WAIT、ROLLING BACK、COMMITTING
  • trx_started - 事务开始的时间
  • trx_requested_lock_id - 事务当前正在等待的锁 ID 号,如果 trx_state 为 LOCK WAIT,则此处为具体的锁 ID 号;否则为 NULL
  • trx_wait_started - 事务开始等待的锁的时间
  • trx_weight - 事务的权重,反映的是更改的行数与锁定的行数(不一定是确切的数)。在 InnoDB 中,如果发生死锁需要回滚,那么 InnoDB 会选择最小的值进行回滚
  • trx_mysql_thread_id - 事务的线程 ID
  • trx_query - 事务正在执行的 SQL 语句
  • trx_operation_state - 事务的当前操作状态,没有则为 NULL
  • trx_tables_in_use - 当前事务使用 innodb 存储引擎的表的个数
  • trx_tables_locked - 当前 SQL 语句具有行锁的 innodb 表数(因为这些是行锁而不是表锁,所以表通常仍然可以被多个事务读取和写入,尽管有些行是锁定的)
  • trx_lock_structs - 当前事务持有的锁结构数量。它反映了事务锁的复杂程度,值越高表示事务持有更复杂的锁结构。每个锁(无论是行级锁还是表级锁)都会占用一个锁结构。
  • trx_lock_memory_bytes - 此事务的锁结构在内存中占用的总大小,单位为字节(byte)
  • trx_rows_locked - 此事务锁定的大致行数,该值可能包括实际存在但对事务不可见的已删除标记行
  • trx_rows_modified - 此事务中修改与插入的行数
  • trx_concurrency_tickets - 事务当前持有的并发度票数量(每个事务在 InnoDB 中持有一个并发度票(ticket)),与系统变量 innodb_concurrency_tickes 的值关联
  • trx_isolation_level - 当前事务的隔离级别
  • trx_unique_checks - 是否为当前事务打开或关闭唯一性检查
  • trx_foreign_key_checks - 是否为当前事务打开或关闭外键检查
  • trx_last_foreign_key_error - 最后一个外键的详细错误信息,没有则为 NULL
  • trx_adaptive_hash_latched - 监控事务对自适应哈希索引(Adaptive Hash Index,AHI)的锁定状态。当事务当前正在访问或修改 AHI,trx_adaptive_hash_latched 字段的值为 YES(1),否则为 NO(0)
  • trx_adaptive_hash_timeout - 监控事务对自适应哈希索引(AHI)的锁定超时状态
  • trx_is_read_only - 事务是否是只读
  • trx_autocommit_non_locking - 标识事务是否使用了非锁定自动提交(autocommit non-locking)模式。非锁定自动提交(autocommit non-locking)是 MySQL 中一种优化读操作的事务模式。值为 1,表示是一个没有使用 for update 或 lock in share mode 的 select 语句,且开启了 autocommit 。若此字段与 trx_is_read_only 同时为 1,InnoDB 会对此事务进行优化,以降低事务修改表数据时的开销。
  • trx_schedule_weight - ‌冲突感知事务调度(Contention-Aware Transaction Scheduling ,CATS)算法为锁等待事务分配的调度权重值。当多个事务在等待同一个对象上的锁时,CATS 算法确定哪个事务首先接收锁。值越大,优先级越高。在 8.0.20 之前的版本,使用的是先进先出(FIFO)算法来调度事务;从 8.0.20 以及之后的版本使用 CATS 算法。
use locks;

set autocommit=0;

start transaction;

# 加一个记录锁(排他锁,行锁)。此时 InnoDB 存储引擎会自动添加一个 IX 锁
seletc * from tlock1 where id=1 for update;

select * from performance_schema.data_locks\G;
*************************** 1. row ***************************
               ENGINE: INNODB
       ENGINE_LOCK_ID: 139919017077976:110:1140:139919028704224
ENGINE_TRANSACTION_ID: 30244
            THREAD_ID: 57
             EVENT_ID: 264
        OBJECT_SCHEMA: locks
          OBJECT_NAME: tlock1
       PARTITION_NAME: NULL
    SUBPARTITION_NAME: NULL
           INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 139919028704224
            LOCK_TYPE: TABLE
            LOCK_MODE: IX
          LOCK_STATUS: GRANTED
            LOCK_DATA: NULL
*************************** 2. row ***************************
               ENGINE: INNODB
       ENGINE_LOCK_ID: 139919017077976:110:78:4:2:139919028701232
ENGINE_TRANSACTION_ID: 30244
            THREAD_ID: 57
             EVENT_ID: 264
        OBJECT_SCHEMA: locks
          OBJECT_NAME: tlock1
       PARTITION_NAME: NULL
    SUBPARTITION_NAME: NULL
           INDEX_NAME: PRIMARY
OBJECT_INSTANCE_BEGIN: 139919028701232
            LOCK_TYPE: RECORD
            LOCK_MODE: X,REC_NOT_GAP
          LOCK_STATUS: GRANTED
            LOCK_DATA: 1
2 rows in set (0.00 sec)

rollback;
  • ENGINE - 持有或请求锁的存储引擎
  • ENGINE_LOCK_ID - 存储引擎持有或请求的锁 ID
  • ENGINE_TRANSACTION_ID - 请求锁的事务 ID
  • THREAD_ID - 持有锁的线程 ID
  • EVENT_ID - 事件(Event)的 ID。事件(event)由一组 SQL 语句集合组成,主要的作用是周期性运行数据库对象,用来实现 MySQL 的计划任务。
  • OBJECT_SCHEMA - 库名称
  • OBJECT_NAME - 表名称
  • PARTITION_NAME - 锁的分区名称
  • SUBPARTITION_NAME - 锁的子分区名称
  • INDEX_NAME - 锁的索引名
  • OBJECT_INSTANCE_BEGIN - 内存中锁的起始地址
  • LOCK_TYPE - 锁的类型。取决于存储引擎,对于 InnoDB,值可以有 RECORD、TABLE
  • LOCK_MODE - 请求锁的方式
  • LOCK_STATUS - 锁请求的状态。取决于存储引擎,对于 InnoDB,值可以有 GRANTED (锁被持有)和 WAITING (锁正在等待)。
  • LOCK_DATA - 与锁关联的数据(如果有的话)

也可以使用 show open tables from 库名; 来查看:

show open tables from locks;
+----------+---------+--------+-------------+
| Database | Table   | In_use | Name_locked |
+----------+---------+--------+-------------+
| locks    | t1      |      0 |           0 |
| locks    | tindex1 |      0 |           0 |
| locks    | tb1     |      0 |           0 |
| locks    | tlock1  |      0 |           0 |
+----------+---------+--------+-------------+
4 rows in set (0.00 sec)
  • Database - 库名
  • Table - 表名
  • In_use - 该表的表锁或锁请求数,如果为 0 表示表已经打开但当前未使用。如果一个连接会话使用了表锁(lock table 表名 write;) 则 In_use 将为 1
  • Name_locked - 表名是否被锁。主要用于对表进行删除或重命名等操作。
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇