监控DB由于使用的TokuDB引擎,因此选择使用Percona MySQL 5.7版本,在使用过程中遇到了比较多的坑,在这里做一下简单的记录,希望对广大DBA有帮助。
load文件飙升导致的DB雪崩
在上层机器(mqproxy)出问题的时候,会导致load文件飙升,导致监控DB大量的load线程堆积,造成监控DB雪崩,比如2月15号的一次异常:
DB雪崩的时候有大量的load线程堆积,并且机器的写入性能之前下降,直到超过最大连接数,业务无法访问。
这种场景的解决办法有两个:
1、业务上层进行控制,对DB进行保护,控制load的线程数或者文件数
2、DB启用线程池,控制DB并发load的线程数
目前DB已经完成2的改造,1的改造也正在进行中。
使用线程池内存问题
出于对DB做保护,我们准备在监控DB启用线程池功能。为了安全起见,先在从机启用,并进行持续观察,在观察的过程中发现在启用了线程池以后,内存飙升了8G左右,如下图:
不但启用线程池后内存飙升了8G左右,而且内存还在持续增长,很明显启用线程池后存在内存泄漏了。
这个问题在网上也有不少的人遇到,确认是percona的bug导致(https://jira.percona.com/browse/PS-3734),只有开启Performance_Schema和ThreadPool的时候才会出现,解决办法是关闭Performance_Schema即可,具体操作方法是在配置文件添
加performance_schema=off
然后重启MySQL就OK。下面是关闭PS后的内存使用情况对比:
线程池启用后的高可用探测问题
在描述问题之前,先来描述一下线程池是如何分配连接和控制的:
线程池会根据参数thread_pool_size的大小分成若干的group,每个group各自维护客户端发起的连接,当客户端发起连接到MySQL的时候,MySQL会跟进连接的线程id(thread_id)对thread_pool_size进行去模,从而落到对应的group。thread_pool_oversubscribe参数控制每个group的最大并发线程数,每个group的最大并发线程数为thread_pool_oversubscribe+1个,若对应的group达到了最大的并发线程数,则对应的连接就需要等待。
在线上配置了几组机器使用线程池后,发现有1组机器发生自动切换,排查了机器的负载、MySQL错误日志、操作系统日志、高可用日志以后,确定是由于启用线程池问题导致,具体的原因描述如下:
启用线程池以后,相当于限制了MySQL的并发线程数,当达到最大线程数的时候,其他的线程需要等待,新连接也会卡在连接验证那一步,这时候会造成拨测程序连接MySQL超时,拨测程序连接实例超时后,就会认为master已经出现问题,从而启动自动切换的操作,将业务切换到从机。
这种情况有两种解决办法:
1、启用MySQL的旁路管理端口,监控和高可用相关直接使用MySQL的旁路管理端口
具体做法为是在my.cnf中添加如下配置后重启,就可以通过旁路端口登录MySQL了,不受线程池最大线程数的影响:
extra_max_connections = 8
extra_port = 33333
备注:建议启用线程池后,这个也添加上,方便紧急情况下进行故障处理。
2、修改高可用探测脚本,将达到线程池最大活动线程数返回的错误做异常处理,类似于当作超过最大连接数的场景(备注:超过最大连接数只告警,不进行自动切换)
监控这边选择了解决方法2,因为这种方式改动量最小。
简单总结
以上就是最近使用Percona MySQL时候遇到的几个问题,通过这几个问题概括出几个需要广大DBA们注意的事情:
1、上层应该对DB进行保护,防止DB出现雪崩
2、在上新功能的时候,一定记得灰度、灰度、灰度
3、灰度的时候,注意密切观察线上DB的性能指标(内存、性能、IO以及其他和变更相关的指标)
4、综合考虑各种解决方案,选择最适合的方案