背景:
晚上,公司业务群里发信息说,有玩家在游戏里面赠送别人礼物后,赠送记录在20多分钟以后才出现,延时太高。
问题:
公司数据库使用mysql,配置了主从。配置的是,游戏程序写数据到主库,读数据到从库。
数据库服务器主:A
数据库服务器从:B
1.首先查看了A主上面的赠送记录的库,发现都是正常的。然后查看B从上面赠送记录的库,发现有几个表没有通过过来。
2.在B从上面查看,从数据库是否正常: show slave status\G;发现如下问题:
根据上面圈出来的参数发现:主从存在延迟,主库执行到了mysql-bin-000077,而从库才执行到mysql-bin-000070,也可以从执行的位置,上面两个_POS看出来有延迟,根据Seconds_Behind_Master发现,大约有365360的延迟。
由上面分析可以发现,从库B虽然已经从主库拉取了所有的binlog,但是执行却没有完成。
show processlist;发现Slave_SQL线程处于:Reading event from the relay log.
经查找发现:由于主库可以并发执行,而从库只有一个slave_sql线程来进行执行,所以当事务多的时候,从库来不及处理就会出现以上情况。
查找是哪些资源到了瓶颈:
top发现,loadavg平均在1.7左右,内存,cpu都没有异常。cpu行中的wa%却有些偏高。'状态列'有一个程序处于D状态,即不可终端的睡眠。状态D,一般是由于wait IO造成的所谓“非中断睡眠”。
用iostat, $iostat -x 1 10 发现IO utils%一直出于70%-99%之间,发现是系统IO达到了瓶颈。
用iotop查看是哪些进程在频繁的进行IO操作,发现是mysqld和jdb2/dm-2-8
进行相关的优化:
由于主数据库上面也有IO瓶颈,同样是上面两个进程。
进入mysql查看show processlist,发现有1500多个任务,大部分处于sleep状态。(发现了之前公司业务发的,有些玩家登录不上游戏的原因,( ╯□╰ )),mysql配置中,max_connection最大连接数设置的才只有2000,所以很容易到达,然后满了后玩家就进不来了。
对于sleep任务太多的处理:(1)程序里每次连接数据库后,记得关闭数据库。(2)或者,在mysql配置文件中,设置mysql超时时间wait_timout,默认是八小时,设置低一点。