1. 程式人生 > >MySQL對資料庫資料進行復制的基本過程詳解

MySQL對資料庫資料進行復制的基本過程詳解

MySQL對資料庫資料進行復制的基本過程詳解

這篇文章主要介紹了MySQL對資料庫資料進行復制的基本過程,解讀了Slave的一些相關配置,需要的朋友可以參考下

複製

複製是從一個MySQL伺服器(master)將資料拷貝到另外一臺或多臺MySQL伺服器(slaves)的過程.複製是非同步進行的--slaves伺服器不需要持續地保持連線來接收master的資料.依據配置的不同,可以複製所有資料庫,或指定的資料庫,甚至是某一資料庫指定的表.

使用複製功能的目的在於:

向外擴充套件的解決方案 -- 通過在多臺伺服器之間分散負載來提高效能.在這種環境下,所有寫和更新操作都在master伺服器上進行,而讀操作則發生在一臺或多臺slaves伺服器上.
資料安全 -- 因為資料是被複制到slave上的,並且slave可以暫停複製過程,因此可以在不破壞master資料的前提下在slave伺服器上進行備份
分析 -- 實時資料在master上建立,然而資料分析卻可以slave伺服器上進行,且不會影響master的效能
長距離資料分佈 -- 如果分公司需要主公司的資料複本進行工作,就可以通過複製建立一個本地複本,從而不需要長久地訪問master伺服器
MySQL的複製是單向非同步的,這與MySQL Cluster的同步複製特性正好相反.MySQL5.5支援半同步(semisynchronous),即在master上的提交之後,並不是立即返回,而是等待至少有一個slave確認說已經收到和記錄了當前事務之後,再返回.

最好的複製方法與資料的展現方式及所選擇的儲存引擎有關,核心的複製格式有兩種:SBR(Statement Based Replication) -- 複製所有的SQL語句,和RBR(Row Based Replication) -- 僅複製被改變的rows. 當然也有最三種方案可供選擇:MBR(Mixed Based Replication),這也是MySQL5.5之後版本的預設模式.

複製配置

MySQL伺服器之間的複製使用的是二進位制日誌機制.對master的更新與變動都會作為事件(event)記錄在日誌中,日誌中的資訊會隨變化的不同被記錄成不同的格式.slaves被配置成從master讀取日誌,並且執行二進位制日誌中的事件到slave本地資料庫.一旦master啟動二進位制日誌功能,那麼所有語句操作都會被記錄下來,每一個slave會收到一份整個日誌內容的拷貝.slave的責任就是決定日誌中的哪條語句需要被執行,而我們不能通過配置master來僅僅記錄某些特定的事件.如果您沒有另行指定,在主伺服器二進位制日誌中的所有事件都在slave上執行.如果需要,還可以配置slave僅應用來自於特定資料庫或表的事件.

每個slave都會保持一份二進位制日誌檔案的記錄,且記錄其已經讀取和處理過記錄的位置.這表明,多個slaves可以連線到master,並且執行日誌的不同部分,因為slave自己來控制這個過程,單個slave的斷開與連線,不會影響master的操作.同時也正因為每個slave會記錄二進位制日誌中的位置,所以slaves可以斷開,重連,然後從記錄的位置開始起上.

Master和每一個slave都必須賦予一個唯一的ID(可能使用server_id),另外,還必須告知slave其master的主機,日誌檔名和位置(position).可以在會話中通過CHANGE MASTER TO來改變,詳細資訊會記錄在master.info檔案中.

1. 如何啟動複製

1.1 建立一個用於複製的使用者

每個slave都必須使用標準MySQL使用者名稱和密碼連線到master,任何帳號都可以,只要被授予了REPLICATION SLAVE許可權.雖然建立一個單獨用於複製的使用者並不是必須的,但是你需要清楚的是用於複製的帳號的使用者名稱與密碼都是用明文的方式儲存在master.info中的,因此出於安全的考慮還是建立一個的好.如:

mysql>GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.158.1.100' IDENTIFIED BY 'testpass';
即建立了一個使用者名稱為"repl",密碼為"testpass"的帳號,所有的slaves都可以使用同一個帳號,當然我們也可以為每一個slave都建立一個登入帳號.

1.2 配置Master

首先,必須得開啟master的二進位制日誌功能,其次為master設定一個唯一的server-id -- 1~p, li { white-space: pre-wrap; }232-1 之間的正整數.如在my.cnf或my.ini中作如下設定:

[mysqld]

log-bin=master-bin

server-id=1
需要注意的是:為了在使用InnoDB事務時建立複製達到最大可能的穩定及一致,你需要使用:innodb_flush_log_at_trx_commit=1和sync_binlog=1兩個選項.並同時確保:skip-networking=0否則slave與master就無法通訊了.

1.3配置Slave

在slave上我們唯一需要配置的就是為slave指定一個唯一的server-id. Slave上的二進位制日誌功能的開啟不必須的,但開啟可以用來作slave上的資料備份或災難資料恢復,同時也可以使用slave作為更復雜複製拓撲架構的一部分(如:某個slave作為其它slaver的master時).

1.4 獲取Master資訊

為了配置slave複製,你需要知道master在其二進位制日誌中的當前位置,這樣當slave開始複製過程時,就知道從當前這個點開始處理事件了.如果在master上已經存在資料,且這些資料需要在開始複製之前同步到其它slaves上,那麼你就得讓master停止處理語句,獲得當前位置,然後匯出資料.為了得到master的狀態資訊,需要通過下面的步驟:

執行:

mysql>FLUSH TABLES WITH READ LOCK
來阻止所有的寫操作,包括InnoDB的commit操作. 需要注意的此時只有退出了連線客戶端這個"鎖"才能被釋放掉.
通過:

mysql>SHOW MASTER STATUS
來確定當前的二進位制日誌檔案及位移量(offset)
p, li { white-space: pr

1.5 在Slave上配置Master資訊

mysql> CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_USER='replication_user_name',
-> MASTER_PASSWORD='replication_password',
-> MASTER_LOG_FILE='master_bin_log_file_name',
-> MASTER_LOG_POS='recorded_log_position';

2. 複製格式的選擇

每種二進位制日誌格式都有自己的優缺點,對大多數使用者來說,MBR提供了最好的效果.但當需要為某些特定任務選取SBR或RBR時,可以通過下面的比較來決定哪一個更適合:

SBR的優勢:

從MySQL3.23開始,就被證明了的技術
更少的資料寫入日誌. 當更新或刪除影響到很多行時,SBR會使用更少的儲存空間,這也意味著在匯入或恢復時需要更少的時間
日誌檔案包含所有的語句操作所作的變動,因此可以用來審計資料庫
SBR的劣勢:

語句表述(Statements)對SBR來說是不安全的,不是所有修改資料的語句都可以使用SBR複製.任何為確定的行為都很難被複制,如具有LIMIT或ORDER BY的DELETE或UPDATE
INSERT ... SELECT 比RBR需要更多數量的行鎖定
需要掃描整個表的UPDATE(因為沒有在WHERE中使用索引)比RBR要鎖定更多的行
對InnoDB,使用了AUTO_INCREMENT的INSERT會阻塞其它非衝突的INSERT
對於複雜的語句,slave在更新或插入之前必須先進行評估和執行,而RBR只需要執行語句應用不同就可以了
儲存過程執行同樣的NOW()
確定的UDFs必須被應用到所有的slaves上
master與slave上的表必須(幾乎)相同
RBR的優勢:

所有的改變都能被複制,這是最安全的複製模式. 但mysql資料庫不會被複制,mysql會被認為是一個特殊節點資料庫
這種技術與很多其它資料庫管理系統一樣,因此可以許多在其它系統上的認知,都可以轉移到MySQL上來
Master需要更少的鎖定來執行:INSERT ... SELECT,INSERT中有AUTO_INCREMENT,以及WHERE中沒有使用鍵值的 UPDATE/DELETE
Slaves在執行INSERT,UPDATE/DELETE時,需要更少的鎖定
RBR的劣勢:

RBR勢必會產生更多的日誌資料
你不能通過log知道什麼語句被執行了,然後你卻可以通過mysqlbinlog檢視什麼資料被改變了
相關命令

mysql>show slave hosts -- 檢視所有連線到Master的Slave資訊
mysql>show master status -- 檢視Master狀態資訊
mysql>show slave status -- 檢視Slave狀態資訊
MYSQL>SHOW BINARY LOGS -- 檢視所有二進位制日誌
mysql>show binlog events [IN log_file] -- 檢視二進位制日誌中的事件