MySQL 使用元数据锁来管理对数据库对象的并发访问并确保数据一致性;请参阅 第 10.11.4 节,“元数据锁定”。元数据锁定不仅适用于表,还适用于架构、存储程序(过程、函数、触发器、计划事件)、表空间、使用 GET_LOCK()
函数获取的用户锁(请参阅 第 14.14 节,“锁定函数”),以及使用 第 7.6.9.1 节,“锁定服务” 中所述的锁定服务获取的锁。
Performance Schema 通过 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';
Performance Schema 使用 LOCK_STATUS
列指示每个锁的状态,以下列出 metadata_locks
表内容的维护方式
当请求元数据锁并立即获得时,将插入一条状态为
GRANTED
的行。当请求元数据锁但未立即获得时,将插入一条状态为
PENDING
的行。当先前请求的元数据锁被授予时,其行状态将更新为
GRANTED
。当元数据锁被释放时,其行将被删除。
当死锁检测器取消先前请求的锁请求以打破死锁 (
ER_LOCK_DEADLOCK
) 时,其行状态将从PENDING
更新为VICTIM
。当锁请求超时 (
ER_LOCK_WAIT_TIMEOUT
) 时,其行状态将从PENDING
更新为TIMEOUT
。当授予的锁或挂起的锁请求被杀死时,其行状态将从
GRANTED
或PENDING
更新为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
被监控对象的名称。
OBJECT_INSTANCE_BEGIN
被监控对象在内存中的地址。
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
。性能模式会根据之前描述的规则分配这些值。SOURCE
包含生成事件的被监控代码的源文件名称以及发生监控的代码所在文件的行号。这使您可以检查源代码以确定确切涉及的代码。
OWNER_THREAD_ID
请求元数据锁的线程。
OWNER_EVENT_ID
请求元数据锁的事件。
名为 metadata_locks
的表包含以下索引:
基于 (
OBJECT_INSTANCE_BEGIN
) 的主键基于 (
OBJECT_TYPE
、OBJECT_SCHEMA
、OBJECT_NAME
) 的索引基于 (
OWNER_THREAD_ID
、OWNER_EVENT_ID
) 的索引
对名为 metadata_locks
的表不允许使用 TRUNCATE TABLE
。