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=https://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: [<ffffffff8154b203>] io_schedule+0x73/0xc0 [<ffffffff811dabcd>] __blockdev_direct_IO_newtrunc+0xb7d/0x1270 [<ffffffffa00831e4>] ? do_get_write_access+0x3b4/0x520 [jbd2] [<ffffffffa00ac4a0>] ? ext4_get_block+0x0/0x120 [ext4] [<ffffffff811db337>] __blockdev_direct_IO+0x77/0xe0 [<ffffffffa00ac4a0>] ? ext4_get_block+0x0/0x120 [ext4] [<ffffffffa00ab29a>] ext4_ind_direct_IO+0xba/0x250 [ext4] [<ffffffffa00ac4a0>] ? ext4_get_block+0x0/0x120 [ext4] [<ffffffffa00ab486>] ext4_direct_IO+0x56/0x260 [ext4] [<ffffffffa00c1998>] ? __ext4_journal_stop+0x68/0xa0 [ext4] [<ffffffffa00ab0df>] ? ext4_dirty_inode+0x4f/0x60 [ext4] [<ffffffff8112f222>] generic_file_direct_write+0xc2/0x190 [<ffffffff81130b41>] __generic_file_aio_write+0x3a1/0x490 [<ffffffff811b9384>] ? notify_change+0x234/0x340 [<ffffffff81130cb8>] generic_file_aio_write+0x88/0x100 [<ffffffffa00a4ef8>] ext4_file_write+0x58/0x190 [ext4] [<ffffffff81199aba>] do_sync_write+0xfa/0x140 [<ffffffff810a6930>] ? autoremove_wake_function+0x0/0x40 [<ffffffff811ec895>] ? fcntl_setlk+0x75/0x320 [<ffffffff8123adc6>] ? security_file_permission+0x16/0x20 [<ffffffff81199db8>] vfs_write+0xb8/0x1a0 [<ffffffff8119a42a>] sys_pwrite64+0x7a/0x90 [<ffffffff8100b0d2>] 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能力
上一篇: 披著羊皮的大野狼 - Session