请听题:

“MySQL是一主两从架构,现在接到IAAS部门反馈数据盘坏了一块,计划凌晨去机房更换硬盘,DBA说保险起见,还是跟业务对接一下,切数据库做一次割接更为稳妥。JAVA架构师采纳了DBA的意见,问什么时候切库割接,DBA说晚上22点吧,在家弄就行。于是晚上22点,DBA跟JAVA师说,我现在要切库,大约10几秒完事。结果很顺利,VIP漂移成功DBA查看应用连接已经正常在新的主库上查询。但仅仅过了10分钟,业务部门反馈说打开APP很卡,JAVA架构师一脸懵逼,说我这边没问题啊?问DBA你更改什么了? DBA反馈说我从库是好好的,我就切换了一下主从角色,我不可能修改数据配置。但当JAVA研发从日志中发现很多慢SQL,并且都是一些很简单的单表查询的SQL,并且确实都走了索引。


请问,你现在做为JAVA的总架构师P8,这个棘手问题,你怎么诊断?到底是哪个环节出了问题?


BTW:主库和从库的数据是一致的,没有延迟。”


P0事故原因:

由于从库innodb_buffer_pool里还没有缓存热数据,当DBA实施了主从数据库切换角色后,从库的Innodb_buffer_pool热点数据还没有加载进去,固当业务高并发读写时,会从磁盘里加载数据到Innodb_buffer_pool里,导致磁盘转数升高,引起的普通sql都变慢了,直到热点数据全部加载到内存里,业务才恢复正常。


面临一个问题,如何将之前频繁访问的数据重新加载回buffer中?(也就是说,如何对innodb buffer pool进行预热,以便于快速恢复到之前的性能状态?)


破:

1)在数据库切换前,在新主库上,通过手工执行下列语句,把热数据加载到Innodb_Buffer_Pool缓冲池里进行预热。

select count(*) from 热点表;

2)在数据库切换前,在源主库上,把热数据dump到本地磁盘,会把内存中的热数据保存在磁盘的ib_buffer_pool文件里。

mysql> set global innodb_buffer_pool_dump_now = 1;

面试题:切库后MySQL为什么会变慢?_数据

3)把ib_buffer_pool文件拷贝到新主库上,并采用手工方式把热数据加载到内存里。

mysql> set global innodb_buffer_pool_load_now = 1;

面试题:切库后MySQL为什么会变慢?_数据_02

这样,主从切换后,主库上的热点数据会始终保存在切换后的新主库内存中。

参考官方文献:https://dev.mysql.com/doc/refman/8.0/en/innodb-preload-buffer-pool.html