Mysql主從(主從不一樣步解決辦法,常見問題及解決辦法,在線對mysql作主從複製)

1、主從不一樣步解決辦法python

先上Master庫: 
mysql>show processlist; 查看下進程是否Sleep太多。發現很正常。 
show master status; 也正常。 
mysql> show master status; 
+-------------------+----------+--------------+-------------------------------+ 
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | 
+-------------------+----------+--------------+-------------------------------+ 
| mysqld-bin.000001 | 3260 | | mysql,test,information_schema | 
+-------------------+----------+--------------+-------------------------------+ 
1 row in set (0.00 sec) 
再到Slave上查看 
mysql> show slave status\G 
Slave_IO_Running: Yes 
Slave_SQL_Running: No 
可見是Slave不一樣步  mysql

下面介紹兩種解決方法: 
方法一:忽略錯誤後,繼續同步
該方法適用於主從庫數據相差不大,或者要求數據能夠不徹底統一的狀況,數據要求不嚴格的狀況 
解決: 
stop slave; sql

表示跳過一步錯誤,後面的數字可變 

set global sql_slave_skip_counter =1; 
start slave; 
以後再用mysql> show slave status\G 查看: 
Slave_IO_Running: Yes 
Slave_SQL_Running: Yes 
ok,如今主從同步狀態正常了。。。  shell

方式二:從新作主從,徹底同步
該方法適用於主從庫數據相差較大,或者要求數據徹底統一的狀況 
解決步驟以下: 
1.先進入主庫,進行鎖表,防止數據寫入 
使用命令: 
mysql> flush tables with read lock; 
注意:該處是鎖定爲只讀狀態,語句不區分大小寫 
2.進行數據備份 數據庫

把數據備份到mysql.bak.sql文件 

[root@server01 mysql]#mysqldump -uroot -p -hlocalhost > mysql.bak.sql 
這裏注意一點:數據庫備份必定要按期進行,能夠用shell腳本或者python腳本,都比較方便,確保數據萬無一失 
3.查看master 狀態 
mysql> show master status; 
+-------------------+----------+--------------+-------------------------------+ 
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | 
+-------------------+----------+--------------+-------------------------------+ 
| mysqld-bin.000001 | 3260 | | mysql,test,information_schema | 
+-------------------+----------+--------------+-------------------------------+ 
1 row in set (0.00 sec) 
4.把mysql備份文件傳到從庫機器,進行數據恢復 服務器

使用scp命令 

[root@server01 mysql]# scp mysql.bak.sql root@192.168.128.101:/tmp/ 
5.中止從庫的狀態 
mysql> stop slave; 
6.而後到從庫執行mysql命令,導入數據備份 
mysql> source /tmp/mysql.bak.sql 
7.設置從庫同步,注意該處的同步點,就是主庫show master status信息裏的| File| Position兩項 
change master to master_host = '192.168.128.100', master_user = 'rsync', master_port=3306, master_password='', master_log_file = 'mysqld-bin.000001', master_log_pos=3260; 
8.從新開啓從同步 
mysql> stop slave; 
9.查看同步狀態 
mysql> show slave status\G 查看: 
Slave_IO_Running: Yes 
Slave_SQL_Running: Yes app

2、錯誤及解決辦法socket

問題: 從數據庫沒法同步post

Slave_SQL_Running 值爲 NO,或 Seconds_Bebind_Master 值爲 Nullui

緣由:

1. 程序有可能在 slave 上進行了寫操做

2. 也有多是 slave 機器重啓後,事務回滾形成的

解決方法一:

msyql> stop slave;

msyql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

msyql> start slave;

解決方法二:

msyql> stop slave; 

查看主服務器上當前的 bin-log 日誌名和偏移量

msyql> show master status;

獲取到以下內容:

| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB |

| mysql-bin.000005 |      286 |              |                  |

而後到從服務器上執行手動同步

msyql> change master to

    ->master_host="192.168.10.1",

    ->master_user="user",

    ->master_password="123456",

    ->master_post=3306,

    ->master_log_file="mysql-bin.000005",

    ->master_log_pos=286;

msyql> start slave;

  • 場景1:主庫上用系統命令複製或刪除表數據文件

    【模擬異常】:

    主庫上直接copy表數據文件,或直接rm表數據文件主庫上拷貝test表數據文件後,執行insert into test values('111');或主庫上執行rm -f test05.*後,執行create table test05(a int(11));

【錯誤日誌】:

從庫日誌:SHOW SLAVE STATUS \G;

Last_Errno: 1146

Last_Error:Error 'Table'testdb.test 'doesn't exist'on query' insertinto test values('111') '.

Default database: 'testdb'. Query: 'insert into testvalues('111')'

或者以下:

Last_Error: Error 'Table’test05 'already exists' on query.

【錯誤緣由】:

表的建立或刪除不是經過執行sql,未寫入binlog,從庫上沒有相關表;

【解決方案】:

在從庫上手動建立此表(建表語句可參考主庫);

之後,主庫上對錶的操做請經過sql完成,避免使用系統命令拷貝或刪除

  • 場景2:數據不一致:包括刪除失敗、主鍵重複、更新丟失

【問題1】:

主鍵重複:在slave已經有該記錄,又在master上插入了同一條記錄。

從庫日誌:SHOW SLAVE STATUS \G;

Last_Errno: 1062

Last_Error: Error 'Duplicate entry 'xxxn-66-77' for key1' on query. Default database: 'guild'. Query: 'insert into pynpcrecord setMapCode = 'xxxn', UpdateTime = '2015-08-07 00:00:32''

     【解決方案】:

方案1:在從庫上將重複的主鍵記錄刪除,再次重啓主從;

deletefrom xxxx where 主鍵=yyyy;

  stopslave;start slave;

       方案2:停掉主從同步,忽略一次錯誤,再開啓同步:

 stop slave;

      set global sql_slave_skip_counter=1;startslave;

  如果新配主從,忽略3次還報此錯,還能夠在my.cnf里加

      一 行: slave-skip-errors=1062

而後重啓實例,再重啓主從同步;

stop slave; start slave;

【問題2】刪除失敗:在master上刪除一條記錄,而slave上找不到。

從庫日誌:SHOW SLAVE STATUS \G;

Last_Errno: 1032;

Last_Error: Could not execute Delete_rows event ontable hcy.t1;

Can't find record in 't1',

【解決方案】:

因爲master要刪除一條記錄,而slave上找不到而報錯,這種狀況主庫都將其刪除了,從庫能夠直接跳過。

可用命令:

stop slave;

set global sql_slave_skip_counter=1;startslave;

【問題3】:更新丟失:在master上更新一條記錄,而slave上找不到,丟    失了數據。

從庫日誌:SHOW SLAVE STATUS \G;

Last_Errno: 1032;

Last_Error: Could not execute Update_rows event ontable hcy.t1; Can't find record in 't1',

     【解決方案】:

把丟失的數據在slave上填補,而後跳過報錯便可。

  • 場景3:字段不一致:包括字段丟失、不夠長等

【問題1】

從庫日誌:SHOW SLAVE STATUS \G;

Slave_IO_Running: Yes

Slave_SQL_Running: No

Last_Errno: 1264

Last_Error: Error 'Out of range value for column 'JFNow' at row 1' onquery. Default database: 'guild'. Query: 'update pyPHBWS set JFNow =JFNow -1 wherePlayerName = '狂魔''

雖然從庫該字段和主庫的一致,但從庫仍是報錯:

guild> desc pyPHBWS;

| Field      |Type                | Null | Key |Default | Extra |

| PlayerName | varchar(30)         | NO  | PRI | NULL    |       |

| JFNow   | int(10)unsigned    | YES  |     |NULL    |       |

| JFAll   |int(10) unsigned    | NO   |    | NULL    |       |

     【解決方案】

修改字段:

ALTER TABLE guild.pyPHBWS MODIFY JFNowbigint(20) unsigned;

重啓主從:stop slave;start slave;

【問題2】

從庫日誌:

  SHOW SLAVE STATUS \G;

Slave_IO_Running: Yes

Slave_SQL_Running: No

Last_Errno: 1054

Last_Error:Error 'Unknown column 'qdir' in 'field list''on query. Default database: 'club'. Query: 'insert into club.question_del (id,pid, ques_name, title, intime, order_d, endtime,qdir) select id, pid,ques_name, title, intime, order_d, endtime ,qdir from club.question whereid=7330212'

【解決方案】

主庫:查詢 desc club.question_del,發現club.question_del表裏面沒有qdir這個字段;

從庫:執行 alter table question_del add qdirvarchar(30) not null;

  • 場景4:超出MyISAM數據表大小限制

【錯誤日誌】

從庫日誌:

   SHOW SLAVE STATUS \G;

Slave_IO_Running: No

Slave_SQL_Running: Yes

Last_Errno : 1114

Last_Error : Error 'The table   'tbleventlog' is full' onquery. Default database: 'dblog'. Query: 'insert into `tbleventlog`(`PlayerName`, `ACTION`, `VALUE`, `PARAM`, `TIME`) values ('ĺɫ', '־', '620',':2,:397842703', '2015-07-28 06:56:04')'

找到該實例所在的目錄,發現該表大小超過4GB;

【解決方案】

對於MyISAM數據表,單個.MYD和.MYI默認4GB。

利用AVG_ROW_LENGTH和MAX_ROWS建表選項能夠把這個最大值擴大到800萬TB.

max_rows主要對myisam生效.

從庫:調整max_rows並重啓slave.

use dblog; ALTER TABLE tbleventlog MAX_ROWS=1000000000;

stop slave; start slave;

  • 場景5:slave的中繼日誌relay-bin損壞

【模擬異常】

SLAVE在宕機,或者非法關機,例如電源故障、主板燒了等,形成中繼日誌損壞,同步停掉。

【錯誤日誌】

從庫日誌:SHOW SLAVE STATUS \G;

Slave_IO_Running: Yes

Slave_SQL_Running: No

Last_Errno: 1593

Last_Error: Error initializing relay log position: I/Oerror reading event at position 4

【解決方案】

在主庫上找到同步的binlog和POS點,而後從新作同步,這樣就能夠有新的中繼日誌了。

mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000010',MASTER_LOG_POS=821;

  • 場景6:binlog index記錄不一致

【模擬異常】

主數據庫忽然中止或問題終止,更改了mysql-bin.xxx日誌,slave服務器找不到這個文件。

【錯誤日誌】

從庫日誌:SHOW SLAVE STATUS \G;

Master_Log_File: mysql-bin.000029

Last_Errno: 1594

Last_Error: Relay log read failure: Could not parserelay log event entry.

【解決方案】

找到同步的點和日誌文件,而後chage master便可:

change master to master_log_file='mysql-bin.000025',master_log_pos=1010663436;

  • 場景7:時區不一致致使主從數據不一致

【模擬異常】:主從服務器設置不一樣的時區

主庫:show variables like '%timezone%';      #.看到變量timezone值爲EDT

從庫:showvariables like '%timezone%';       #.看到變量timezone值爲 CST

【錯誤日誌】:主庫執行insert into tbname(dtime)values(now());

主庫:  select* from tbname;  #.看到字段dtime值爲 2013-05-08 18:40:18

從庫:  select* from tbname;  #.看到字段dtime值爲 2013-05-09 06:40:18

【解決方案】:

設置主從爲相同時區,並儘可能使用相同時間服務器

若是對時間字段用now()寫入,在刪除時候用delete * from tbname where dtime='xxx',因爲主從時間是不一致的,就會形成刪除的非同一條記錄,也會引發主鍵衝突問題。

  • 場景8:字段集不一致

【模擬異常】

1.主庫:版本MySQL 4.0.18,字符集gb2312,主鍵字段PlayerName

show create table pybcsltscore; 

PRIMARY KEY (`PlayerName`)  ENGINE=MyISAM DEFAULT CHARSET=gb2312

2.從庫:版本MySQL 4.1.22,字符集latin1,主鍵字段PlayerName

show create table pybcsltscore; 

PRIMARY KEY (`PlayerName`)  ENGINE=MyISAM DEFAULT CHARSET=latin1

3.主庫:執行sql:

mysql> insert into pybcsltscore set PlayerName = '怒☆斬', PT = 'pchg.c8';

mysql> insert into pybcsltscore set PlayerName = '怒★斬', PT = 'pchg.c8';

4. 主庫:查詢正常

select * from pybcsltscore where playername='怒☆斬' or playername='怒★斬';

【錯誤日誌】

從庫:查詢異常,查詢實心星號,結果卻出現空心星號

select * from pybcsltscore_bak where playername='怒★斬';

從庫: 從庫狀態:

Last_Errno: 1062

Last_Error: Error 'Duplicate entry '怒★斬' for key 1' on query. Defaultdatabase: 'test0505'. Query: 'insert into pybcsltscore set PlayerName = '怒★斬', PT = 'pchg.cs68'‘

從庫:插入playname=’怒★斬’ 的記錄,會提示主鍵衝突

insert into score_bak set PlayerName = '怒★斬', PT = 'pchg.cs68';

ERROR 1062 (23000): Duplicate entry '怒★斬' for key 1

【解決方案】

方案1. 從庫:去掉主鍵

alter table pybcsltscore_test0513 drop primary key;

stop slave sql_thread; start slave sql_thread;

       方案2. 從庫:修改默認編碼爲gb2312

mysql --default-character-set=gb2312 -S mysql3307.sock

       從庫:再次查詢:

select * from pybcsltscore where playername='怒☆斬' or playername='怒★斬';

  • 場景9:max_allowed_packet過小

【模擬異常】

1. 主庫:設置max_allowed_packet爲特小值,好比12K:

mysql> set global max_allowed_packet=12*1024;

Query OK, 0 rows affected (0.00 sec)

   mysql> show variables like 'max_allowed_packet';                 

| Variable_name      | Value |

| max_allowed_packet | 12288 |

2. 重啓slave io thread

說明:slave若是不重啓的話,我的以爲主從關係所使用的主庫的變

不會改變,重啓以便從新加載一些變量

3. 主庫:導入r2.txt(僅一行記錄    

 # du -sh r2.txt    80K    r2.txt)

 ./bin/mysql test0505 -e "load data infile'/tmp/r2.txt' into table test2;"

4. 查看從庫狀態

Slave_IO_Running: No

Slave_SQL_Running: Yes

5. 從庫:

mysql> show variables like 'max_allowed_packet';                 

| Variable_name      | Value    |

| max_allowed_packet | 16776192|

【錯誤日誌】

查看從數據庫的錯誤日誌,找到以下信息:

[ERROR] Got fatal error 1236: 'log event entry exceededmax_allowed_packet;

Increase max_allowed_packet on master' from master whenreading data from binary log

或相似:

[ERROR] Error reading packet from server: Got packetbigger than          'max_allowed_packet' bytes (server_errno=2020)

應該是master上的dump線程在從binlog讀取數據時,讀取的結果集超出了max_allowed_packet限制,形成往slave發送失敗。

【解決方案】

修改max_allowed_packet的大小,而後重啓slave。建議主從一致

mysql> set global max_allowed_packet=16*1024*1024;

重啓slave, stop salve;start slave;

  • 場景10:臨時表太大致使磁盤寫滿

【錯誤日誌】:從庫日誌

Last_Errno: 3

  Last_Error: Error 'Error writing file '/tmp/FeqMc' (Errcode: 28)'on query.

  Default database: 'evt'. Query: 'delete from goodslogwhere OpTime<'2015-07-01''

【錯誤緣由】

1. tmp目錄不可寫,或磁盤沒有空間;

2. tmp還有空間,可是原表太大,因此查詢時生成的臨時表過大,所以出   錯。

【解決方案】

1.確認/tmp可寫入,同時磁盤未寫滿;

2.修改socket目錄到空間較大的分區,再重啓實例;

把 socket = /tmp/mysql.sock 改成 socket = /app/mysql.sock

相關文章
相關標籤/搜索