mysql雙向同步設置及基本原理

1        背景介紹

學校內部有一臺服務器(3g服務器),上面部署着uvge網站。在上海有一臺服務器(上海服務器)。考慮到校外用戶訪問uvge網站時速度很慢,先決定在上海服務器上也部署個相同的網站,當外網用戶想訪問uvge網站時就訪問上海服務器上的網站。

現在就需要解決一個問題:如何讓校外用戶瀏覽校內用戶發表的帖子,校內用戶也能瀏覽校外用戶發表的帖子?

解決辦法就是採用mysql的雙向同步技術

 

2        Mysql單向同步配置步驟

mysql的同步機制是基於日誌的同步機制,所以主服務器一定要支持更改日誌纔行。然後設置要寫入日誌的數據庫或者不要寫入日誌的數據庫。這樣只有您感興趣的數據庫的更改才寫入到數據庫的日誌中。

前期準備:兩臺服務器上都已將網站部署好,兩臺服務器上的數據庫也是一模一樣。這裏的數據庫一摸一樣是指所需要同步的表的內容一樣,兩個數據庫的版本可以不一樣。這裏所做的是雙向同步,所以兩臺服務器互爲主從關係。

爲了方便,上海服務器簡稱ucwise,學校服務器簡稱3g。

 

2.1      配置主數據庫(ucwise)的my.ini文件

server-id=1 //數據庫的id這個應該默認是1就不用改動
log-bin=log_name //日誌文件的名稱,這裏可以制定日誌到別的目錄 如果沒有設置則默認主機名的一個日誌名稱。
binlog-do-db=db_name //記錄日誌的數據庫。
binlog-ignore-db=db_name //不記錄日誌的數據庫。
以上的如果有多個數據庫用","分割開。

auto-increment-offset=1 //表中第一條數據的編號(id)。

auto-increment-increment=2 //設置自動增量,向表中沒添加一條數據,數據的id自動增2。這樣就保證了主數據庫中數據的id爲1,3,5,7…..的形式。

2.2      爲主庫設置創建同步用戶及賦權

先連接到主庫中,

mysql> grant all privileges on *.* to'訪問該數據庫的用戶名'@'可以訪問該數據庫的ip'identified by '訪問該數據庫用的密碼'。;

mysql>flush privileges; 使生效

2.3      鎖定數據庫

mysql> flush tables with read lock;

這一步很重要,如果不鎖定主數據庫,那麼其他用戶還能對數據庫裏的數據進行寫操作。一旦對主數據庫進行了寫操作,那麼主從數據庫裏的內容就不一致了,在以後的同步過程中可能會出現錯誤。

2.4      配置從數據庫(3g)的my.ini文件

在從數據庫的my.ini文件中找到[mysqld]模塊下,並添加一下內容:

server-id = 2

master-connect-retry =60    //從服務器發現主服務器斷掉,重連時間差(秒)

replicate-do-db = testdb    //同步數據庫:多個寫多行

auto_increment_offset = 2 //表中第一條數據的id號

auto_increment_increment = 2//向表中每添加一條數據,id好自動增2.這就保證了該表中數據的id格式爲:2,4,6,8….

這樣主從庫同步時就不會出現id號衝突了。

配置完畢保存後,增加了master.info與relay-log.info等文件。
停止MYSQL服務,刪除data目錄下除數據庫外的所有文件, master.info和relay-log.info兩文件必須刪除。
注意:master修改my.ini時,master.info和relay-log.info必須刪除重啓服務。

2.5      查看主庫狀態

在主庫上查看當前二進制日誌名和偏移量值,注意:是查看主庫

mysql> show master status;

記下返回結果中File屬性的值和position的值,這兩個值在以後的操作中會用的到。

注意:一旦主數據庫的數據發生變化,這兩個值就會隨之發生改變。所以,如果主數據庫中有數據寫入,就要重新執行這個命令,獲取最新的更新點。

2.6      在從數據庫上制定更新點


先登錄至從數據庫,停止slave:

mysql> slave stop; //停止slave的服務

然後設置更新點:

mysql> CHANGE MASTERTO
    -> MASTER_HOST='主機ip',
    -> MASTER_USER='訪問用戶名',
    -> MASTER_PASSWORD='訪問密碼',
    -> MASTER_LOG_FILE='mysql-bin.000008',
    -> MASTER_LOG_POS=880;
Query OK, 0 rows affected (0.01 sec)
注意到這裏master_log_file和master_log_pos就是前面show master status的結果。

2.7      查看從數據庫狀態

登錄從數據庫,在數據庫中輸入以下命令:

mysql> show slave status\g;

 

返回結果中如果沒有錯誤信息就表示,主從數據庫都已經配置連接好,可以進行同步了。

2.8      啓動同步線程

mysql> slave start;

2.9      解除主庫鎖定

mysql> unlock tables;

現在可以對主數據庫進行寫操作了,所有在主數據庫中進行的寫操作在從數據庫中都會有相同的操作。單向同步完成。

3        雙向同步配置

我們在前面已經實現了單向同步,ucwis服務器中數據庫爲主數據庫,3g服務器中數據庫爲從數據庫。反過來,我們在把3g服務器中的數據庫作爲主數據庫,把ucwise服務器中的數據庫作爲從數據庫,就可以實現反向同步,這樣一來,雙向同步就實現了。所以,要實現雙向同步,我們只需在原有的操作中添加以下操作:

3.1      查看從庫狀態

 

在從數據庫上查看當前二進制日誌名和偏移量值,注意:是查看從庫

mysql>show master status;

 

3.2      在主數據庫中設置更新點

在主服務器上指定更新點(根據上面查的記錄)

mysql>CHANGE MASTER TO

    -> MASTER_HOST='從數據庫ip',

    -> MASTER_PORT=3306,

    -> MASTER_USER='登錄用戶',

    -> MASTER_PASSWORD='訪問密碼',

    -> MASTER_LOG_FILE='mysql-bin.000009',

    -> MASTER_LOG_POS=990;

3.3      在數據庫中啓動同步線程

登錄主數據庫,輸入以下命令,啓動同步線程,就可以開始雙向同步。

mysql> slave stop;

mysql> slave start;

注意:本次測試主從數據庫的版本都是mysql5.5。如果數據庫的版本低於5.1.7,那麼配置文件中可以直接設置master參數。

4        主從同步原理

4.1      日誌文件的作用

主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌可以記錄發送到從服務器的更新。當一個從服務器連接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,然後封鎖並等待主服務器通知新的更新。

MySQL複製基於主服務器在二進制日誌中跟蹤所有對數據庫的更改(更新、刪除等等)。因此,要進行復制,必須在主服務器上啓用二進制日誌。

每個從服務器從主服務器接收主服務器已經記錄到其二進制日誌的保存的更新,以便從服務器可以對其數據拷貝執行相同的更新。

從服務器設置爲複製主服務器的數據後,它連接主服務器並等待更新過程。如果主服務器失敗,或者從服務器失去與主服務器之間的連接,從服務器保持定期嘗試連接,直到它能夠繼續幀聽更新。由--master-connect-retry選項控制重試間隔。 默認爲60秒。

每個從服務器跟蹤複製時間。主服務器不知道有多少個從服務器或在某一時刻有哪些被更新了。

 

4.2      主從同步過程的相關文件

默認情況,中繼日誌使用host_name-relay-bin.nnnnnn形式的文件名,其中host_name是從服務器主機名,nnnnnn是序 列號。用連續序列號來創建連續中繼日誌文件,從000001開始。從服務器跟蹤索引文件中目前正使用的中繼日誌。 默認中繼日誌索引文件名爲host_name-relay-bin.index。默認情況,在從服務器的數據目錄中創建這些文件。可以用--relay- log--relay-log-index服務器選項覆蓋 默認文件名

中繼日誌與二進制日誌的格式相同,並且可以用mysqlbinlog讀取。SQL線程執行完中繼日誌中的所有事件並且不再需要之後,立即自動刪除它。沒有 直接的刪除中繼日誌的機制,因爲SQL線程可以負責完成。然而,FLUSH LOGS可以循環中繼日誌,當SQL線程刪除日誌時會有影響。

 

從屬複製服務器在數據目錄中另外創建兩個小文件。這些狀態文件默認名爲主master.info和relay-log.info。它們包含SHOW SLAVE STATUS語句的輸出所顯示的信息(關於該語句的描述參見13.6.2節,“用於控制從服務器的SQL語句”)。狀態文件保存在硬盤上,從服務器關閉時 不會丟失。下次從服務器啓動時,讀取這些文件以確定它已經從主服務器讀取了多少二進制日誌,以及處理自己的中繼日誌的程度。

由I/O線程更新master.info文件。文件中的行和SHOW SLAVE STATUS顯示的列的對應關係爲:

 

行 描述

1 文件中的行號

2 Master_Log_File

3 Read_Master_Log_Pos

4 Master_Host

5 Master_User

6 密碼(不由SHOW SLAVE STATUS顯示)

7 Master_Port

8 Connect_Retry

9 Master_SSL_Allowed

10 Master_SSL_CA_File

11 Master_SSL_CA_Path

12 Master_SSL_Cert

13 Master_SSL_Cipher

14 Master_SSL_Key

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


由SQL線程更新relay-log.info文件。文件中的行和SHOW SLAVE STATUS顯示的列的對應關係爲:

 

行 描述

1 Relay_Log_File

2 Relay_Log_Pos

3 Relay_Master_Log_File

4 Exec_Master_Log_Pos

 
 

 

 

 

 

 

 

 


4.3    主從同步過程的相關文件和MySQL語句的關係

 

行 描述

1 文件中的行號

2 Master_Log_File

3 Read_Master_Log_Pos

4 Master_Host

5 Master_User

6 密碼(不由SHOW SLAVE STATUS顯示)

7 Master_Port

8 Connect_Retry

9 Master_SSL_Allowed

10 Master_SSL_CA_File

11 Master_SSL_CA_Path

12 Master_SSL_Cert

13 Master_SSL_Cipher

14 Master_SSL_Key

 
由I/O線程更新master.info文件。文件中的行和SHOW SLAVE STATUS顯示的列的對應關係爲:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SQL線程更新relay-log.info文件。文件中的行和SHOW SLAVE STATUS顯示的列的對應關係爲:

 

行 描述

1 Relay_Log_File

2 Relay_Log_Pos

3 Relay_Master_Log_File

4 Exec_Master_Log_Pos

 
 

 

 

 

 

 

 

 

當備份從服務器的數據時,你還應備份這兩個小文件以及中繼日誌文件。它們用來在恢復從服務器的數據後繼續進行復制。如果丟失了中繼日誌但仍然有 relay-log.info文件,你可以通過檢查該文件來確定SQL線程已經執行的主服務器中二進制日誌的程度。然後可以用 Master_Log_File和Master_LOG_POS選項執行CHANGE MASTER TO來告訴從服務器重新從該點讀取二進制日誌。當然,要求二進制日誌仍然在主服務器上。

如果從服務器正複製LOAD DATAINFILE語句,你應也備份該目錄內從服務器用於該目的的任何SQL_LOAD-*文件。從服務器需要這些文件繼續複製任何中斷的LOAD DATA INFILE操作。用--slave-load-tmpdir選項來指定目錄的位置。如果未指定,默認值爲tmpdir變量的值。

4.4      主從同步起點的說明

master.info的內容會覆蓋命令行或in my.cnf中指定的部分選項。如果從服務器啓動時master.info文件不存在,選項採用選項文件或命令行中指定的值。首次將服務器作爲從服務器啓動時,或者已經運行RESET SLAVE然後已經關閉並重啓從服務器時會發生。

如果從服務器啓動時master.info文件存在,服務器忽略那些選項。使用master.info文件中發現的值。如果你使用與master.info文件中相對應的啓動選項的不同的值重啓從服務器,啓動選項的不同的值不會生效,因爲服務器繼續使用 master.info文件。要想使用啓動選項的不同的值,必須刪除master.info文件並重啓從服務器,或(最好是)在從服務器運行時使用 CHANGEMASTER TO語句重新設置值。

4.5    兩個重要的選項

· --logs-slave-updates

這個是在my.cnf文件配置的。通常情況,從服務器從主服務器接收到的更新不記入它的二進制日誌。該選項告訴從服務器將其SQL線程執行的更新記入到從服務器自己的二進制日誌。爲了使該 選項生效,還必須用--logs-bin選項啓動從服務器以啓用二進制日誌。

如果想要應用鏈式複製服務器,應使用logs-slave-updates。例如,可能你想要這樣設置:A -> B -> C 也就是說,A爲從服務器B的主服務器,B爲從服務器C的主服務器。爲了能工作,B必須既爲主服務器又爲從服務器。你必須用--logs-bin啓動A和B以啓用二進制日誌,並且用--logs-slave-updates選項啓動B。

·--slave-skip-errors=[err_code1,err_code2,... | all]

這個是在mysql啓動時的選項通常情況,當出現錯誤時複製停止,這樣給你一個機會手動解決數據中的不一致性問題。該選項告訴從服務器SQL線程當語句返回任何選項值中所列的錯誤時繼續複製。

如果你不能完全理解爲什麼發生錯誤,則不要使用該選項。如果複製設置和客戶程序中沒有bug,並且MySQL自身也沒有bug,應不會發生停止複製的錯誤。濫用該選項會使從服務器與主服務器不能保存同步,並且你找不到原因。

對於錯誤代碼,你應使用從服務器錯誤日誌中錯誤消息提供的編號和SHOW SLAVE STATUS的輸出。服務器錯誤代碼列於附錄B:錯誤代碼和消息。

你也可以(但不應)使用不推薦的all值忽略所有錯誤消息,不考慮所發生的錯誤。無需而言,如果使用該值,我們不能保證數據的完整性。在這種情況下,如果從服務器的數據與主服務器上的不相近請不要抱怨(或編寫bug報告),已經警告你了。

 

 

 

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