这条语句主要用于查看表的锁竞争情况,where 条件限制了只有存在锁竞争才会显示数据。
显示字段如下:
Database
数据库名称
Table
表名
In_use
表锁会使这个值+1,每个请求行锁而阻塞的线程也会使这个值+1
Name_locked
表名是否被锁定。名称锁定用于诸如删除或重命名表的操作
这条语句显示当前正在运行的线程连接,如果你的权限足够,那么你可以看到全部的用户的线程,否则只能看到你当前用户的线程。
显示字段如下:
Id
线程id,可以使用 kill id 来杀死这条线程。
Host
创建连接的主机地址
db
使用的数据库
Command
线程正在执行的命令的类型。
具体信息查看 Mysql官网Commom描述
Time
线程处于当前状态的时间(以秒未单位)
State
线程正在执行的操作,事件或者状态
大多数状态对应于非常快速的操作。如果线程在给定状态下停留许多秒钟,则可能存在需要调查的问题。
具体信息查看Mysql官网State描述
Info
线程当前正在执行的语句
这条语句显示InnoDb中正在开启的非只读事务的相关信息。
这条语句我们重点关注它是否正在等待锁,以及事务的开始时间。
显示字段如下:
TRX_ID
事务Id
TRX_WEIGHT
事务的权重,反映(未必是准确的)已更改的行和该事务锁定的行数。出现死锁时,InnoDb通常会回滚权重较小的事务。
TRX_STATE
事务执行状态。允许值是 RUNNING,LOCK WAIT, ROLLING BACK,和 COMMITTING。
TRX_STARTED
事务的开始时间
TRX_REQUESTED_LOCK_ID
事务当前正在等待的锁的ID
TRX_WAIT_STARTED
事务等待锁的时间
TRX_MYSQL_THREAD_ID
Mysql的线程id
TRX_QUERY
事务正在执行的SQL语句
TRX_OPERATION_STATE
事务当前的操作状态
TRX_TABLES_IN_USE
事务使用到的表的数量
TRX_TABLES_LOCKED
事务从多少个表中获取了锁
TRX_LOCK_STRUCTS
事务保留的锁数。
TRX_LOCK_MEMORY_BYTES
内存中此事务的锁结构占用的总大小。
TRX_ROWS_LOCKED
此事务的锁定行数
TRX_ROWS_MODIFIED
此事务中已修改和已插入的行数。
TRX_CONCURRENCY_TICKETS
由innodb_concurrency_tickets 系统变量指定的值,该值指示当前事务在被换出之前可以完成多少工作
TRX_ISOLATION_LEVEL
当前事务的隔离级别。
TRX_UNIQUE_CHECKS
当前事务是打开还是关闭唯一检查。例如,它们可能在批量数据加载期间关闭。
TRX_FOREIGN_KEY_CHECKS
当前事务是打开还是关闭唯一检查。例如,它们可能在批量数据加载期间关闭。
TRX_LAST_FOREIGN_KEY_ERROR
最后一个外键错误的详细错误消息(如果有);否则NULL。
TRX_ADAPTIVE_HASH_LATCHED
自适应哈希索引是否被当前事务锁定。(一次仅一个事务可以修改自适应哈希索引。)
TRX_ADAPTIVE_HASH_TIMEOUT
是立即放弃搜索锁存器以获取自适应哈希索引,还是在MySQL的调用之间保留它。当没有自适应哈希索引争用时,此值保持为零,并且语句保留闩锁,直到它们完成为止。在争用期间,它递减计数为零,并且语句在每次查询行后立即释放锁存器。
TRX_IS_READ_ONLY
值为1表示事务是只读的。
TRX_AUTOCOMMIT_NON_LOCKING
值为1表示事务是 SELECT不使用 FOR UPDATE 或者LOCK IN SHARED MODE子句的语句,并且正在autocommit启用状态下执行, 因此事务将仅包含此一条语句。当此列和TRX_IS_READ_ONLY均为1时,InnoDB优化事务以减少与更改表数据的事务相关的开销。
这条语句显示 InnoDB 中产生锁等待的事务信息。
一个锁等待至少会产生两行的数据,分别是等待锁的事务,以及持有锁的事务。
显示字段如下:
LOCK_ID
内部唯一的锁ID号
LOCK_TRX_ID
请求或者持有锁的事务的ID
LOCK_MODE
请求或者持有的锁。允许值S,X, IS,IX, GAP,AUTO_INC,和 UNKNOWN
LOCK_TYPE
锁的类型。允许的值 RECORD用于行级锁定, TABLE表级锁定
LOCK_TABLE
已锁定或包含锁定记录的表的名称
LOCK_INDEX
索引的名称,如果LOCK_TYPE 为 RECORD 则显示;否则NULL
LOCK_SPACE
锁定记录的表空间ID,如果LOCK_TYPE 为 RECORD 则显示;否则NULL
LOCK_PAGE
锁定记录的页码,如果LOCK_TYPE 为 RECORD 则显示;否则NULL
LOCK_REC
页面内锁定记录的堆号,如果LOCK_TYPE 为 RECORD 则显示;否则NULL
LOCK_DATA
与锁关联的数据(如果有)。如果LOCK_TYPE为RECORD,则显示一个值,否则为NULL。
如果锁定的是唯一索引,则显示的是二级索引的值。
如果显示的是二级索引,则显示二级索引值并附加主键值。
这条语句显示锁等待的事务的对应信息。
显示字段如下:
REQUESTING_TRX_ID
请求锁的事务id
REQUESTED_LOCK_ID
请求的锁id
BLOCKING_TRX_ID
持有锁的事务id
BLOCKING_LOCK_ID
持有的锁id
这条语句显示的是Innodb过去一段时间的运行日志(这里是每一段时间刷新一次,因此未必是最新的)。
排除死锁的时候,我们重点关注 LATEST DETECTED DEADLOCK 这部分内容就好,这部分内容记录的是最近一次死锁的信息。
这部分的内容解析如下,如果需要更详细的 innodb status 内容的解析,可以查看这篇博客
------------------------
LATEST DETECTED DEADLOCK
------------------------
160128 1:51:53 #这里显示了最近一次发生死锁的日期和时间
*** (1) TRANSACTION:
TRANSACTION D20847, ACTIVE 141 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s)
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1818124 localhost root statistics
select * from test_deadlock where id=2 for update
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20847 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
*** (2) TRANSACTION:
TRANSACTION D20853, ACTIVE 119 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1248, 2 row lock(s)
MySQL thread id 20081, OS thread handle 0x7f0a0f020700, query id 1818204 localhost root statistics
select * from test_deadlock where id=1 for update
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000001; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab0110; asc ;;
3: len 4; hex 00000001; asc ;;
*** WE ROLL BACK TRANSACTION (2)
这部分内容比较多,下面分段逐一进行解释:
5.2.1 下面这部分显示的是死锁的第一个事务的信息:
*** (1) TRANSACTION:
TRANSACTION D20847, ACTIVE 141 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s)
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1818124 localhost root statistics
select * from test_deadlock where id=2 for update
TRANSACTION D20847, ACTIVE 141 sec starting index read:这行表示事务D20847,ACTIVE 141 sec表示事务处于活跃状态141s,starting index read表示正在使用索引读取数据行
mysql tables in use 1, locked 1#这行表示事务D20847正在使用1个表,且涉及锁的表有1个
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s) #这行表示在等待3把锁,占用内存376字节,涉及2行记录,如果事务已经锁定了几行数据,这里将会有一行信息显示出锁定结构的数目(注意,这跟行锁是两回事)和堆大小,堆的大小指的是为了持有这些行锁而占用的内存大小,Innodb是用一种特殊的位图表来实现行锁的,从理论上讲,它可将每一个锁定的行表示为一个比特,经测试显示,每个锁通常不超过4比特
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1818124 localhost root statistics #这行表示该事务的线程ID信息,操作系统句柄信息,连接来源、用户
select * from test_deadlock where id=2 for update #这行表示事务涉及的SQL
5.2.2 下面这一部分显示的是当死锁发生时,第一个事务正在等待的锁等信息:
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: #这行信息表示第一个事务正在等待锁被授予
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20847 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20847 lock_mode X locks rec but not gap waiting#这行信息表示等待的锁是一个record lock,空间id是441,页编号为3,大概位置在页的72位处,锁发生在表xiaoboluo.test_deadlock的主键上,是一个X锁,但是不是gap lock。 waiting表示正在等待锁
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 #这行表示record lock的heap no 位置
#这部分剩下的内容只对调试才有用。
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
5.2.3 下面这部分是事务二的状态:
*** (2) TRANSACTION:
TRANSACTION D20853, ACTIVE 119 sec starting index read #事务2处于活跃状态119s
mysql tables in use 1, locked 1 #正在使用1个表,涉及锁的表有1个
3 lock struct(s), heap size 1248, 2 row lock(s) #涉及3把锁,2行记录
MySQL thread id 20081, OS thread handle 0x7f0a0f020700, query id 1818204 localhost root statistics
select * from test_deadlock where id=1 for update #第二个事务的SQL
5.2.4 下面这部分是事务二的持有锁信息:
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 #从这两行持有锁信息计息后面几行调试信息上看,就是事务1正在等待的锁。
5.2.5 下面这部分是事务二正在等待的锁,从下面的信息上看,等待的是同一个表,同一个索引,同一个page上的record lock X锁,但是heap no位置不同,即不同的行上的锁:
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000001; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab0110; asc ;;
3: len 4; hex 00000001; asc ;;
*** WE ROLL BACK TRANSACTION (2) #这个表示事务2被回滚,因为两个事务的回滚开销一样,所以选择了后提交的事务进行回滚,如果两个事务回滚的开销不同(undo 数量不同),那么就回滚开销最小的那个事务。
本文参考:
MYSQL官方说明文档
小萝卜博客-mysql之show engine innodb status解读