查看事务锁:innodb_trx + innodb_locks + innodb_lock_waits

InnoDB锁详解
本文介绍MySQL 5.5版本中新增的InnoDB锁相关表结构,包括innodb_trx、innodb_locks和innodb_lock_waits。通过实例演示如何利用这些表定位锁等待问题,帮助快速解决SQL执行过程中出现的锁冲突。


 

以前,当出现:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction,要解决是一件麻烦的事情;特别是当一个SQL执行完了,但未COMMIT,后面的SQL想要执行就是被锁,超时结束,DBA光从数据库无法着手找出源头是哪个SQL锁住了;有时候看看 show engine innodb status, 并结合 show full processlist 能暂时解决问题,但一直不能精确定位。

 

在5.5中,information_schema 库中增加了三个关于锁的表(MEMORY引擎):
innodb_trx         ## 当前运行的所有事务
innodb_locks       ## 当前出现的锁
innodb_lock_waits  ## 锁等待的对应关系


看到这个就非常激动,这可是解决了一个大麻烦,先来看一下表结构:
复制代码
root@127.0.0.1 : information_schema 13:28:38> desc innodb_locks;
+————-+———————+——+—–+———+——-+
| Field       | Type                | Null | Key | Default | Extra |
+————-+———————+——+—–+———+——-+
| lock_id     | varchar(81)         | NO   |     |         |       |#锁ID
| lock_trx_id | varchar(18)         | NO   |     |         |       |#拥有锁的事务ID
| lock_mode   | varchar(32)         | NO   |     |         |       |#锁模式
| lock_type   | varchar(32)         | NO   |     |         |       |#锁类型
| lock_table  | varchar(1024)       | NO   |     |         |       |#被锁的表
| lock_index  | varchar(1024)       | YES  |     | NULL    |       |#被锁的索引
| lock_space  | bigint(21) unsigned | YES  |     | NULL    |       |#被锁的表空间号
| lock_page   | bigint(21) unsigned | YES  |     | NULL    |       |#被锁的页号
| lock_rec    | bigint(21) unsigned | YES  |     | NULL    |       |#被锁的记录号
| lock_data   | varchar(8192)       | YES  |     | NULL    |       |#被锁的数据
+————-+———————+——+—–+———+——-+
10 rows in set (0.00 sec)
   
root@127.0.0.1 : information_schema 13:28:56> desc innodb_lock_waits;
+——————-+————-+——+—–+———+——-+
| Field             | Type        | Null | Key | Default | Extra |
+——————-+————-+——+—–+———+——-+
| requesting_trx_id | varchar(18) | NO   |     |         |       |#请求锁的事务ID
| requested_lock_id | varchar(81) | NO   |     |         |       |#请求锁的锁ID
| blocking_trx_id   | varchar(18) | NO   |     |         |       |#当前拥有锁的事务ID
| blocking_lock_id  | varchar(81) | NO   |     |         |       |#当前拥有锁的锁ID
+——————-+————-+——+—–+———+——-+
4 rows in set (0.00 sec)
   
root@127.0.0.1 : information_schema 13:29:05> desc innodb_trx ;
+—————————-+———————+——+—–+———————+——-+
| Field                      | Type                | Null | Key | Default             | Extra |
+—————————-+———————+——+—–+———————+——-+
| trx_id                     | varchar(18)         | NO   |     |                     |       |#事务ID
| trx_state                  | varchar(13)         | NO   |     |                     |       |#事务状态:
| trx_started                | datetime            | NO   |     | 0000-00-00 00:00:00 |       |#事务开始时间;
| trx_requested_lock_id      | varchar(81)         | YES  |     | NULL                |       |#innodb_locks.lock_id
| trx_wait_started           | datetime            | YES  |     | NULL                |       |#事务开始等待的时间
| trx_weight                 | bigint(21) unsigned | NO   |     | 0                   |       |#
| trx_mysql_thread_id        | bigint(21) unsigned | NO   |     | 0                   |       |#事务线程ID
| trx_query                  | varchar(1024)       | YES  |     | NULL                |       |#具体SQL语句
| trx_operation_state        | varchar(64)         | YES  |     | NULL                |       |#事务当前操作状态
| trx_tables_in_use          | bigint(21) unsigned | NO   |     | 0                   |       |#事务中有多少个表被使用
| trx_tables_locked          | bigint(21) unsigned | NO   |     | 0                   |       |#事务拥有多少个锁
| trx_lock_structs           | bigint(21) unsigned | NO   |     | 0                   |       |#
| trx_lock_memory_bytes      | bigint(21) unsigned | NO   |     | 0                   |       |#事务锁住的内存大小(B)
| trx_rows_locked            | bigint(21) unsigned | NO   |     | 0                   |       |#事务锁住的行数
| trx_rows_modified          | bigint(21) unsigned | NO   |     | 0                   |       |#事务更改的行数
| trx_concurrency_tickets    | bigint(21) unsigned | NO   |     | 0                   |       |#事务并发票数
| trx_isolation_level        | varchar(16)         | NO   |     |                     |       |#事务隔离级别
| trx_unique_checks          | int(1)              | NO   |     | 0                   |       |#是否唯一性检查
| trx_foreign_key_checks     | int(1)              | NO   |     | 0                   |       |#是否外键检查
| trx_last_foreign_key_error | varchar(256)        | YES  |     | NULL                |       |#最后的外键错误
| trx_adaptive_hash_latched  | int(1)              | NO   |     | 0                   |       |#
| trx_adaptive_hash_timeout  | bigint(21) unsigned | NO   |     | 0                   |       |#
+—————————-+———————+——+—–+———————+——-+
22 rows in set (0.01 sec)
复制代码

 

 

下面我们来动手看看数据吧:

 

##建立测试数据:
复制代码
use test;
create table tx1
(id int primary key ,
c1 varchar(20),
c2 varchar(30))
engine=innodb default charset = utf8 ;

insert into tx1 values
(1,’aaaa’,'aaaaa2′),
(2,’bbbb’,'bbbbb2′),
(3,’cccc’,'ccccc2′);

commit;
复制代码

 

###产生事务
### Session1
start transaction;
update tx1 set c1=’heyf’,c2=’heyf’ where id = 3;

 

### 产生事务,在 innodb_trx 就有数据
复制代码
root@127.0.0.1 : information_schema 13:38:21> select * from innodb_trx \G
*************************** 1. row ***************************
                    trx_id: 3669D82
                 trx_state: RUNNING
               trx_started: 2010-12-24 13:38:06
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 3
       trx_mysql_thread_id: 2344
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 0
          trx_lock_structs: 2
     trx_lock_memory_bytes: 376
           trx_rows_locked: 1
         trx_rows_modified: 1
   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: 10000
1 row in set (0.00 sec)
复制代码

 

### 由于没有产生锁等待,下面两个表没有数据
root@127.0.0.1 : information_schema 13:38:31> select * from innodb_lock_waits \G
Empty set (0.00 sec)

root@127.0.0.1 : information_schema 13:38:57> select * from innodb_locks \G
Empty set (0.00 sec)

 

#### 产生锁等待
#### session 2
复制代码
start transaction;
update tx1 set c1=’heyfffff’,c2=’heyffffff’ where id =3 ;

root@127.0.0.1 : information_schema 13:39:01> select * from innodb_trx \G
*************************** 1. row ***************************
                    trx_id: 3669D83   ##第2个事务
                 trx_state: LOCK WAIT   ## 处于等待状态
               trx_started: 2010-12-24 13:40:07
     trx_requested_lock_id: 3669D83:49:3:4  ##请求的锁ID
          trx_wait_started: 2010-12-24 13:40:07
                trx_weight: 2
       trx_mysql_thread_id: 2346       ##线程 ID
                 trx_query: update tx1 set c1=’heyfffff’,c2=’heyffffff’ where id =3
       trx_operation_state: starting index read
         trx_tables_in_use: 1      ##需要用到1个表
         trx_tables_locked: 1      ##有1个表被锁
          trx_lock_structs: 2
     trx_lock_memory_bytes: 376
           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: 10000
*************************** 2. row ***************************
                    trx_id: 3669D82 ##第1个事务
                 trx_state: RUNNING
               trx_started: 2010-12-24 13:38:06
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 3
       trx_mysql_thread_id: 2344
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 0
          trx_lock_structs: 2
     trx_lock_memory_bytes: 376
           trx_rows_locked: 1
         trx_rows_modified: 1
   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: 10000
2 rows in set (0.00 sec)

root@127.0.0.1 : information_schema 13:40:12> select * from innodb_locks \G
*************************** 1. row ***************************
    lock_id: 3669D83:49:3:4      ## 第2个事务需要的锁
lock_trx_id: 3669D83
  lock_mode: X
  lock_type: RECORD
 lock_table: `test`.`tx1`
 lock_index: `PRIMARY`
 lock_space: 49
  lock_page: 3
   lock_rec: 4
  lock_data: 3
*************************** 2. row ***************************
    lock_id: 3669D82:49:3:4     ## 第1个事务需要的锁
lock_trx_id: 3669D82
  lock_mode: X
  lock_type: RECORD
 lock_table: `test`.`tx1`
 lock_index: `PRIMARY`
 lock_space: 49
  lock_page: 3
   lock_rec: 4
  lock_data: 3
2 rows in set (0.00 sec)

root@127.0.0.1 : information_schema 13:40:15> select * from innodb_lock_waits \G
*************************** 1. row ***************************
requesting_trx_id: 3669D83         ## 请求锁的事务
requested_lock_id: 3669D83:49:3:4  ## 请求锁的锁ID
  blocking_trx_id: 3669D82         ## 拥有锁的事务
 blocking_lock_id: 3669D82:49:3:4  ## 拥有锁的锁ID
1 row in set (0.00 sec)

<think>嗯,用户问的是MySQL中的innodb_trx系统表的作用。我需要先回忆一下这个系统表的具体信息。首先,InnoDB是MySQL的存储引擎,innodb_trx应该和事务有关。系统表通常用来提供内部状态信息,所以这个表可能记录了当前运行的事务信息。 接下来,我得确认这个表的字段和作用。记得这个表会显示事务的ID、状态、隔离级别、开始时间、正在执行的SQL语句等。可能还有事务等待的锁信息,这对排查锁冲突或长时间运行的事务有帮助。 用户可能想知道这个表的实际应用场景,比如监控事务、分析性能问题或者死锁情况。需要说明如何查询这个表,以及各个字段的含义。比如使用SELECT * FROM information_schema.innodb_trx; 来查看当前事务。 还要注意权限问题,用户需要有PROCESS权限才能访问这个表。另外,解释事务的状态,比如RUNNING、LOCK WAIT、ROLLING BACK等,这些状态能帮助用户判断事务是否正常。 可能用户在使用过程中遇到了事务阻塞或性能下降的情况,想通过这个表来诊断问题。需要提到如何结合其他系统表,比如innodb_locksinnodb_lock_waits,来分析锁的依赖关系。 另外,需要提醒用户长时间运行的事务可能导致的后果,比如回滚时间长、锁争用等。通过innodb_trx可以及时发现这些事务,并采取相应措施,比如终止事务或优化查询。 总结一下,回答的结构应该包括innodb_trx的作用、字段说明、使用方法、应用场景以及注意事项。确保用中文解释清楚,并按照用户的要求分步骤说明,保持结构清晰。</think>MySQL 中的 `innodb_trx` 系统表是 InnoDB 存储引擎提供的监控事务状态的关键工具,属于 `information_schema` 数据库。以下是其核心作用和使用场景的逐步解析: --- ### **1. 核心作用** **记录所有正在执行的 InnoDB 事务信息**,包括: - **事务 ID** (`trx_id`): 唯一标识符,未提交的只读事务可能显示为虚拟 ID。 - **事务状态** (`trx_state`): 例如 `RUNNING`(运行中)、`LOCK WAIT`(等待锁)、`ROLLING BACK`(回滚中)。 - **隔离级别** (`trx_isolation_level`): 如 `REPEATABLE READ`。 - **启动时间** (`trx_started`): 事务开始时间,用于识别长时间未提交的事务。 - **关联的 SQL** (`trx_query`): 当前事务正在执行的 SQL 语句(可能为空)。 - **锁等待信息** (`trx_wait_started`): 事务开始等待锁的时间(若处于 `LOCK WAIT` 状态)。 --- ### **2. 典型使用场景** #### **(1) 监控事务状态** ```sql SELECT * FROM information_schema.innodb_trx; ``` 通过此命令可实时查看: - 是否有事务长时间未提交(`trx_started` 时间过久)。 - 事务是否因锁冲突阻塞(`trx_state = LOCK WAIT`)。 #### **(2) 排查锁争用** 结合 `innodb_locks` 和 `innodb_lock_waits` 表,分析事务间的锁依赖关系: ```sql SELECT r.trx_id AS blocking_trx_id, b.trx_query AS blocking_query, w.blocking_engine_transaction_id FROM information_schema.innodb_lock_waits w JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_engine_transaction_id JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_engine_transaction_id; ``` #### **(3) 终止问题事务** 若发现异常事务(如长时间未提交),可通过 `trx_mysql_thread_id` 找到对应连接并终止: ```sql -- 获取线程 ID SELECT trx_mysql_thread_id FROM innodb_trx WHERE trx_id = '问题事务ID'; -- 终止连接 KILL [线程ID]; ``` --- ### **3. 关键字段说明** | 字段名 | 说明 | |-------------------------|----------------------------------------------------------------------| | `trx_id` | 事务 ID(只读事务可能为虚拟 ID) | | `trx_state` | 事务状态(`RUNNING`、`LOCK WAIT`、`ROLLING BACK` 等) | | `trx_started` | 事务开始时间 | | `trx_query` | 当前执行的 SQL 语句(可能为空) | | `trx_operation_state` | 事务操作状态(如 `fetching rows`) | | `trx_tables_in_use` | 事务涉及的表的数量 | | `trx_isolation_level` | 事务隔离级别(如 `REPEATABLE READ`) | | `trx_rows_locked` | 事务已锁定的行数 | --- ### **4. 注意事项** - **权限要求**: 需要 `PROCESS` 权限才能查询 `innodb_trx`。 - **性能影响**: 频繁查询可能对高负载系统产生轻微影响。 - **事务可见性**: 仅显示未提交的事务,已提交事务会自动消失。 通过合理利用 `innodb_trx`,可以有效诊断事务性能瓶颈、死锁问题和锁争用场景,是优化数据库稳定性的重要工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值