data_locks 表显示了持有和请求的数据锁。关于哪些锁请求被哪些持有的锁阻塞的信息。
示例数据锁信息:
mysql> SELECT * FROM performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 139664434886512:1059:139664350547912
ENGINE_TRANSACTION_ID: 2569
THREAD_ID: 46
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 139664350547912
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 2. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 139664434886512:2:4:1:139664350544872
ENGINE_TRANSACTION_ID: 2569
THREAD_ID: 46
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: GEN_CLUST_INDEX
OBJECT_INSTANCE_BEGIN: 139664350544872
LOCK_TYPE: RECORD
LOCK_MODE: X
LOCK_STATUS: GRANTED
LOCK_DATA: supremum pseudo-record
与大多数Performance Schema数据收集不同,没有用于控制是否收集数据锁信息的工具或用于控制数据锁表大小的系统变量。Performance Schema收集的是服务器中已经可用的信息,因此生成这些信息不需要额外的内存或CPU开销,也不需要控制其收集的参数。
在高并发负载期间出现性能问题时,使用data_locks表来帮助诊断。
data_locks表有以下列:
-
ENGINE
持有或请求锁的存储引擎。
-
ENGINE_LOCK_ID
存储引擎持有或请求的锁的ID。 (ENGINE_LOCK_ID, ENGINE)值对是唯一的。
锁ID格式是内部的,并且可能随时改变。应用程序不应依赖于锁ID具有特定的格式。
-
ENGINE_TRANSACTION_ID
请求锁的事务的存储引擎内部ID。可以认为是锁的所有者,尽管锁可能仍在等待,还没有实际被授予(LOCK_STATUS='WAITING')。
如果事务尚未执行任何写操作(仍被视为只读),该列包含用户不应尝试解释的内部数据。否则,该列为事务ID。
对于InnoDB,要获取有关事务的详细信息,请将此列与INFORMATION_SCHEMA INNODB_TRX表的TRX_ID列连接起来。
-
THREAD_ID
创建锁的会话的线程ID。要获得有关线程的详细信息,请将此列与Performance Schema threads表的THREAD_ID列连接起来。
THREAD_ID可以与EVENT_ID一起使用,以确定在内存中创建锁数据结构的事件。(如果用于存储多个锁,则该数据结构的创建可能在此特定锁请求发生之前。)
-
EVENT_ID
导致锁的Performance Schema事件。 (THREAD_ID, EVENT_ID)值对隐式地标识其他Performance Schema表中的父事件:
- events_waits_xxx表中的父等待事件
- events_stages_xxx表中的父阶段事件
- events_statements_xxx表中的父语句事件
- events_transactions_current表中的父事务事件
要获得有关父事件的详细信息,请将THREAD_ID和EVENT_ID列与相应父事件表中同名的列连接起来。
-
OBJECT_SCHEMA
包含锁定表的模式。
-
OBJECT_NAME
锁定的表的名称。
-
PARTITION_NAME
锁定的分区名称(如果有);否则为NULL。
-
SUBPARTITION_NAME
锁定的子分区名称(如果有);否则为NULL。
-
INDEX_NAME
锁定的索引的名称(如果有);否则为NULL。
在实践中,InnoDB总是创建一个索引(GEN_CLUST_INDEX),所以对于InnoDB表,INDEX_NAME非NULL。
-
OBJECT_INSTANCE_BEGIN
锁在内存中的地址。
-
LOCK_TYPE
锁的类型。
该值依存储引擎而定。对于InnoDB,允许的值是RECORD(行级锁),TABLE(表级锁)。
-
LOCK_MODE
如何请求锁。
该值依存储引擎而定。对于InnoDB,允许的值是S[,GAP], X[,GAP], IS[,GAP], IX[,GAP], AUTO_INC及UNKNOWN。除AUTO_INC和UNKNOWN外的锁模式,如果存在,表示间隙锁。
-
LOCK_STATUS
锁请求的状态。
该值依存储引擎而定。对于InnoDB,允许的值是GRANTED(锁被持有)和WAITING(锁正在等待)。
-
LOCK_DATA
与锁相关联的数据(如果有)。该值依存储引擎而定。对于InnoDB,如果LOCK_TYPE是RECORD,会显示一个值,否则该值为NULL。在主键索引上放置锁时,显示被锁记录的主键值。在次级索引上放置锁时,显示被锁记录的次级索引值,并附加上主键值。如果没有主键,LOCK_DATA将显示选择的唯一索引的键值或独特的InnoDB内部行ID号码,根据InnoDB聚簇索引使用的规则。如果包含被锁记录的页面不在缓冲池中,因为在持有锁的同时它被写入磁盘,InnoDB不会从磁盘获取页面。相反,LOCK_DATA报告为NULL。
data_locks表有以下索引:
- 主键索引(ENGINE_LOCK_ID, ENGINE)
- 普通索引(ENGINE_TRANSACTION_ID, ENGINE)
- 普通索引(THREAD_ID, EVENT_ID)
- 普通索引(OBJECT_SCHEMA, OBJECT_NAME, PARTITION_NAME, SUBPARTITION_NAME)
不允许对data_locks表进行TRUNCATE TABLE操作。 注意
在MySQL 8.0.1之前,类似于Performance Schema data_locks表的信息可在INFORMATION_SCHEMA.INNODB_LOCKS表中获得,该表提供了InnoDB事务请求但尚未获得的每个锁的信息,以及阻止另一个事务的每个事务持有的锁的信息。INFORMATION_SCHEMA.INNODB_LOCKS已被弃用,并在MySQL 8.0.1版本中移除。应该改用data_locks表代替。
INNODB_LOCKS和data_locks之间的差异:
- 如果事务持有锁,仅当另一个事务正在等待它时,INNODB_LOCKS才会显示锁。data_locks无论是否有事务正在等待都会显示锁。
- data_locks表没有对应LOCK_SPACE, LOCK_PAGE或LOCK_REC的列。
- INNODB_LOCKS表需要全局PROCESS权限。data_locks表需要通常的Performance Schema权限,即在要选取的表上有SELECT权限。