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
。Performance Schema 按前面描述的方式分配这些值。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
。