程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> 關於MYSQL數據庫 >> 解讀mysql主從配置及其原理分析(Master-Slave)

解讀mysql主從配置及其原理分析(Master-Slave)

編輯:關於MYSQL數據庫
1.在主數據庫服務器為從服務器添加一個擁有權限訪問主庫的用戶:
GRANT REPLICATION SLAVE ON *.* TO ' test'@'%' IDENTIFIED BY 'test';
(%表示允許所有IP,可設置指定從服務器IP)
添加用戶後:
可在從服務器上用mysql -h127.0.0.1 -utest -ptest;  來測試是否有權限訪問主數據庫


2.在主據庫配置文件加上:
#master config
server-id       = 1
log-bin          = mysql-bin

3.在從服務器數據庫配置文件:
server-id        = 2 
master-host      =  10.0.0.199 
master-user      =  test
master-password  =  test   
replicate-do-db  =  test 
master-port      =  3306
log-bin          = mysql-bin


如果你的一切配置順利
你在從服務器上輸入命令:show slave status\G
正常情況:Slave_IO_Running:yes
Slave_SQL_Running:yes




在主服務器上輸入show master status



那麼,恭喜,主從數據庫配置OK,可以在主數據庫插入數據進行測試,是否從庫同步木有...
注:請檢查防火牆!!!
其實配置過程是很容易簡單的,不要太過激動,我們再花點時間了解其主從的原理。
下面的內容對你理解應該有點作用。


一 MySQL 復制的基本過程如下(各部分學習自Google,謝謝)
1. Slave 上面的IO線程連接上 Master,並請求從指定日志文件的指定位置(或者從最開始的日志)之後的日志內容;

2. Master 接收到來自 Slave 的 IO 線程的請求後,通過負責復制的 IO線程根據請求信息讀取指定日志指定位置之後的日志信息,返回給 Slave 端的 IO線程。返回信息中除了日志所包含的信息之外,還包括本次返回的信息在 Master 端的 Binary Log 文件的名稱以及在 BinaryLog 中的位置;
3. Slave 的 IO 線程接收到信息後,將接收到的日志內容依次寫入到 Slave 端的RelayLog文件(mysql-relay-lin.xxxxxx)的最末端,並將讀取到的Master端的bin-log的文件名和位置記錄到 master-info文件中,以便在下一次讀取的時候能夠清楚的高速Master“我需要從某個bin-log的哪個位置開始往後的日志內容,請發給 我”

4. Slave 的 SQL 線程檢測到 Relay Log 中新增加了內容後,會馬上解析該 Log 文件中的內容成為在 Master
端真實執行時候的那些可執行的 Query 語句,並在自身執行這些 Query。這樣,實際上就是在 Master 端和 Slave
端執行了同樣的 Query,所以兩端的數據是完全一樣的。

二、設置mysql主從配置的優點:
1、解決web應用系統,數據庫出現的性能瓶頸,采用數據庫集群的方式來實現查詢負載;一個系統中數據庫的查詢操作比更新操作要多得多,通過多台查詢服務器將 數據庫的查詢分擔到不同的查詢服務器上從而提高查詢效率。
2、Mysql數據庫支持數據庫的主從復制功能,使用主數據庫進行數據的插入、刪除與更新操作,而從數據庫則專門用來進行數據查詢操作,這樣可以將更新操作和 查詢操作分擔到不同的數據庫上,從而提高了查詢效率。




二 主從原理如下:

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

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

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

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

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

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

四:主從同步過程的相關文件和MySQL語句的關系
由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

當備份從服務器的數據時,你還應備份這兩個小文件以及中繼日志文件。它們用來在恢復從服務器的數據後繼續進行復制。如果丟失了中繼日志但仍然有 relay-log.info文件,你可以通過檢查該文件來確定SQL線程已經執行的主服務器中二進制日志的程度。然後可以用 Master_Log_File和Master_LOG_POS選項執行CHANGE MASTER TO來告訴從服務器重新從該點讀取二進制日志。當然,要求二進制日志仍然在主服務器上。
如果從服務器正復制LOAD DATA INFILE語句,你應也備份該目錄內從服務器用於該目的的任何SQL_LOAD-*文件。從服務器需要這些文件繼續復制任何中斷的LOAD DATA INFILE操作。用--slave-load-tmpdir選項來指定目錄的位置。如果未指定, 默認值為tmpdir變量的值。
五:主從同步起點的說明
master.info的內容會覆蓋命令行或in my.cnf中指定的部分選項。
如果從服務器啟動時master.info文件不存在,選項采用選項文件或命令行中指定的值。首次將服務器作為從服務器啟動時,或者已經運行RESET SLAVE然後已經關閉並重啟從服務器時會發生。
如果從服務器啟動時master.info文件存在,服務器忽略那些選項。使用master.info文件中發現的值。
如果你使用與master.info文件中相對應的啟動選項的不同的值重啟從服務器,啟動選項的不同的值不會生效,因為服務器繼續使用 master.info文件。要想使用啟動選項的不同的值,必須刪除master.info文件並重啟從服務器,或(最好是)在從服務器運行時使用 CHANGE MASTER TO語句重新設置值。
六:如何確保所有從服務器已經處理了中繼日志中的所有語句
在每個從服務器上,發出STOP SLAVE IO_THREAD語句,然後檢查SHOW PROCESSLIST語句的輸出,直到你看到Has read all relay log。當所有從服務器都執行完這些,它們可以被重新配置為一個新的設置。在被提升為主服務器的從服務器S1上,發出STOP SLAVE和RESET MASTER語句。
七:如果你確定可以跳過來自主服務器的下一個語句,可以執行下面的語句
復制代碼 代碼如下:
mysql> SET GLOBAL SQL_slave_SKIP_COUNTER = n;
mysql> START SLAVE;

如果來自主服務器的下一個語句不使用AUTO_INCREMENT或LAST_INSERT_ID(),n 值應為1。否則,值應為2。使用AUTO_INCREMENT或LAST_INSERT_ID()的語句使用值2的原因是它們從主服務器的二進制日志中取 兩個事件。
七:兩個重要的選項:
1):· --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。
2):· --slave-skip-errors=[err_code1,err_code2,... | all]
這個是在mysql啟動時的選項
通常情況,當出現錯誤時復制停止,這樣給你一個機會手動解決數據中的不一致性問題。該選項告訴從服務器SQL線程當語句返回任何選項值中所列的錯誤時繼續復制。
如果你不能完全理解為什麼發生錯誤,則不要使用該選項。如果復制設置和客戶程序中沒有bug,並且MySQL自身也沒有bug,應不會發生停止復制的錯誤。濫用該選項會使從服務器與主服務器不能保存同步,並且你找不到原因。
對於錯誤代碼,你應使用從服務器錯誤日志中錯誤消息提供的編號和SHOW SLAVE STATUS的輸出。服務器錯誤代碼列於附錄B:錯誤代碼和消息。
你也可以(但不應)使用不推薦的all值忽略所有錯誤消息,不考慮所發生的錯誤。無需而言,如果使用該值,我們不能保證數據的完整性。在這種情況下,如果從服務器的數據與主服務器上的不相近請不要抱怨(或編寫bug報告)。已經警告你了。
例如:
復制代碼 代碼如下:
--slave-skip-errors=1062,1053
--slave-skip-errors=all

八:二個有用的問與答:
1)Q:如果主服務器正在運行並且不想停止主服務器,怎樣配置一個從服務器?
A:有多種方法。如果你在某時間點做過主服務器備份並且記錄了相應快照的二進制日志名和偏移量(通過SHOW MASTER STATUS命令的輸出),采用下面的步驟:
復制代碼 代碼如下:
1. 確保從服務器分配了一個唯一的服務器ID號。
2. 在從服務器上執行下面的語句,為每個選項填入適當的值:
mysql> CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_USER='master_user_name',
-> MASTER_PASSWORD='master_pass',
-> MASTER_LOG_FILE='recorded_log_file_name',
-> MASTER_LOG_POS=recorded_log_position;

3. 在從服務器上執行START SLAVE語句。
如果你沒有備份主服務器,這裡是一個創建備份的快速程序。所有步驟都應該在主服務器主機上執行。

以下是引用片段:
1. 發出該語句:
mysql> FLUSH TABLES WITH READ LOCK;
2. 仍然加鎖時,執行該命令(或它的變體):
shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql
3. 發出該語句並且確保記錄了以後用到的輸出:
mysql>SHOW MASTER STATUS;
4. 釋放鎖:
mysql> UNLOCK TABLES;
一個可選擇的方法是,轉儲主服務器的SQL來代替前面步驟中的二進制復制。要這樣做,你可以在主服務器上使用mysqldump --master-data,以後裝載SQL轉儲到到你的從服務器。然而,這比進行二進制復制速度慢。
不管你使用這兩種方法中的那一個,當你有一個快照和記錄了日志名與偏移量時,後來根據說明操作。你可以使用相同的快照建立多個從服務器。一旦你擁有主服務 器的一個快照,可以等待創建一個從服務器,只要主服務器的二進制日志完整。兩個能夠等待的時間實際的限制是指在主服務器上保存二進制日志的可用硬盤空間和 從服務器同步所用的時間。
你也可以使用LOAD DATA FROM MASTER。這是一個方便的語句,它傳輸一個快照到從服務器並且立即調整日志名和偏移量。將來,LOAD DATA FROM MASTER將成為創建從服務器的推薦方法。然而需要注意,它只工作在MyISAM 表上並且可能長時間持有讀鎖定。它並不象我們希望的那樣高效率地執行。如果你有大表,執行FLUSH TABLES WITH READ LOCK語句後,這時首選方法仍然是在主服務器上制作二進制快照。
2)Q:從服務器需要始終連接到主服務器嗎?
A:不,不需要。從服務器可以宕機或斷開連接幾個小時甚至幾天,重新連接後獲得更新信息。例如,你可以在通過撥號的鏈接上設置主服務器/從服務器關系,其 中只是偶爾短時間內進行連接。這意味著,在任何給定時間,從服務器不能保證與主服務器同步除非你執行某些特殊的方法。將來,我們將使用選項來阻塞主服務器 直到有一個從服務器同步。

當備份從服務器的數據時,你還應備份這兩個小文件以及中繼日志文件。它們用來在恢復從服務器的數據後繼續進行復制。如果丟失了中繼日志但仍然有 relay-log.info文件,你可以通過檢查該文件來確定SQL線程已經執行的主服務器中二進制日志的程度。然後可以用 Master_Log_File和Master_LOG_POS選項執行CHANGE MASTER TO來告訴從服務器重新從該點讀取二進制日志。當然,要求二進制日志仍然在主服務器上。
如果從服務器正復制LOAD DATA INFILE語句,你應也備份該目錄內從服務器用於該目的的任何SQL_LOAD-*文件。從服務器需要這些文件繼續復制任何中斷的LOAD DATA INFILE操作。用--slave-load-tmpdir選項來指定目錄的位置。如果未指定, 默認值為tmpdir變量的值

MySQL的 Replication 是一個異步的復制過程,從一個 Mysql instace(我們稱之為 Master)復制到另一個Mysql instance(我們稱之 Slave)。在 Master 與 Slave之間的實現整個復制過程主要由三個線程來完成,其中兩個線程(Sql線程和IO線程)在 Slave 端,另外一個線程(IO線程)在 Master端。

要實現 MySQL 的 Replication ,首先必須打開 Master 端的BinaryLog(mysql-bin.xxxxxx)功能,否則無法實現。因為整個復制過程實際上就是Slave從Master端獲取該日志然後 再在自己身上完全順序的執行日志中所記錄的各種操作。打開 MySQL 的 Binary Log 可以通過在啟動 MySQL Server 的過程中使用“—log-bin” 參數選項,或者在 my.cnf 配置文件中的 mysqld 參數組([mysqld]標識後的參數部分)增加“log-bin” 參數項。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved