Mysql主從複製原理及配置
阿新 • • 發佈:2022-05-11
Mysql主從複製原理及配置
Mysql主從複製原理及配置
1.複製概述
Mysql內建的複製功能是構建大型,高效能應用程式的基礎。將Mysql的資料分佈到多個系統上去,這種分佈的機制,是通過將Mysql的某一臺主機的資料複製到其它主機(slaves)上,並重新執行一遍來實現的。複製過程中一個伺服器充當主伺服器,而一個或多個其它伺服器充當從伺服器。主伺服器將更新寫入二進位制日誌檔案,並維護檔案的一個索引以跟蹤日誌迴圈。這些日誌可以記錄傳送到從伺服器的更新。當一個從伺服器連線主伺服器時,它通知主伺服器從伺服器在日誌中讀取的最後一次成功更新的位置。從伺服器接收從那時起發生的任何更新,然後封鎖並等待主伺服器通知新的更新。
請注意當你進行復制時,所有對複製中的表的更新必須在主伺服器上進行。否則,你必須要小心,以避免使用者對主伺服器上的表進行的更新與對從伺服器上的表所進行的更新之間的衝突。(所以一般會把從伺服器設定成只讀read_only= 1)
1.1 mysql支援的複製型別:
1):基於語句的複製:在主伺服器上執行的SQL語句,在從伺服器上執行同樣的語句。MySQL預設採用基於語句的複製,效率比較高.一旦發現沒法精確複製時,會自動選著基於行的複製。
2):基於行的複製:把改變的內容複製過去,而不是把命令在從伺服器上執行一遍. 從mysql5.0開始支援
3):混合型別的複製:預設採用基於語句的複製,一旦發現基於語句的無法精確的複製時,就會採用基於行的複製。
1.2 . 複製解決的問題
MySQL複製技術有以下一些特點:
(1)資料分佈 (Data distribution )
(2)負載平衡(load balancing)
(3)備份(Backups)
(4)高可用性和容錯行 High availability and failover
1.3 複製如何工作 > 複製的原理:
(1) master將改變記錄到二進位制日誌(binary log)中(這些記錄叫做二進位制日誌事件,binary log events);
(2) slave將master的binary log events拷貝到它的中繼日誌(relay log);
(3) slave重做中繼日誌中的事件,將更改應用到自己的資料上。
下圖描述了複製的過程:
slave複製過程:
第一步:master記錄二進位制日誌。在每個事務更新資料完成之前,master二進位制日誌記錄這些改變。MySQL將事務序列的寫入二進位制日誌,即使事務中的語句都是交叉執行的。在事件寫入二進位制日誌完成後,master通知儲存引擎提交事務。
第二步:slave利用I/O thread將master的binary log讀取並拷貝到它自己的中繼日誌。首先,slave開始一個工作執行緒——I/O執行緒。I/O執行緒在master上開啟一個普通的連線,然後開始binlog dump process。Binlog dump process從master的二進位制日誌中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件。I/O執行緒將這些事件寫入中繼日誌。
第三步:SQL slave thread(SQL從執行緒)處理該過程的最後一步。SQL執行緒從中繼日誌讀取事件,並重新執行其中的事件而更新slave的資料,使其與master中的資料一致。該執行緒與I/O執行緒保持一致,中繼日誌通常會位於OS的快取中,所以中繼日誌的開銷很小。
注意:I/O執行緒更新的資料的情況記錄在master.info中.(/application/mysql/data)
此外,在master中也有一個工作執行緒:和其它MySQL的連線一樣,slave在master中開啟一個連線也會使得master開始一個執行緒。複製過程有一個很重要的限制——複製在slave上是序列化的,也就是說master上的並行更新操作不能在slave上並行操作。實際生產過程中,同步並不是實時的,是非同步進行的.
2 .主從實踐配置
準備兩臺MySQL資料庫伺服器Master和slave,Master為主伺服器,slave為從伺服器,初始狀態時,Master和slave中的資料資訊相同,如果資料不相同,應該先把master的資料全備匯出,然後匯入到slave中,這是為了保證主庫從庫資料一致.(利用多埠例項也可以做)
要點:
負責在主、從伺服器傳輸各種修改動作的媒介是主伺服器的二進位制變更日誌,這個日誌記載著需要傳輸給從伺服器的各種修改動作。因此,主伺服器必須啟用二進位制日誌功能。從伺服器必須具備足以讓它連線主伺服器並請求主伺服器把二進位制變更日誌傳輸給它的許可權。
環境:
Master版本為5.1.17和slave的版本同為5.5.34(其實最好版本一樣,不一樣可能有些函式沒辦法複製)
作業系統:centos 6.9
2.1、建立複製帳號
1、在Master的資料庫中建立一個備份帳戶:每個slave使用標準的MySQL使用者名稱和密碼連線master。進行復制操作的使用者會授予replication slave許可權。使用者名稱的密碼都會儲存在文字檔案master.info中
命令如下:
mysql > grant replication slave,reload,super on *.* to 'backup'@’192.168.52.220’ identified by '123456';
建立一個帳戶backup,並且只能允許從192.168.52.220這個地址上來登陸,密碼是123456。這裡@後面的ip地址就是slave的ip
2.2、拷貝資料
(假如是你完全新安裝mysql主從伺服器,這個一步就不需要。因為新安裝的master和slave資料完全一樣)
如果不是則需要:關停Master伺服器,將Master中的資料拷貝到B伺服器中,使得Master和slave中的資料同步,並且確保在全部設定操作結束前,禁止在Master和slave伺服器中進行寫操作,使得兩資料庫中的資料一定要相同!
其中在進行master資料庫全備的時候,請使用引數--master-data=1進行備份如下:
[root@localhost]#mysqldump -uroot -p123456 -A -B -F --master-data=1 -x --events|gzip>備份的檔案.
有這個引數,那麼在做主從同步的時候,執行change master就不用單獨指定mysql-bin的位置,和檔案,因為已經在全備裡面了,而且是執行語句,在從庫進行全備恢復的時候已經完成恢復.和相關檔案的指定.
2.3、配置master
接下來對master進行配置,包括開啟二進位制日誌,指定唯一的servr ID。例如,在配置檔案加入如下值:
server-id = 1 #為主伺服器A的ID值
log-bin=/data/mysqlbinlog/mysql-bin #二進位制變更日誌(根據情況修改)
expire_logs_days = 14 #自動清理 14 天前的log檔案 可根據需要修改
max_binlog_size = 500M #日誌大小
expire_logs_days = 7 表示超過7點的bin-log日誌檔案會自動清理。
max_binlog_size = 500M 表示單個日誌檔案mysql-index.000002的大小超過500M後會自動生成一個新的mysql-index.000003來記錄bin-log,以此類推。
show variables like 'max_binlog_size'; #檢視大小
show variables like '%logs_days%'; # 檢視天數
重啟master,執行SHOW MASTER STATUS,輸出如下則代表二進位制日誌已經成功開啟:
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 106 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
2.4、配置slave
Slave的配置與master類似,你同樣需要重啟slave的MySQL。如下:
log_bin = mysql-bin
server_id= 2
relay_log = mysql-relay-bin
log_slave_updates = 1
read_only= 1
1)server_id是必須的,而且唯一。
2)slave沒有必要開啟二進位制日誌,但是在一些情況下,必須設定,例如,如果slave為其它slave的master,必須設定bin_log。在這裡,我們開啟了二進位制日誌,而且顯示的命名(預設名稱為hostname,但是,如果hostname改變則會出現問題)。
3)relay_log配置中繼日誌,log_slave_updates表示slave將複製事件寫進自己的二進位制日誌(後面會看到它的用處)。
有些人開啟了slave的二進位制日誌,卻沒有設定log_slave_updates,然後檢視slave的資料是否改變,這是一種錯誤的配置。
4)儘量使用read_only,它防止改變資料(除了特殊的執行緒)。但是需要在slave上建立表的應用read_only並是很實用.
配置也需要重啟才生效.
2.5、啟動slave
到此,接下來就是讓slave連線master,並開始重做master二進位制日誌中的事件。你不應該用配置檔案進行該操作,而應該使用CHANGE MASTER TO語句,該語句可以完全取代對配置檔案的修改,而且它可以為slave指定不同的master,而不需要停止伺服器。如下:
mysql> CHANGE MASTER TO MASTER_HOST='主機IP',
-> MASTER_USER='rep',
-> MASTER_PASSWORD='123456',
-> MASTER_LOG_FILE='mysql-bin.000001',#恢復備份用--master-data=1的不需指定.自動在備份中指定
-> MASTER_LOG_POS=0;##恢復備份用--master-data=1的不需要指定.自動在備份中指定
MASTER_LOG_POS的值為0,因為它是日誌的開始位置。
如果沒有用--master-data則可以需要登入資料庫,利用show master status進行MASTER_LOG_FILE
和MASTER_LOG_POS的尋找.
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 106 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
你可以用SHOW SLAVE STATUS語句檢視slave的設定是否正確:
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.52.220
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 4
Relay_Log_File: mysql-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: No
Slave_SQL_Running: No
...omitted...
Seconds_Behind_Master: NULL
Slave_IO_State, Slave_IO_Running, 和Slave_SQL_Running是No
表明slave還沒有開始複製過程。日誌的位置為4而不是0,這是因為0只是日誌檔案的開始位置,並不是日誌位置。實際上,MySQL知道的第一個事件的位置是4。
開始複製,你可以執行:
mysql> START SLAVE;
執行SHOW SLAVE STATUS檢視輸出結果:
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host:192.168.52.220
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 164
Relay_Log_File: mysql-relay-bin.000001
Relay_Log_Pos: 164
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...omitted...
Seconds_Behind_Master: 0
在這裡主要是看:
Slave_IO_Running=Yes
Slave_SQL_Running=Yes
slave的I/O和SQL執行緒都已經開始執行,而且Seconds_Behind_Master不再是NULL。日誌的位置增加了,意味著一些事件被獲取並執行了。
驗證:如果你在master上進行修改,你可以在slave上看到各種日誌檔案的位置的變化,同樣,你也可以看到資料庫中資料的變化。
你可檢視master和slave上執行緒的狀態。在master上,你可以看到slave的I/O執行緒建立的連線:
在master上輸入show processlist\G;
mysql> show processlist \G
*************************** 1. row ***************************
Id: 1
User: root
Host: localhost:2096
db: test
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 2. row ***************************
Id: 2
User: repl
Host: localhost:2144
db: NULL
Command: Binlog Dump
Time: 1838
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
2 rows in set (0.00 sec)
行2為處理slave的I/O執行緒的連線。
注意:
如果啟動 Slave_SQL_Running = No 的狀態,RESET SLAVE ALL 在 5.6 版本中 reset slave 並不會清理儲存於記憶體中的複製資訊比如 master host, master port, master user, or master password,也就是說如果沒有使用change master 命令做重新定向,執行start slave 還是會指向舊的master 上面。當從庫執行reset slave之後,將mysqld shutdown 複製引數將被重置。
在slave伺服器上執行該語句:
mysql> show processlist \G
*************************** 1. row ***************************
Id: 1
User: system user
Host:
db: NULL
Command: Connect
Time: 2291
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 2
User: system user
Host:
db: NULL
Command: Connect
Time: 1852
State: Has read all relay log; waiting for the slave I/O thread to update it
Info: NULL
*************************** 3. row ***************************
Id: 5
User: root
Host: localhost:2152
db: test
Command: Query
Time: 0
State: NULL
Info: show processlist
3 rows in set (0.00 sec)
行1為I/O執行緒狀態,行2為SQL執行緒狀態。