MySQL 创建触发器引起的元数据锁
1,583 total views, 2 views today
同事反映,在主库使用pt-online-schema-change工具修改字段长度时,引起三个从库中的一个从库产生了元数据锁,此时一个创建触发器的语句在等待获取元数据(Waiting for table metadata lock)。
pt-online-schema-change执行时,会创建三个触发器,用于数据同步,分别是insert、update、delete触发器。
同事在描述问题时,我脑子中蹦出来的场景:从库中有一个长时间没有执行完的查询操作,此时这个表上有DDL操作,然后DDL操作需要获取元数据锁,就要产生了元数据锁等待(Waiting for table metadata lock)。
这个场景很常见,也是产生元数据锁等待的最常见的场景。
但是,创建触发器会需要获取元数据锁吗? 为了破解这个疑问,我做了实验,步骤如下:
1、sysbench创建一个500万行数据的表sbtest1
2、在sbtest1表上执行笛卡尔查询,执行时间很久
1 |
select * from sbtest1 t1,sbtest1 t2; |
3、pt-online-schema-change工具执行修改字段长度操作
1 |
pt-online-schema-change --no-version-check --critical-load="Threads_running=200" --chunk-size=5000 --user=sbtest --password='sbpass' --host=10.0.114.232 P=3307,D=sbtest,t=sbtest1 --alter "modify c char(230) " --progress=time,5 --recursion-method=none --charset=utf8 --execute |
4、产生了元数据锁
1 2 3 4 5 6 7 8 9 10 |
+-----+-------------+------------------+--------+---------+---------+-----------------------------------------------+------------------------------------------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +-----+-------------+------------------+--------+---------+---------+-----------------------------------------------+------------------------------------------------------------------------------------------------------+ | 90 | system user | | NULL | Connect | 4554221 | Reconnecting after a failed master event read | NULL | | 115 | root | localhost | sbtest | Query | 91 | Sending to client | select * from sbtest1 t1,sbtest1 t2 | | 116 | sbtest | 10.0.2.140:39491 | sbtest | Query | 27 | Waiting for table metadata lock | CREATE TRIGGER `pt_osc_sbtest_sbtest1_del` AFTER DELETE ON `sbtest`.`sbtest1` FOR EACH ROW DELETE IG | | 117 | sbtest | 10.0.2.140:39492 | sbtest | Sleep | 88 | | NULL | | 118 | root | localhost | NULL | Query | 0 | starting | show processlist | +-----+-------------+------------------+--------+---------+---------+-----------------------------------------------+------------------------------------------------------------------------------------------------------+ 6 rows in set (0.04 sec) |
结论:
创建触发器,同样需要获取到对应表的元数据锁。这点要在日常运维工作中引起我们的重视。