MySQL主從複製及排錯

一、MySQL主從複製概述

1、主從複製簡介

MySQL主從複製就是將一個MySQL實例(Master)中的數據實時複製到另一個MySQL實例(slave)中,而且這個複製是一個異步複製的過程。

實現整個複製操作主要由三個進程完成的,其中兩個進程在Slave(sql_thread和IO_thread),另外一個進程在 Master(IO進程)上。

2、主從複製原理、機制

要實施複製,首先必須打開Master端的binary log(bin-log)功能,否則無法實現。因爲整個複製過程實際上就是Slave從Master端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。

複製的基本過程如下:

1)、Slave上面的IO_thread連接上Master,並請求從指定日誌文件的指定位置(或者從最開始的日誌)之後的日誌內容;

2)、Master接收到來自Slave的IO_thread的請求後,通過負責複製的IO進程根據請求信息讀取制定日誌指定位置之後的日誌信息,返回給Slave 的IO_thread。返回信息中除了日誌所包含的信息之外,還包括本次返回的信息已經到Master端的bin-log file的以及bin-log pos;

3)、Slave的IO_thread接收到信息後,將接收到的日誌內容依次添加到Slave端的relay-log文件的最末端,並將讀取到的Master端的 bin-log的文件名和位置記錄到master-info文件中,以便在下一次讀取的時候能夠清楚的告訴Master“我需要從某個bin-log的哪 個位置開始往後的日誌內容,請發給我”;

4)、Slave的Sql_thread檢測到relay-log中新增加了內容後,會馬上解析relay-log的內容成爲在Master端真實執行時候的那些可執行的內容,並在本數據庫中執行。 

3、主從複製原理圖

blob.pngblob.png

二、MySQL主從複製搭建

MySQL主從複製搭建主要步驟有:Master端配置部署、Slave端配置部署、建立主從同步

1Master端配置部署

a、 配置參數:

[mysqld]

server-id=101  # 這個要保證一個主從複製環境中,不要有相同的server-id

log-bin=/data/mysql6001/binlog/mysql-bin.log

log-bin-index=/data/mysql6001/binlog/mysql-bin.index

expire_logs_days=30

b、 創建用戶,並賦予權限:

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY PASSWORD '******';

 

2Slave端配置部署

a、 配置參數:

[mysqld]

server-id=102  

relay-log=/data/mysql6001/relaylog/mysql-relay-bin.log

relay-log-index=/data/mysql6001/relaylog/mysql-relay-bin.index

relay_log_purge=on

 

3、建立主從同步

(重建備庫也是使用該方法)

 

建立主從同步可以從主庫上導出數據,也可以從已有的從庫上導出數據,然後再導入到新的從庫中,change master to建立同步。

3.1 、導出數據

在主庫上導出數據:

mysqldump -u*** -p*** -S /data/mysql6001/mysql.sock --default-character-set=utf8 -q --single-transaction --master-data -A  >  /tmp/all_database.sql

(或者)在從庫上導出數據:

mysqldump -u*** -p*** -S /data/mysql6001/mysql.sock --default-character-set=utf8 -q --single-transaction --dump-slave -A  >  /tmp/all_database.sql

NOTES

--master-data--dump-slave導出的備份中,會包含master_log_filemaster_log_pos信息。

blob.png 

3.2 、從庫導入數據

mysql -u*** -p*** --default-character-set=utf8 < all_database.sql

NOTES

此處導入腳本,就已經在從庫中執行了以下操作:

change_master_to

master_log_file=' mysql-bin.000xxx',

master_log_pos=xxxxxx;

3.3 、從庫與主機建立同步

以下爲建立主從同步最基本的6個項:

change master to

master_host='xxx.xxx.xxx.xxx',     # 主庫IP

master_port=6001,              # 主庫mysqld的端口

master_user='repl',              # 主庫中創建的有REPLICATION SLAVE 權限的用戶

master_password='xxxxxxxx',      # 該用戶的密碼

master_log_file=' mysql-bin.000xxx', # 已在導入時指定了

master_log_pos=xxxxxx;          #已在導入時指定了

指定與主庫同步的基本信息後,就可以啓動slave進程了:(IO_threadsql_thread

start slave;

三、主從複製狀態檢查及異常處理

1、主從複製狀態檢查

主庫查看binlog情況:

show master status\G

*************************** 1. row ***************************

            File: mysql-bin.000303

        Position: 18711563

    Binlog_Do_DB:

Binlog_Ignore_DB:

 

在從庫上主要是使用以下命令查看從庫與主庫的同步狀態:

show slave status\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.43.128    #主庫IP

                  Master_User: repl             #主庫複製的用戶

                  Master_Port: 6001             #主庫mysqld端口

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000303   #io_thread讀取主庫master_log_file

          Read_Master_Log_Pos: 18711563        # io_thread讀取主庫master_log_pos

               Relay_Log_File: mysql-relay-bin.000900

                Relay_Log_Pos: 18711709

        Relay_Master_Log_File: mysql-bin.000303  #sql_thread執行主庫的master_log_file

             Slave_IO_Running: Yes             #關鍵的,io_thread是否running

            Slave_SQL_Running: Yes             #關鍵的,sql_thread是否running

              Replicate_Do_DB:

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 0

                   Last_Error:

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 18711563       #sql_thread執行主庫的master_log_pos

              Relay_Log_Space: 18711908

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File:

           Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

               Master_SSL_Key:

        Seconds_Behind_Master: 0               #從庫的延遲

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 0

               Last_SQL_Error:

  Replicate_Ignore_Server_Ids:

             Master_Server_Id: 101

1 row in set (0.00 sec)

 

2IO_thread異常

IO_thread異常,狀態往往是Slave_IO_Running: Connecting NO

IO_thread是向Master發送請求讀取master binlog,如果處於Connecting狀態,說明無法正確地與Master進行連接,可能的原因有:

a網絡不通(是否打開防火牆)

b複製用戶的密碼不對

c指定的master_port端口不對

dmaster上的mysql-bin.xxxxxx被誤刪

e主庫磁盤空間滿了

通過show slave status\G可以看到相關錯誤信息,例如:

show slave status\G

Last_IO_Errno: 2003

Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 60      

            retries: 86400

或者通過錯誤日誌看到相關信息,如:

140828 15:47:20 [ERROR] Slave I/O: error connecting to master '[email protected]:3306' -  

              retry-time: 60  retries: 86400, Error_code: 2003

140828 15:47:21 [Note] Event Scheduler: Loaded 0 events

140828 15:47:21 [Note] /home/mysql/mysql/bin/mysqld: ready for connections.

3sql_thread異常

sql_thread發生異常,狀態就會變爲Slave_SQL_Running: NO

sql_thread發生異常的情況非常多,發生異常後,需要通過以下方法排查和解決:

a、對比主庫和從庫的二進制日誌的情況:

主庫:

show master status\G

            File: mysql-bin.000303

        Position: 18711563

從庫:

show slave status\G

               Master_Log_File: mysql-bin.000303   --IO_thread

          Read_Master_Log_Pos: 18711563          --IO_thread

          Relay_Master_Log_File: mysql-bin.000303   --sql_thread

           Exec_Master_Log_Pos: 18711163          --sql_thread

 

b、通過show slave status\G查看錯誤信息:

show slave status\G

Last_SQL_Errno: 1062

Last_SQL_Error: Error 'Duplicate entry '1' for key 'PRIMARY'' on query. Default database:

             'test'. Query: 'insert into test values(1,2,3,4,5,6)'

 

c、 通過錯誤日誌查看錯誤信息:

140828 16:27:51 [ERROR] Slave SQL: Error 'Duplicate entry '1' for key 'PRIMARY'' on query.

              Default database: 'test'. Query: 'insert into test values(1,2,3,4,5,6)',

              Error_code: 1062

140828 16:27:51 [Warning] Slave: Duplicate entry '1' for key 'PRIMARY' Error_code: 1062

140828 16:27:51 [ERROR] Error running query, slave SQL thread aborted. Fix the problem,

              and restart the slave SQL thread with "SLAVE START". We stopped at log

              'mysql-bin.000303' position 18711163

 

根據這些報錯信息,往往就能夠定位到發生異常的原因。如果我們瞭解產生異常的具體事件,而且能夠掌控,可以通過設置sql_slave_skip_counter參數來跳過當前錯誤。

set global sql_slave_skip_counter=1;

或者使用slave_skip_errors參數(read only variable),指定跳過某種類型的錯誤:

參數文件中設置:

slave_skip_errors=1062     #跳過1062錯誤

遇到錯誤時,不要一通百度後,然後根據看起來很類似的操作直接來進行操作。因爲網上大部分解決sql_thread異常的方法是:

a直接set global sql_slave_skip_counter=n; n設置很大的值,即:跳過所有錯誤),

b設置slave_skip_errors=all;  跳過所有類型的錯誤

c直接查看主庫的binlog,然後在從庫上直接執行change master to

這些方法都會導致主從數據不一致。

 

如果發現從庫與主庫差異太大,無法通過手動操作數據修改重新建立同步。可以參考上述"MySQL主從複製搭建" 重新搭建從庫。

 

4、主從複製延遲

主從複製延遲,可能的原因有:

a主從同步延遲與系統時間的關係,查看主從兩臺機器間系統時間差

b主從同步延遲與壓力、網絡、機器性能的關係,查看從庫的iocpumem及網絡    

c主從同步延遲與lock鎖的關係(myisam表讀時會堵塞寫),儘量避免使用myisam 表。 一個實例裏面儘量減少數據庫的數量。

d、主從複製發生異常而中斷,過很久之後才發現複製異常。可通過查看masterslavestatus估算相差的日誌。如果相差太大,則可以考慮重做從庫。

 

 原文鏈接:http://blog.itpub.net/26355921/viewspace-1273303/ 


MySQL主從複製和讀寫分離 實現:http://jayluns.iteye.com/blog/2275690 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章