Posts tagged ‘binlog’

主备备的两个备机转为双master时出现的诡异slave lag问题

有三台MySQL服务器,a,b和c,复制关系为 a -> b -> c。a,b,c的server_id分别为1,2,3
因为需要切换为 a b <-> c,也就是说,a单独出来,b和c作为双master结构时。
这种切换会经常出现在需要搭建备机把数据备份出来,然后把a独立出来的case中。

昨天,我就做了这样的切换,结果发现出现莫名奇妙的slave lag。
Seconds_Behind_Master一下子为0,一下子变成几千秒。
使用mysqlbinlog查看,binlog日志里面也有很多时间在几小时以前的event数据。
为了验证复制是否正常,我特别测试了一下,在b建一个表,并插入时间数据,到c上一看,表已经复制过来了,时间数据也是正确。
询问了一下同事,他说应该是MySQL的bug,在这种切换的情况下很容易触发这个bug,可以采用stop slave;change master; start slave;的方法来修复。但是实际的数据其实完全没有影响,复制还是正常的。

于是我按照这个办法:
stop slave io_thread;
stop slave;
show slave status\G
(这里先停io_thread是为了SQL thread和IO thread都执行到了同一个位置,change master 的时候没有风险)
stop slave;change master to … ; start slave;
(change master到show slave status的Master_Log_File:和Exec_Master_Log_Pos:位置,也就是说,其实根本没有改变复制的位置)

结果slave lag依然故我。这个问题就比较郁闷了。时间已经过了午夜,脑袋也转不动了,想过不管它了,反正复制没有问题。但是问题没有解决总觉得什么东西卡在喉咙一样。各种资料,各种变量都参考了一遍,最后,基本不太意识的输入:
show master logs;
show binlog events in ‘mysql-bin.000680’ from 34385301;
想看看最新产生的event,结果就发现不对的地方了。
这个最新产生的event有很多,并且server_id是1,1是a的server_id啊,应用访问的是b啊,怎么会在b上面产生a的server_id列,MySQL哪里出问题了?

仔细一想,明白了,事情是这样的:
a -> b -> c,a的event1(server_id为1)复制到b,也会复制到c,这个是正常的。
然后搭建c -> b的复制关系时,b需要断开a的连接,切换主库到c,在 change master 的位置在event1出现之前,那么event1肯定会被重新复制到b去,event1的server_id是1,那么b判断,这个event1不是我提交的,需要在本地执行,并且把它记录到了自己的binlog中;
由于b和c是双master结构,event1又复制到了c,c同样判断它不是我提交的,那么我需要在本地执行,并且记录到本地binlog中。
这样event1就在b和c之间循环往复,时间保持不变,MySQL的slave lag也就一下子是0,一下子是几千秒了。

这里,还需要说明一点,在环型复制里面,event之所以能够在环内只循环一次,而不是重复做,是因为提交的那个节点会发现这个event的server_id是自己的server_id,也就是说是自己提交的。那么,它就不会把这个event再应用一次,自然也不会记录到binlog。这个循环就结束了。除非你闲着没事做,设置了replicate-same-server-id参数。

那么解决问题怎么办列,很简单,把没有应用访问的c的server_id设置成a的server_id:
set global server_id=1;
看看时间差不多了,server_id为1的event都被干掉以后:
set global server_id=3;
然后再设置回来。
还好,MySQL 5.0和5.1的server_id都是动态的。

may your success.

一个目录chmod造成的血案

最近团队的可用性一直没有上去,把自己之前差点造成故障的一个事情翻出来,好好看一下,提高警惕。

2010年5月25日。艳阳高照。但是我的心却是拔凉拔凉的。执行了一个授权和chmod的操作,由于是批量执行,结果导致大量MySQL数据库报警,出现了重大的问题。
事情得从头说起。为了配合sa部门管理机器和收回主机root权限,我们想去将admin用户添加到mysql组里,并统一一下MySQL数据库的目录,以及相关的权限。于是我写了一个简单的脚本如下:

id admin
usermod -G mysql admin
id admin
groups admin

chown -R mysql:mysql /var/lib/mysql
chown -R mysql:mysql /home/mysql
chown -R mysql:mysql /data/mysqldata

chmod -R 770 /var/lib/mysql
chmod -R 770 /var/lib/mysql/etc
chmod -R 770 /var/lib/mysql/log
chmod -R 770 /var/lib/mysql/sock

chmod 750 /data
chmod 750 /data/mysqldata
chmod 700 /data/mysqldata/mydata
chmod 700 /data/mysqldata/innodb_log
chmod 700 /data/mysqldata/innodb_ts
chmod 750 /data/mysqldata/binlog
chmod 750 /data/mysqldata/relaylog
chmod 750 /data/mysqldata/tmpdir

按照惯例,我提交了变更,简单测试了一下,并在pm-my1b生产机器上先执行了一下,看看,没有什么问题。然后就分发到所有的pm,offer,comm,ai等一批机器上去。于是悲剧产生了,数据库报警。一看MySQL
的报警,
sort aborted
这个报警是由于mysql访问它的tmpdir出现问题导致的。判断是由于文件权限导致的。赶紧修改脚本,给刚才附权的所有目录修改为750.后来一想,还是不放心。干脆把所有的权限都给它们了。777。部分数据库没有报警了。

我们认真检查了一下数据库。发现部分MySQL不能写自己的日志。show master logs显示
root@localhost : (none) 10:24:01> show master logs;
ERROR 1381 (HY000): You are not using binary logging
没有打开binlog写日志的功能。应该就是由于目录权限的问题,MySQL自动把写binlog日志的功能停掉了;而它对应的备机则由于这个问题,show slave status\G会卡死在那边。这样的话,如果不写binlog的MySQL数据库是应用访问的机器,那么现在它就是单点(备机无法获得binlog日志,自然无法同步数据),这种情况对应用来说其实是不可以接受的,当然,运气还好,MySQL没有直接crash,或者启动不起来。多谢donny的招财猫保佑阿。但是这个问题的严重性可想而知。由于短时间内没有什么特别好的办法让MySQL自己再启动binlog的日志写,并且单点的情况不能这样一直持续下去。所以我们只好联系cobar和应用人员,申请停机,并重搭备机和复制。朝阳帮忙联系中文站的,我联系itbu的。中文站的offer重要性从朝阳打的电话数就可以看出来…….这回真是搞大了。

我和朝阳最终确定了offer重启的步骤。并文档化下来,以预先计划好重启过程中步骤和可能出现的问题。

pm同样的有这个问题,我们10点半的时候尝试了一下修复pm的一套同样出问题的机器。结果发现了问题的根源所在。chmod 750 /data这个东西导致了数据库不能访问对应的文件夹。/data这个目录是root创建的,它的属主和属组为root:root。当mysql尝试进入这个目录的时候,它是作为“other”进去的,而other的权限是0。所以无法访问/data目录,就算/data里面的mysqldata是mysql:mysql的。最终我们整理好了最终修改目录权限的命令组。修改以后重启MySQL;MySQL正在运行的时候修改目录属性两种方式下,MySQL都不会出现问题了。

另外,我们还尝试几种办法,想让MySQL自己把记录binlog的方法启动起来,结果都失败了:
1、flush logs; 命令执行成功,但是MySQL没有启动log_bin
2、reset master;
执行报错:
root@localhost : (none) 10:24:09> reset master;
ERROR 1186 (HY000): Binlog closed, cannot RESET MASTER

最终还是不得不在凌晨0点和2点分别对offer和pm应用的MySQL服务器重启了MySQL主备机。重启的过程比较顺利,基本在3-5分钟之内,应用就重新连过来了。

这次的出问题的教训和以后需要注意的问题:
1、修改文件,目录的权限,属组,属主的时候需要特别注意,特别是正在提供应用服务的进程需要访问的目录。
2、当需要大规模部署的时候,需要充分测试。我这边虽然在pm-my1b MySQL机器上测试过了,但是由于它是备机,写压力和对文件的访问没有那么频繁,所以短时间内也看不出什么问题。如果在一台主机上在测试一下,也许就会发现问题。
3、拜DBA团队的保护神“招财猫”的时候,要心诚。不能心里还在挂着苍井空,饭岛爱。

附一、offer两台出问题的主机MySQL重启详细步骤如下:
目前主要是两套机器需要停止重启。第4套和第8套。
先停止第四套,然后操作第八套。
停止第4套的操作如下:
1、11点,设置主机(xy-offer-db4b    172.22.32.40)的dirty page为0;因为备机没有数据应用,所以备机不用设置这个。
set global innodb_max_dirty_pages_pct = 0;
2、检查主机(xy-offer-db4b    172.22.32.40)dirty page数是否一直在减少。
mysqladmin -uroot  ext -i3 | grep dirty
3、11点30分,停止备机(xy-offer-db4c    172.22.32.56 )的mysql
service mysql stop
4、12点。主机(xy-offer-db4b    172.22.32.40)flush tables将数据刷入磁盘:
登录mysql: flush tables。
5、刷新成功后,停止和重启主机(xy-offer-db4b    172.22.32.40)的mysql
service mysql stop
service mysql start
6、检查主机(xy-offer-db4b    172.22.32.40)mysql启动是否有错误。有错误及时修复。
正常的文件夹权限为:
drwxr-xr-x   5 root root  4096 May 25 22:13 data
drwxr-xr-x 3 mysql mysql  4096 Dec 25  2008 mysqldata
drwxr-xr-x 2 mysql mysql 4096 May 24 15:15 binlog
drwxr-xr-x 2 mysql mysql 4096 Feb 24 15:13 innodb_log
drwxr-xr-x 2 mysql mysql 4096 Feb 24 15:13 innodb_ts
drwxr-xr-x 2 mysql mysql 4096 Feb 24 15:13 relaylog
drwxr-xr-x 7 mysql mysql 4096 May 24 08:05 mydata
drwxr-xr-x 2 mysql mysql 4096 May 25 11:08 tmpdir
drwxr-xr-x  26 root root  4096 May 25 22:16 var
drwxr-xr-x 26 root root  4096 Feb 26 14:58 lib
drwxr-xr-x 12 mysql mysql 4096 Feb 24 11:07 mysql
drwxr-xr-x  2 mysql mysql 4096 Mar  4 17:12 sock
drwxr-xr-x  2 mysql mysql 4096 Apr 28 09:51 log
7、检查cobar连接是否有问题。
8、检查应用连接是否有问题。
然后检查第8套。
1、11点,设置主机(xy-offer-db8c    172.22.32.60)的dirty page为0;因为备机没有数据应用,所以备机不用设置这个。
set global innodb_max_dirty_pages_pct = 0;
2、检查主机(xy-offer-db8c    172.22.32.60)dirty page数是否一直在减少。
mysqladmin -uroot  ext -i3 | grep dirty
3、11点30分,停止备机(xy-offer-db8b    172.22.32.44 )的mysql
service mysql stop
4、12点。主机(xy-offer-db8c    172.22.32.60)flush tables将数据刷入磁盘:
登录mysql: flush tables。
5、刷新成功后,停止和重启主机(xy-offer-db8c    172.22.32.60)的mysql
service mysql stop
service mysql start
6、检查主机(xy-offer-db8c    172.22.32.60)mysql启动是否有错误。有错误及时修复。
正常的文件夹权限为:
drwxr-xr-x   5 root root  4096 May 25 22:13 data
drwxr-xr-x 3 mysql mysql  4096 Dec 25  2008 mysqldata
drwxr-xr-x 2 mysql mysql 4096 May 24 15:15 binlog
drwxr-xr-x 2 mysql mysql 4096 Feb 24 15:13 innodb_log
drwxr-xr-x 2 mysql mysql 4096 Feb 24 15:13 innodb_ts
drwxr-xr-x 2 mysql mysql 4096 Feb 24 15:13 relaylog
drwxr-xr-x 7 mysql mysql 4096 May 24 08:05 mydata
drwxr-xr-x 2 mysql mysql 4096 May 25 11:08 tmpdir
drwxr-xr-x  26 root root  4096 May 25 22:16 var
drwxr-xr-x 26 root root  4096 Feb 26 14:58 lib
drwxr-xr-x 12 mysql mysql 4096 Feb 24 11:07 mysql
drwxr-xr-x  2 mysql mysql 4096 Mar  4 17:12 sock
drwxr-xr-x  2 mysql mysql 4096 Apr 28 09:51 log
7、检查cobar连接是否有问题。
8、检查应用连接是否有问题。

主机检查没有问题。就可以搭备机了,

附二、最终修改文件目录属性的命令组

chown -R mysql:mysql /var/lib/mysql
chmod -R 770 /var/lib/mysql
chmod -R 770 /var/lib/mysql/etc
chmod -R 770 /var/lib/mysql/log
chmod -R 770 /var/lib/mysql/sock

chmod -R 755 /data

chown -R mysql:mysql /data/mysqldata
chmod -R 755 /data/mysqldata
chmod -R 700 /data/mysqldata/mydata
chmod -R 700 /data/mysqldata/innodb_log
chmod -R 700 /data/mysqldata/innodb_ts
chmod -R 750 /data/mysqldata/binlog
chmod -R 750 /data/mysqldata/relaylog
chmod -R 750 /data/mysqldata/tmpdir