MySQL 使用元数据锁定来管理数据库对象的并发访问和确保数据一致性;见 第 10.11.4 节,“元数据锁定”。元数据锁定不仅适用于表,还适用于模式、存储程序(过程、函数、触发器、计划事件)、表空间、用户锁(使用 GET_LOCK()
函数获取的锁,见 第 14.14 节,“锁定函数”),以及锁定服务描述的锁(见 第 7.6.9.1 节,“锁定服务”)。
性能模式通过 metadata_locks
表公开元数据锁信息:
-
已经授予的锁(显示哪些会话拥有当前元数据锁)。
-
尚未授予的锁请求(显示哪些会话正在等待哪些元数据锁)。
-
死锁检测器杀死的锁请求。
-
超时的锁请求,等待请求会话的锁请求被丢弃。
这些信息使您能够了解会话之间的元数据锁依赖关系。您不仅可以看到哪个会话正在等待哪个锁,还可以看到哪个会话当前持有该锁。
该 metadata_locks
表是只读的,不能更新。它默认是自动调整大小的;要配置表大小,请在服务器启动时设置 performance_schema_max_metadata_locks
系统变量。
元数据锁仪表使用 wait/lock/metadata/sql/mdl
仪表,默认情况下启用。
要在服务器启动时控制元数据锁仪表状态,请在 my.cnf
文件中添加以下行:
-
启用:
[mysqld] performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'
-
禁用:
[mysqld] performance-schema-instrument='wait/lock/metadata/sql/mdl=OFF'
要在运行时控制元数据锁仪表状态,请更新 setup_instruments
表:
-
启用:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME = 'wait/lock/metadata/sql/mdl';
-
禁用:
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO', TIMED = 'NO' WHERE NAME = 'wait/lock/metadata/sql/mdl';
性能模式维护 metadata_locks
表内容,如下所示,使用 LOCK_STATUS
列指示每个锁的状态:
-
当元数据锁被请求并立即获得时,插入状态为
GRANTED
的行。 -
当元数据锁被请求但未立即获得时,插入状态为
PENDING
的行。 -
当先前请求的元数据锁被授予时,其行状态更新为
GRANTED
。 -
当元数据锁被释放时,其行被删除。
-
当死锁检测器取消了挂起的锁请求以打破死锁 (
ER_LOCK_DEADLOCK
),其行状态更新为VICTIM
。 -
当挂起的锁请求超时 (
ER_LOCK_WAIT_TIMEOUT
),其行状态更新为TIMEOUT
。 -
当授予的锁或挂起的锁请求被杀死时,其行状态更新为
KILLED
。 -
状态值
VICTIM
、TIMEOUT
和KILLED
是暂时的,表明锁行即将被删除。 -
状态值
PRE_ACQUIRE_NOTIFY
和POST_RELEASE_NOTIFY
是暂时的,表明元数据锁定子系统正在通知感兴趣的存储引擎,而进入锁获取操作或离开锁释放操作。
该 metadata_locks
表具有以下列:
-
OBJECT_TYPE
元数据锁子系统中使用的锁类型。该值是
GLOBAL
、SCHEMA
、TABLE
、FUNCTION
、PROCEDURE
、TRIGGER
(当前未使用)、EVENT
、COMMIT
、USER LEVEL LOCK
、TABLESPACE
、BACKUP LOCK
或LOCKING SERVICE
之一。值为
USER LEVEL LOCK
表示使用GET_LOCK()
获取的锁。值为LOCKING SERVICE
表示使用锁服务获取的锁,如 第 7.6.9.1 节,“锁服务” 所述。 -
OBJECT_SCHEMA
包含对象的模式。
-
OBJECT_NAME
被instrumented 对象的名称。
-
OBJECT_INSTANCE_BEGIN
被instrumented 对象在内存中的地址。
-
LOCK_TYPE
元数据锁子系统中的锁类型。该值是
INTENTION_EXCLUSIVE
、SHARED
、SHARED_HIGH_PRIO
、SHARED_READ
、SHARED_WRITE
、SHARED_UPGRADABLE
、SHARED_NO_WRITE
、SHARED_NO_READ_WRITE
或EXCLUSIVE
之一。 -
LOCK_DURATION
元数据锁子系统中的锁持续时间。该值是
STATEMENT
、TRANSACTION
或EXPLICIT
之一。STATEMENT
和TRANSACTION
值表示在语句或事务结束时隐式释放的锁。EXPLICIT
值表示在语句或事务结束后继续存在的锁,需要明确的操作来释放,例如使用FLUSH TABLES WITH READ LOCK
获取的全局锁。 -
LOCK_STATUS
元数据锁子系统中的锁状态。该值是
PENDING
、GRANTED
、VICTIM
、TIMEOUT
、KILLED
、PRE_ACQUIRE_NOTIFY
或POST_RELEASE_NOTIFY
之一。Performance Schema 按照之前的描述分配这些值。 -
SOURCE
包含instrumented 代码的源文件的名称和行号,该文件在该行号处发生了instrumentation。这使您可以检查源代码以确定确切的代码参与了什么。
-
OWNER_THREAD_ID
请求元数据锁的线程。
-
OWNER_EVENT_ID
请求元数据锁的事件。
The metadata_locks
表具有以下索引:
-
主键在 (
OBJECT_INSTANCE_BEGIN
) -
索引在 (
OBJECT_TYPE
,OBJECT_SCHEMA
,OBJECT_NAME
) -
索引在 (
OWNER_THREAD_ID
,OWNER_EVENT_ID
)
TRUNCATE TABLE
不允许用于 metadata_locks
表。