公司里有兩個mysql服務(wù)器做主從同步,某天Nagios發(fā)來報警短信,
mysqla is down...趕緊聯(lián)系機(jī)房,機(jī)房的人反饋來的信息是
HARDWARE ERROR 后面信息省略,讓機(jī)房記下錯誤信息后讓他們幫忙重啟下看是不是能正常起來,結(jié)果竟然正常起來了,趕緊導(dǎo)出所有數(shù)據(jù)。
問題又出現(xiàn)了,nagios 又報警,mysql_AB error,檢查從庫
show slave status \G; 果然
Slave_IO_Running: YesSlave_SQL_Running: No而且出現(xiàn)了
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)'很顯然,由于主庫重啟導(dǎo)致 從庫數(shù)據(jù)不同步而且主鍵沖突。查看error 日志發(fā)現(xiàn)error日志文件變得好大,比以前大了將近好幾倍,
tail -f mysql_error.log 最開始查看到的是這條信息
發(fā)現(xiàn)這條信息
[ERROR] Slave SQL: Error 'Duplicate entry '1007-443786-0' for key 'PRIMARY'' on query. Default database: 'ufo'. Query: 'insert into misdata (uid,mid,pid,state,mtime) values (443786,1007,0,-1,1262598003)', Error_code: 1062100104 17:39:05 [Warning] Slave: Duplicate entry '1007-443786-0' for key 'PRIMARY' Error_code: 1062100104 17:39:05 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'ufolog.0000588' position 55793296報錯和上面的意思差不多,
最先想到的就是首先手動同步一下,從庫上首先
stop slave;停止同步
進(jìn)入主庫鎖表,
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)
進(jìn)入從庫
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;發(fā)現(xiàn)正常了,長處了一口氣。可是還沒過一分鐘,發(fā)現(xiàn)又開始報錯了,還是最開始那個錯誤,這是怎么回事...
于是又想到了跳過錯誤的辦法,(不過我不太喜歡用這種方法)馬上進(jìn)入從庫
stop slave; set global sql_slave_skip_counter=1; (1是指跳過一個錯誤)
slave start;再
show slave status \G;查看
還是報錯 只不過 原來的 164761 變成了 165881,連續(xù)執(zhí)行了幾次后
除了上面的數(shù)值 在變,錯誤依然還在
郁悶了,看來只能先強(qiáng)制跳過 1062錯誤了,于是修改從庫的/etc/my.cnf文件
在里面的
[mysqld]下面加入了一行
slave-skip-errors = 1062 (忽略所有的1062錯誤)
重啟下從庫的
mysql /etc/init.d/mysqld restart再
show slave status \G;一下發(fā)現(xiàn)正常了,但是我知道這時的數(shù)據(jù)可能已經(jīng)不同步了,
再次查看一下日志,讓我感到意外的是
tail -f mysql_error.log 出現(xiàn)大量的
.......
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.........
日志里面有大量的這種警告,意思應(yīng)該是statement 格式不安全,用vim 打開他看了一下,發(fā)現(xiàn)好多這類警告,我說為什么錯誤日志怎么變這么大了呢??!
statement format 應(yīng)該是 binlog的一種格式,進(jìn)入從庫查看一下
show global variables like 'binlog_format';果然當(dāng)前的格式為
statement 我需要把格式改為
mixed格式
修改
從庫的 my.cfg在
[mysqld]下面加入下面這行
binlog_format=mixed然后重啟mysql服務(wù),發(fā)現(xiàn)錯誤日志里的 警告 都停止了。這回清靜多了~~
我突然想起一件事,記得有朋友說過 RBR 模式可以解決很多因?yàn)橹麈I沖突導(dǎo)致的主從無法同步情況,想到這里我就想要不要把 slave-skip-errors = 1062 去掉再試試,
于是就進(jìn)入到my.cnf 里在注釋掉了 slave-skip-errors = 1062再次重新啟動 mysql服務(wù)
進(jìn)入從庫
show slave status \G;.........
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
........
恢復(fù)了!??!有觀察了一段時間沒有出現(xiàn)問題這才放心,
看來導(dǎo)致 mysql 主從復(fù)制出錯的原因還真不少修復(fù)的辦法也不止一個,binlog的格式也是其中之一。
希望遇到和這次一樣問題的朋友看到這篇文章后會得到 一些啟發(fā)和解決問題的方法~~
本文出自 “story的天空” 博客,請務(wù)必保留此出處http://storysky.blog.51cto.com/628458/259280