mysql主從複製,基於gtid的主從複製
MySQL複製原理,其通過三個執行緒來完成,在master節點上執行的binlogdump執行緒以及在slave節點上執行的I/O執行緒和SQL執行緒。 1. master節點上的binlogdump執行緒,在slave與其正常連線的情況下,將binlog傳送到slave上。 2.slave節點上的I/O執行緒,通過讀取master節點發送的內容,並將資料複製到本地的relaylog中。 3.slave節點上的SQL執行緒,讀取relaylog中的日誌,並將其事務在本地執行。
binlog: binary log,主庫中儲存更新事件日誌的二進位制檔案。
主從複製的基礎是主庫記錄資料庫的所有變更記錄到binlog。binlog是資料庫中儲存配置中過期時間內所有修改資料庫結構或內容的一個檔案。如果過期時間是10d的話,那麼就是最近10d的資料庫修改記錄。
mysql主從複製是一個非同步的複製過程,主庫傳送更新事件到從庫,從庫讀取更新記錄,並執行更新記錄,使得從庫的內容與主庫保持一致。在主庫裡,只要有更新事件出現,就會被依次地寫入到binlog裡面,是之後從庫連線到主庫時,從主庫拉取過來進行復制操作的資料來源
實驗環境:server7:172.25.66.7(master)
server8:172.25.66.8(slave)
在server7中:
vim /etc/my.cnf 主節點必須啟用二進位制日誌,記錄任何修改資料庫資料的事件
/etc/init.d/mysqld start
進行資料庫初始化,第一次輸入的密碼為上面檢視日誌的臨時密碼,後面為root使用者設定的密碼要儘可能複雜,否則一直提示錯誤
在master中:檢視狀態
在server8中:
vim /etc/my.cfg
檢視授權是否成功
出現兩個YES表示成功
測試:在master中
在slave中檢視,資料已同步
基於gtid模式:
GTID是MySQL 5.6的新特性,其全稱是Global Transaction Identifier,可簡化MySQL的主從切換以及Failover。GTID用於在binlog中唯一標識一個事務。當事務提交時,MySQL Server在寫binlog的時候,會先寫一個特殊的Binlog Event,型別為GTID_Event,指定下一個事務的GTID,然後再寫事務的Binlog。主從同步時GTID_Event和事務的Binlog 都會傳遞到從庫,從庫在執行的時候也是用同樣的GTID寫binlog,這樣主從同步以後,就可通過GTID確定從庫同步到的位置了。也就是說,無論是級聯情況,還是一主多從情況,都可以通過GTID自動找點兒,而無需像之前那樣通過File_name和File_position找點兒了。
1、master更新資料時,會在事務前產生GTID,一同記錄到binlog日誌中。
2、slave端的i/o 執行緒將變更的binlog,寫入到本地的relay log中。
3、sql執行緒從relay log中獲取GTID,然後對比slave端的binlog是否有記錄。
4、如果有記錄,說明該GTID的事務已經執行,slave會忽略。
5、如果沒有記錄,slave就會從relay log中執行該GTID的事務,並記錄到binlog。
前面在slave端配置,進行change master to操作時, 使用的是日誌號(指定position),當master端的服務down掉了, 就會在slave端選擇一個日誌號與原來的master最接近的作為master。但是,在另一個slave上,並沒有指定新的master的資訊,因此還要手動去指定,而使用gtid的話,slave通過尋找next的值,並不用指定master的二進位制日誌檔案和日誌號,所以使用gtid更能保證資料的完整性。
server6:172.25.13.6(master)
server7:172.25.13.7(salve)
在master中:
vim /etc/my.cfg
/etc/init.d/mysqld restart 重啟mysql
在slave中:
vim /etc/my.cfg
mysql -p
測試:在master端插入資料
在slave端檢視資料同步過來了
配置一主兩輔
實驗環境:server6作為master,server7和server8相對於server6是slave,把server7作為中繼,扮演其他slave的master,此時,master7把SQL執行緒執行的事件寫進自己的二進位制日誌,然後,master8可以獲取這些事件並執行它,從而有效減輕master端的壓力
server6:首先要備份master中的資料,並將其拷貝到server8中來,實現初始資料相同,否則後面更新資料不會同步
mysqldump -p westos >westos.sql
scp westos.sql 172.25.13.8:
server8:安裝資料庫,完成初始化
vim /etc/my.cfg
/etc/init.d/mysqld start
vim westos.sql 去掉第24行,建立westos資料庫
mysql -p < westos.sql
mysql -p
在srever7中:
vim /etc/my.cfg
/etc/init.d/mysqld restart
測試:
在master中插入資料
在server7中檢視資料已同步
在server8中檢視資料也已同步
半同步複製配置
半同步簡介: 在預設情況下,MySQL的複製是非同步的,這意味著主伺服器及其從伺服器是獨立的。非同步複製可以提供最佳的效能,因為主伺服器在將更新的資料寫入它的二進位制日誌(Binlog)檔案中後,無需等待驗證更新資料是否已經複製到從伺服器中,就可以自由處理其它進入的事務處理請求。但這也同時帶來了很高的風險,如果在主伺服器或從伺服器端發生故障,會造成主從資料的不一致,甚至在恢復時造成資料丟失。 從MySQL5.5開始引入了一種半同步複製功能,該功能可以確保主伺服器和訪問鏈中至少一臺從伺服器之間的資料一致性和冗餘。在這種配置結構中,一臺主伺服器和其許多從伺服器都進行了配置,這樣在複製拓撲中,至少有一臺從伺服器在父主伺服器進行事務處理前,必須確認更新已經收到並寫入了其中繼日誌 (Relay Log)。當出現超時,源主伺服器必須暫時切換到非同步複製模式重新複製,直到至少有一臺設定為半同步複製模式的從伺服器及時收到資訊。 繼5.5半同步複製後,MySQL5.6又對其進行了優化和改進,其中有兩個地方較為重要:
1、在主從切換後,在傳統的方式裡,需要找到binlog和POS點,然後更改master指向,而在mysql5.6裡,你無須再知道binlog和POS點,你只需要知道master的IP、埠,賬號密碼即可,因為同步複製是自動的,mysql通過內部機制GTID自動找點同步。 2、多執行緒複製,以前的版本,同步複製是單執行緒的,只能一個一個執行,在MySQL5.6裡,可以做到多個庫之間的多執行緒複製,但一個庫裡的表,多執行緒複製是無效的。
在主伺服器上:
mysql -p
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> set global rpl_semi_sync_master_enabled=1; #開啟master上的semisync,設定超時時間,可以通過設定rpl_semi_sync_master_timeout變數來修改,預設單位為毫秒
mysql> show variables like '%semi_sync%';
在從節點:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> set global rpl_semi_sync_slave_enabled=1;
mysql> stop slave io_thread; #重啟slave上的IO執行緒
mysql> start slave io_thread;
mysql> show global variables like '%semi%';
檢測:
在master中:
將slave中的半同步關掉,進行插入測試:
mysql> set global rpl_semi_sync_slave_enabled=OFF; ###將半同步設定為關閉
mysql> stop slave io_thread;
mysql> start slave io_thread;
mysql> show global variables like '%semi%';
當把從機的I/O執行緒關閉後,主資料庫在進行對複製資料庫的庫進行更改時,在進行操作會等待10秒,增加了一次半同步傳輸的失敗次數。因為使用半同步失敗,10s後沒有得到反饋資訊,迴轉為非同步方式
Rpl_semi_sync_master_yes_tx ##使用半同步成功的次數,資料一致性效能提高 Rpl_semi_sync_master_no_tx ##使用半同步失敗的次數,10s後沒有得到反饋資訊,會轉為非同步複製