【MySQL08】【死锁】

一、前言

最近在读《MySQL 是怎样运行的》、《MySQL技术内幕 InnoDB存储引擎 》,后续会随机将书中部分内容记录下来作为学习笔记,部分内容经过个人删改,因此可能存在错误,如想详细了解相关内容强烈推荐阅读相关书籍。


系列文章内容目录:

  1. 【MySQL00】【 杂七杂八】
  2. 【MySQL01】【 Explain 命令详解】
  3. 【MySQL02】【 InnoDB 记录存储结构】
  4. 【MySQL03】【 Buffer Pool】
  5. 【MySQL04】【 redo 日志】
  6. 【MySQL05】【 undo 日志】
  7. 【MySQL06】【MVCC】
  8. 【MySQL07】【锁】
  9. 【MySQL08】【死锁】

二、查看事务加锁情况

1. 使用 information_schema 数据库中表获取锁信息

1.1 INNODB_TRX

INNODB_TRX 存储了 InnoDB 当前正在执行的事务信息,包括事务id(如果没有分配事务id,则显示当前事务对应的内存结构的指针)、事务状态(比如事务正在运行还是在等待获取某个锁、事务正在执行的语句、事务是何时开启的)等。如下:

  1. 开启一个事务 T1
    mysql> BEGIN;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT * FROM hero WHERE number = 8 FOR UPDATE;
    +--------+-------+---------+
    | number | name  | country |
    +--------+-------+---------+
    |      8 | c曹操 ||
    +--------+-------+---------+
    1 row in set (0.00 sec)
    
  2. 在另一个会话中查询 INNODB_TRX 表:
    mysql> SELECT * FROM  information_schema.INNODB_TRX\G
    *************************** 1. row ***************************
                        trx_id: 195617
                     trx_state: RUNNING
                   trx_started: 2024-06-27 09:51:28
         trx_requested_lock_id: NULL
              trx_wait_started: NULL
                    trx_weight: 2
           trx_mysql_thread_id: 10
                     trx_query: NULL
           trx_operation_state: NULL
             trx_tables_in_use: 0
             trx_tables_locked: 1
              trx_lock_structs: 2
         trx_lock_memory_bytes: 1136
               trx_rows_locked: 1
             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
    1 row in set (0.00 sec)
    

从执行结果可以看到,当前系统中有一个事务id为 195617 的事务,它的状态为 “正在运行”(RUNNING),隔离级别为 REPEATABLE READ。这里主要关注下面几个属性:

  • trx_tables_locked :表示当前事务加了多少表级锁
  • trx_rows_locked :表示当前事务加了多少行级锁
  • trx_lock_structs :表示当前事务生成了多少内存中的锁结构。

1.2 INNODB_LOCKS

INNODB_LOCKS 记录了一些锁信息,主要包括:

  • 如果一个事务想要获取锁但是未获取到,则记录该锁信息
  • 如果一个事务获取到了某个所,但是这个锁阻塞了别的事务,则记录该锁信息。

innodb_locks表在8.0.13版本中由performance_schema.data_locks表所代替

  1. INNODB_LOCKS 表只有在系统中发生某个事务获取不到锁而被阻塞时才会有记录,因此我们需要再执行一个事务 T2

    mysql> BEGIN;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT * FROM hero WHERE number = 8 FOR UPDATE;
    +--------+-------+---------+
    | number | name  | country |
    +--------+-------+---------+
    |      8 | c曹操 ||
    +--------+-------+---------+
    1 row in set (0.00 sec)
    
  2. 查询 INNODB_LOCKS 表记录,如下

    mysql> SELECT * FROM  information_schema.INNODB_LOCKS;
    +-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
    | lock_id         | lock_trx_id | lock_mode | lock_type | lock_table    | lock_index | lock_space | lock_page | lock_rec | lock_data |
    +-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
    | 195619:2432:3:8 | 195619      | X         | RECORD    | `demo`.`hero` | PRIMARY    |       2432 |         3 |        8 | 8         |
    | 195617:2432:3:8 | 195617      | X         | RECORD    | `demo`.`hero` | PRIMARY    |       2432 |         3 |        8 | 8         |
    +-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
    2 rows in set, 1 warning (0.00 sec)
    

可以看到 trx_id 为 195617 和 195619两个事务存在记录,但是上述内容无法区分是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫吻鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值