MySQL多实例从库show slave status卡死

现象描述:
1、MySQL主库进程被莫名挂起,没有错误日志,一个mysqldump执行被阻塞;
2、MySQL从库出现不同步,show slave status看到出现了很多的锁
3、系统vim,ls -l不能使用,mount -a发现磁盘虽然不是只读
4、查看ps -aux看见很多进程的状态(STAT)是D或者是Ds(不可中断的睡眠或等待)或者Z(僵尸进程),说明已经被阻塞
有一些进程是这样的tee -a ~/.bash_history(审计历史命令),状态是D,一般是在ps中捕捉不到
5、系统日志报错,缓存中的数据往磁盘上写超时。(IO速度慢)
6、3306端口的实例,登录不上报错max_user_connections(某个用户可以并发登录数据库的个数)已经达到上限
  3307端口的实例,登陆上发现有很多的show slave status的线程(笔者之前在中控做了很多次的show slave status监控查看,到这个机器就卡死)
  进程被阻塞了

step1、升级内核(centos6.6的2.6.32内核bug会导致线程诡异的挂起)
原来的内核版本:2.6.32-504.el6.x86_64
升级后:2.6.32-696.16.1.el6.x86_64
1、mysqladmin pro 查看连接
2、service mysql stop 关闭数据库
3、export http_proxy=http://10.10.55.4:2137 && yum install kernel -y 升级内核
4、/etc/init.d/iptables save 保存防火墙策略
5、reboot 生效
升级之后发现不会再出现主库进程被莫名挂起的情况了。

但是发现还是并没有彻底解决主从同步会卡的情况
step2、查看dmseg日志发现报错:
INFO: task mysqld:4731 blocked for more than 120 seconds.                --------mysqld进程被阻塞
      Not tainted 2.6.32-696.16.1.el6.x86_64 #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.    ---内核调动
mysqld        D 0000000000000006     0  4731   3274 0x00000000
 ffff8802f93bf878 0000000000000082 ffff8805ffffffff 00000000085ee510
 ffff88053f504040 ffff8802f8cdb670 000000003551d42e ffffffffa5e094c7
 00000000103a0285 ffffffff81aa8400 ffff88053f5045f8 ffff8802f93bffd8
Call Trace:
 [] io_schedule+0x73/0xc0
 [] __blockdev_direct_IO_newtrunc+0xb7d/0x1270
 [] ? do_get_write_access+0x3b4/0x520 [jbd2]
 [] ? ext4_get_block+0x0/0x120 [ext4]
 [] __blockdev_direct_IO+0x77/0xe0
 [] ? ext4_get_block+0x0/0x120 [ext4]
 [] ext4_ind_direct_IO+0xba/0x250 [ext4]
 [] ? ext4_get_block+0x0/0x120 [ext4]
 [] ext4_direct_IO+0x56/0x260 [ext4]
 [] ? __ext4_journal_stop+0x68/0xa0 [ext4]
 [] ? ext4_dirty_inode+0x4f/0x60 [ext4]
 [] generic_file_direct_write+0xc2/0x190
 [] __generic_file_aio_write+0x3a1/0x490
 [] ? notify_change+0x234/0x340
 [] generic_file_aio_write+0x88/0x100
 [] ext4_file_write+0x58/0x190 [ext4]
 [] do_sync_write+0xfa/0x140
 [] ? autoremove_wake_function+0x0/0x40
 [] ? fcntl_setlk+0x75/0x320
 [] ? security_file_permission+0x16/0x20
 [] vfs_write+0xb8/0x1a0
 [] sys_pwrite64+0x7a/0x90
 [] system_call_fastpath+0x16/0x1b

3306实例,显示连接数太多进不了数据库,3307实例的主从状态不正常
3307更改以下两个参数跳过错误,并不能解决问题(中控安装pt工具,校验数据一致,然后同步主从数据)
set global sql_slave_skip_counter =1;
set global slave_skip_errors = 1032;

原因
这个版本的内核 2.6.32 默认情况下会预留内存的 20% (由参数 vm.dirty_ratio 指定)作为 IO 的缓存,当脏页达到这个阈值时,内核会将内存中的数据写到磁盘上。写到磁盘上这个过程是有 120 秒的超时限制的,所以我们看到了 blocked for more than 120 seconds 这句话。

在大内存机器上,比如64G,那么预留给 IO 缓存的内存有 12.8G。如果需要在 120秒内将 12.8G 到磁盘上需要 109MB/s (873Mbit/s) 的写速度,这个在一般磁盘上都很难达到,所以发生了这个问题。

解决办法
1、解决思路,预留的内存减少到比较合适的阈值,比如10%。
链接:https://www.gaott.info/fix-blocked-for-more-than-120-seconds/
把下面内容追加到 /etc/sysctl.conf 文件中。
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
然后
sysctl -p

2、可以使用dd测试顺序IO,fio测试无序IO,检查IO能力
随机读:
time  fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=10G -numjobs=10 -runtime=300 -group_reporting  -name=iotest
随机写:
time fio -filename=/dev/sdb -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=10G -numjobs=10 -runtime=300 -group_reporting -name=iotest  
顺序读:
time fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=4k -size=10G -numjobs=10 -runtime=300 -group_reporting -name=iotest
顺序写:
time fio -filename=/dev/sdb -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=4k -size=10G -numjobs=10 -runtime=300 -group_reporting -name=iotest
dd命令:
time dd if=/dev/zero of=/home/tools/10GB bs=4096 count=2621440
time dd of=/dev/zero if=/home/tools/10GB bs=4096 count=2621440

测试结论:这台虚拟机的IO能力是正常dell物理机IO能力的五分之一

解决方案:
1、减轻从库IO压力,一个从库只放一个实例
2、提高IO能力


你可能感兴趣的:(MySQL)