1. 程式人生 > >mysql主從複製原理及實踐

mysql主從複製原理及實踐

Mysql主從複製原理及實踐

mysql主從框架

      MySQL主從架構是MySQL叢集中最基本也是最常用的一種架構部署,能夠滿足很多業務需求,常見的有一主一從或者一主多從。可以防止單一主機的資料丟失,提高資料的安全性,務上可以實現讀寫分離,可以把一些讀操作在從伺服器上執行,減小主伺服器的負擔。

主從複製原理

      mysql主從複製是指資料可以從一個mysql伺服器節點複製到一臺或者多臺mysql伺服器上,多個從伺服器採用非同步的方式更新主資料庫的變化。MySQL主從同步是基於從庫對主庫binlog檔案的增量訂閱來實現,更新的事件型別寫入到主庫的binlog檔案中,日誌用於記錄所有更新了資料或者已經潛在更新了資料的所有語句,以“事件”的形式儲存,它描述資料更改,它是以二進位制的形式儲存在磁碟中。以.000001的方式結尾,binlog檔案大小和數字會不斷增加,當mysql重啟時,數字會不斷遞增。

                                                                                           主從複製的原理圖:

                                      


    對於每一個主從連線,都需要三個程序來完成,master(binlog dump thread)、slave(I/O thread 、SQL thread)。

  • 主節點會為每一個當前連線的從節點建一個binary log dump 程序
  • 從節點上執行start slave命令之後,從節點會建立一個I/O執行緒用來連線主節點,請求主庫中更新的bin-log。I/O執行緒接收到主節點binlog dump 程序發來的更新之後,儲存在本地relay-log中。
  • SQL執行緒負責讀取relay log中的內容,解析成具體的操作並執行,最終保證主從資料的一致性。整個同步操作是非同步執行的。

下面講下在linux系統下實現主從同步的相關操作步驟:

主庫配置

  • 開啟master的binglog日誌,
  • 建立唯一的server_id,
  • 指定要同步的資料庫和和不需要同步的資料庫

1、編輯my.cnf檔案

vi /etc/my.cnf

2、新增配置:

log-bin=master-bin
server-id=1
#需要同步的資料庫
binlog-do-db=shoes
#不需要同步的mysql系統資料庫
binlog-ignore-db=mysql

3、授予從庫replication許可權

 grant replication slave on *.* to 'root'@'192.168.48.133' identified by '123456';

   這裡的ip地址和使用者密碼都是從庫的,如果提示:Your password does not satisfy the current policy requirements 說明你的密碼是不安全的,此時需要設定密碼的校驗級別,可自行百度。
設定完畢後,重啟master的mysql服務。

使用命令: mysql -uroot -p 登入mysql服務後,執行 show master status;

會出現類似如圖所示的資訊:

記錄下File和Position的值,後面從庫配置的時候需要使用。
好了,到這裡主庫配置完畢,接下來是從庫的配置。

同樣修改my.cnf檔案,新增如下資訊:

server-id=2 
log-bin=mysql-bin 
replicate-do-db=shoes
replicate-ignore-db=mysql

配置連線主伺服器的資訊:

mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.48.128',
-> MASTER_USER='root',
-> MASTER_PASSWORD='123456',
-> MASTER_LOG_FILE='mysql-bin.000002',
-> MASTER_LOG_POS=7641;
mysql> start slave;

這裡的 MASTER_LOG_POS 是要告訴slave庫從master二進位制日誌的哪個地方開始複製,也就是前文檢視主庫狀態的Position的值。

然後檢視slave的狀態:

mysql>show slave status\G

會出現如圖所示的資訊:

   當出現Slave_IO_Running和Slave_SQL_Running都是yes,並且Slave_IO_State是:Waiting for master to send event的時候,說明配置是成功的。如果是Connecting to.......說明沒連上,這時候要檢查下ip地址、賬號或者防火牆等問題了。

在複製的過程中,由於一些其他不當的操作,可能會遇到如圖所示類似的問題,

   這種情況比如說我在從庫上把資料刪掉了,然後主庫又進行刪除,此時找不到從庫上對應的記錄就會報錯,當發生這樣的錯誤之後,從庫就無法更新主庫的資料了。如果主庫都已經刪除了,那麼從庫也就沒有必要保留了,這種情況的話可以設定從庫複製的時候跳過當前這個事件,需要暫停slave操作:

stop slave;
set global sql_slave_skip_counter=1;
start slave;

   類似的問題還有比如說重複插入,更新丟失,relay log 損壞等,都可以採取相應的策略來恢復,如重新選擇到同步的binlog和POS點,然後重新做同步等。

binlog日誌文示例
使用命令

mysql> show binlog events in 'mysql-bin.000002;
檢視binlog日誌。

binlog的日誌格式

mysql的binlog格式分為三種:

Statement
      每一條會修改資料的 SQL 都會記錄到 master 的 bin-log 中。slave 在複製的時候 SQL 程序會解析成和原來 master 端執行過的相同的 SQL 再次執行。

優點:不需要記錄每一行的變化,減少了binlog日誌量,節約了IO,提高效能。

缺點:由於記錄的只是執行語句,為了這些語句能在slave上正確執行,因此還必須記錄每條語句在執行的時候的一些相關資訊,以保證所有語句能在slave得到和在master端執行時候相同的結果。另外mysql 的複製,像一些特定函式功能,slave可與master上要保持一致會有很多相關問題

row
   日誌中會記錄成每一行資料被修改的形式,然後在 slave 端再對相同的資料進行修改。

優點:Binnary Log可以不記錄執行的Query語句的上下文相關資訊,不會出現某些特定情況下儲存過程或function,以及trigger的呼叫和觸發器無法被正確複製的問題。
缺點:如果批量修改資料,記錄的不是批量修改的SQL語句事件,而是每條記錄被更改的SQL語句,比如說update語句,會記錄每一行被修改的sql語句,當alter表的時候,更是會產生大量的日誌。

Mixedlevel
      以上兩種的結合體,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種.新版本的MySQL中隊row level模式也被做了優化,並不是所有的修改都會以row level來記錄,像遇到表結構變更的時候就會以statement模式來記錄。
因此,企業生產上使用哪種弄場景可以根據具體的場景來選擇合適的格式。
檢視binlog格式使用命令:

mysql> show global variables like "%binlog_format%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+

格式可以在my.cnf檔案中進行配置:

binlog_format="ROW"  

或者在執行時動態的修改格式:

mysql> SET SESSION binlog_format = 'STATEMENT';

   通過mysql複製可以將讀操作分佈在多個伺服器上,實現對密集型應用的優化,通過簡單的程式碼修改就可以實現基本的負載均衡,並且能夠幫助應用程式避免mysql的單點故障,實現mysql的高可用性