您的位置:首页 > 数据库 > MySQL

MYSQL主从同步故障一例及解决过程!

2014-01-26 11:09 501 查看
公司里有两个mysql服务器做主从同步,某天Nagios发来报警短信,mysqla
is down...赶紧联系机房,机房的人反馈来的信息是 HARDWARE ERROR 后面信息省略,让机房记下错误信息后让他们帮忙重启下看是不是能正常起来,结果竟然正常起来了,赶紧导出所有数据。

  问题又出现了,nagios 又报警,mysql_AB error,检查从库

  show slave status \G; 果然

  Slave_IO_Running: Yes

  Slave_SQL_Running: No

  而且出现了1062错误,还提示

  Last_SQL_Error: Error 'Duplicate entry '1001-164761-0' for key 'PRIMARY'' on query. Default database: 'bug'. Query: 'insert into misdata (uid,mid,pid,state,mtime) values (164761,1001,0,-1,1262623560)'

  很显然,由于主库重启导致 从库数据不同步而且主键冲突。查看error 日志发现error日志文件变得好大,比以前大了将近好几倍,

  tail -f mysql_error.log 最开始查看到的是这条信息

  发现这条信息

  [ERROR] Slave SQL: Error 'Duplicate entry '1007-443786-0' for key 'PRIMARY'' on query. Default database: 'ufo'. Query: 'insert into misdata (uid,mid,pid,sta

  te,mtime) values (443786,1007,0,-1,1262598003)', Error_code: 1062

  100104 17:39:05 [Warning] Slave: Duplicate entry '1007-443786-0' for key 'PRIMARY' Error_code: 1062

  100104 17:39:05 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SL***E START". We stopped at log 'ufolog.000058

  8' position 55793296

  报错和上面的意思差不多,

  最先想到的就是首先手动同步一下,从库上首先 stop slave;停止同步

  进入主库锁表,

  FLUSH TABLES WITH READ LOCK;

  mysql> show master status;

  +-------------------+-----------+--------------+------------------+

  | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

  +-------------------+-----------+--------------+------------------+

  | ufo.000063 | 159164526 | | |

  +-------------------+-----------+--------------+------------------+

  1 row in set (0.00 sec)

  进入从库

  mysql>change master to master_host='192.168.1.141', master_user='slave',

  master_password='xxx',

  master_port=3306,

  master_log_file='ufo.000063',

  master_log_pos=159164526;

  完成上面这些后

  start slave;

  回到主库

  unlock tables; 解锁

  回到从库 查看

  show slave status \G;

  发现正常了,长处了一口气。可是还没过一分钟,发现又开始报错了,还是最开始那个错误,这是怎么回事...

  于是又想到了跳过错误的办法,(不过我不太喜欢用这种方法)马上进入从库

  stop slave;

  set global sql_slave_skip_counter=1; (1是指跳过一个错误)

  slave start;

  再show slave status \G;查看

  还是报错 只不过 原来的 164761 变成了 165881,连续执行了几次后

  除了上面的数值 在变,错误依然还在

  郁闷了,看来只能先强制跳过 1062错误了,于是修改从库的/etc/my.cnf文件

  在里面的[mysqld]下面加入了一行

  slave-skip-errors = 1062 (忽略所有的1062错误)

  重启下从库的mysql /etc/init.d/mysqld restart

  再 show slave status \G;一下发现正常了,但是我知道这时的数据可能已经不同步了,

  再次查看一下日志,让我感到意外的是tail -f mysql_error.log 出现大量的

  .......

  100106 16:54:21 [Warning] Statement may not be safe to log in statement format. Statement: delete from `system_message_1` where `to_uid` = 181464 ORDER BY `id` ASC LIMIT 1

  .........

  日志里面有大量的这种警告,意思应该是statement 格式不安全,用vim
打开他看了一下,发现好多这类警告,我说为什么错误日志怎么变这么大了呢!!

  statement format 应该是 binlog的一种格式,进入从库查看一下

  show global variables like 'binlog_format';

  果然当前的格式为statement

  我需要把格式改为 mixed格式

  修改从库的 my.cfg

  在[mysqld]下面加入下面这行

  binlog_format=mixed

  然后重启mysql服务,发现错误日志里的 警告 都停止了。这回清静多了~~

  我突然想起一件事,记得有朋友说过 RBR 模式可以解决很多因为主键冲突导致的主从无法同步情况,想到这里我就想要不要把 slave-skip-errors = 1062 去掉再试试,

  于是就进入到my.cnf 里在注释掉了 slave-skip-errors = 1062

  再次重新启动 mysql服务

  进入从库

  show slave status \G;

  .........

  Slave_IO_Running: Yes

  Slave_SQL_Running: Yes

  ........

  恢复了!!!有观察了一段时间没有出现问题这才放心,

  看来导致 mysql 主从复制出错的原因还真不少修复的办法也不止一个,binlog的格式也是其中之一。

  希望遇到和这次一样问题的朋友看到这篇文章后会得到 一些启发和解决问题的方法~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: