记一次Flink CDC引起的Mysql元数据锁事故,总结经验教训。后续在编写Flink CDC任务时,要处理好异常,避免产生长时间的元数据锁。同时出现生产问题时要及时排查,不能抱有侥幸心理。
1、事件经过
某天上午,收到系统的告警信息,告警提示:同步Mysql的某张表数据到Elasticsearch异常,提示连不上Mysql,当时没有太上心,以为可能是偶尔网络异常。
然后立马大量用户开始投诉系统使用有问题,同时听到有同事反馈内部系统数据导不出来。此时我慌了。
立马看了微服务网关、用户中心服务、部分流量比较大的BFF层服务,CPU、内存、磁盘等都是正常的。但是Pod出现了健康检查失败的情况。
于是又赶紧看了日志,出现了大量拿不到Mysql Connection异常。
又赶紧看了Mysql情况,CPU、内存、磁盘都是正常的,但是出现了许多奇怪的慢SQL。
此时我大概猜测到了可能是什么操作锁表了,导致大量Connection无法释放,又赶紧看了Mysql锁的情况,果然发现了大量的元数据锁,高达400多个Connection没释放。
2、处理步骤
FLUSH TABLES WITH READ LOCK
导致的,跟Nacos无关,Nacos只是个烟雾弹。# Flink相关的:
SHOW CREATE TABLE `xxx_db`.`xxx_table`;
FLUSH TABLES WITH READ LOCK;
# Nacos相关的:
DELETE FROM config_info WHERE data_id='com.alibaba.nacos.testMasterDB';
3、原因分析
3.1、元数据锁
-
以上关于锁的截图,可以看到是元数据锁引发的Connection被耗尽,那什么是元数据锁:
- 元数据锁(Meta Data Lock,MDL),用于锁定数据库对象的元数据,例如:表、索引、视图等的结构信息。通常用于保证并发的数据定义语言(DDL)操作的一致性,防止在修改表结构的过程中出现并发问题。
- 其作用是用于解决DDL操作与DML操作的一致性;通常,DDL操作需要获取MDL写锁,并且MDL锁一旦发生,就可能会对数据库的性能影响,因为后续对该表的任何Select、DML、DDL操作都会被阻塞,造成Connection积压。
-
为什么要有元数据锁:
- 主要为了保证元数据的一致性,用于处理不同线程操作同一数据对象的同步与互斥问题。比如需要事务隔离场景、主从同步场景。
-
元数据锁和Innodb锁的区别:
- 元数据锁主要关注数据库对象的元信息,而InnoDB锁主要关注数据的一致性和隔离性。
- MDL锁还能实现其他粒度级别的锁,比如:全局锁、库级别的锁、表空间级别的锁。这是InnoDB存储引擎不能直接实现的。
-
锁表的原理是数据库使用独占式锁机制。锁表发生在 insert、update、delete中。比如:A程序执行了对table_1的insert、update、delete,并还未commit时,B程序也对table_1进行insert、update、delete时会发生资锁表。
3.2、Flink CDC为什么引起元数据锁事故
笔者使用Flink场景是,利用Flink CDC同步数据,然后做汇总统计。
MySQL CDC如何工作
FLUSH TABLES WITH READ LOCK
,获取一个全局读取锁,防止其他会话对这些表进行写操作,从而保证捕获的数据的一致性和准确性。该锁将阻止其他写入操作。元数据锁原因
FLUSH TABLES WITH READ LOCK
直接上读取锁,由于时间较长,此时有大量的insert、update、delete操作一直处于等待,导致Mysql Connection无法释放。DELETE FROM config_info WHERE data_id='com.alibaba.nacos.testMasterDB'
呢?查阅资料后发现,Nacos也是从Mysql获取Connection的,当Mysql出现问题时,比如死锁、Connection耗尽、CPU打满时,都会执行这个SQL。======>>>>>> 关于我 <<<<<<======
本篇完结!欢迎点赞 关注 收藏!!!