MySQL的非同步複製和半同步複製
Mysql在5.5及其以後的版本引入了半同步的概念,在這裡也普及一些基礎知識。
一:神馬是半同步,同步,非同步。
1:Mysql的複製過程就是slave去master拉日誌回來,存到relay檔案中,然後執行。
2:Master根本不考慮資料是否達到了slave,或者slave是否執行成功了。
3:預設情況下mysql主從複製就是非同步的方式,別看好像資料剛被建立,slve就可以看到了,因為你的資料量太小了,無法感受到非同步的現象。
4:同步就是兩邊資訊都完全一樣,master確認了slvae資料複製並執行成功,才叫同步。
我們舉個生產例子說明一下這件事。
生產中是否做過資料庫讀寫分離?不管什麼資料庫,讀寫分離就是為了減輕資料庫壓力,假設我們有2臺伺服器,A是寫入庫,B是讀庫。使用者註冊了你網站的會員,註冊的時候,是通過A庫寫入, 登入的時候是同步B伺服器,對吧?
非同步:
註冊寫到A庫,應用前端直接返回註冊成功,然後B庫才到A庫拉取新資料,在本地執行同步。如果由於網路,資料量等原因,B庫還沒有執行新資料,新使用者就點選登入視窗,這個時候,應用前端就提示該使用者尚未註冊。。蛋疼了吧??
同步情況:
註冊寫到A庫,A庫要把資訊同步到B庫,確定B庫執行成功後,返回資訊給前端,這個時候應用前端才顯示註冊成功。使用者在註冊後登入就不會出現異常了。這才符合邏輯吧?Mysql主從複製中,主庫根本不去考慮從庫是否把資訊拷貝過去,或者成功執行了。
半同步又是什麼概念??
如果按mysql主從複製原理看,slave到master把資料垃取下來,然後執行,執行完後,把狀態返回給master,這個時候應用程式才給客戶端響應成功,這種延遲,使用者都接受嗎?找一個折中的方法:Mysql半同步在5.5版本橫空出世。
半同步情況:
一主一從,一主多從情況下,Master節點只要確認至少有一個slave接受到了事務,即可向發起請求的客戶端返回執行成功的操作,master節點是不需要等待slave節點成功執行完這個事務。slave節點接受到這個事務,併成功寫入到本地relay日誌中,就算是成功了。
半同步在資料完成性上得到了保障,起碼主從架構中,有一個備份集,當然,這也不是說半同步配置成功,就不會丟失資料,都是有可能的,比如sql錯誤,半同步發現錯誤後,預設會自動轉換成半同步的。有利有弊,半同步也增加了成本,對效能也有一定的影響。開源的就是這樣。不然為什麼Oracle要收費。哈哈。。
二:檢視系統是否支援半同步
檢視是否載入半同步外掛。
sql> show plugins;
查詢是否有semisync字母。如果沒有跟著步驟走。
步驟1:查詢mysql外掛目錄位置。
sql>show variables like ‘plugin_dir‘;
+---------------+--------------------------------+
| Variable_name | Value |
+---------------+--------------------------------+
| plugin_dir | /usr/local/mysql56/lib/plugin/ |
+---------------+--------------------------------+步驟2:檢視目錄檔案是否存在。
$ll /usr/local/mysql56/lib/plugin/
我們可以發現有2個檔案,一個是master.so 一個是slave.so,在主伺服器載入master檔案,在從伺服器載入slave檔案就可以。
【實驗拓撲】
主機名 | 主機地址 | 角色 |
---|---|---|
node1 | 192.168.2.201 | Master |
node2 | 192.168.2.202 | Slave |
node3 | 192.168.2.203 | Slave |
本文使用CentOS7.1,資料庫:MariaDB-5.5.50
注意:本文關閉了selinux,以及iptables。
一、非同步複製:
相關知識點:
- MySQL的非同步複製是MySQL自帶的資料同步功能,在公司裡面也是也就最為常見的。
- Master伺服器中需要開啟二進位制日誌
binlog
,從伺服器需要開啟中繼日誌relay-log
。 - 二進位制日誌
binlog
的主要功能是:記錄令資料庫內容產生改變的語句,如insert
語句;二進位制日誌在備份還原的時候至關重要。 - 中繼日誌
relay-log
則是從伺服器中開啟,作用是從主伺服器的二進位制日誌中複製,並在在從伺服器本地執行一次,達到與主伺服器內容一致的效果。 - 一般MySQL複製是放在內網中進行的,因為MySQL的同步並沒有進行加密。而且相比較於在公網傳輸,在內網中丟包的概率較低,頻寬也高。
Master節點:Node1
(1) 啟動二進位制日誌;
[mysqld]
log_bin=mysql-bin
(2) 為當前節點設定一個全域性唯一的ID號;
[mysqld]
server_id=1
(3) 授權建立僅有複製許可權的使用者賬號;
mysql> GRANT REPLCATION SLAVE, REPLICATION CLIENT ON *.* TO 'repuser'@'192.168.2.%' IDENTIFIED BY 'repuser';
(4)檢視Master端的二進位制日誌記錄到哪裡,用於決定Slave複製的起始位置
MariaDB [(none)]> show master status;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| Master-log.000001 | 245 | | |
+-------------------+----------+--------------+------------------+
#Slave伺服器如果是一個空的資料庫而主伺服器不為空:
#在同步之前可以先用Master的全量備份,恢復到Slave資料庫中。
#然後再從備份那一刻記錄的Position開始複製。
#假設Master和Slave都為空,上面的情況就表示Slave從二進位制日誌Master-log.000001的245開始複製
從節點:Node2設定
(1) 啟動中繼日誌;
[mysqld]
relay_log=relay-log
relay_log_index=relay-log.index
(2) 為當前節點設定一個全域性惟的ID號;
[mysqld]
server_id=2
#node3把這裡改為3
(3) Slave伺服器開啟只讀模式;
[mysqld]
read_only = 1
(4) 使用有複製許可權的使用者賬號連線至主伺服器,並啟動複製執行緒;
#注意:上面的是在/etc/my.cnf的配置檔案中新增,下面mysql>的則是在mysql伺服器中執行的命令
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.2.201',
MASTER_USER='repuser',
MASTER_PASSWORD='repuser',
MASTER_LOG_FILE='Master-log.000001',
MASTER_LOG_POS=245;
(5)在從伺服器中開啟複製執行緒
mysql> START SLAVE;
檢視從伺服器的狀態資訊
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.2.201
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: Master-log.000003
Read_Master_Log_Pos: 1379
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 1414
Relay_Master_Log_File: Master-log.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1379
Relay_Log_Space: 1702
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
插入幾條命令之後,從以上的狀態資訊中可以看得到我們的Master伺服器是192.168.2.201
擁有複製功能的賬號是repuser,現在複製到Master-log.000003的Position 1379這個位置;
上面的輸出結果中,我在複製完成之後使用了flush logs手動地滾動了二進位制日誌,所以二進位制去到000003
二、半同步複製
相關知識點:
- 半同步複製是由谷歌研發的一種資料庫主從複製方式。
- 與傳統的非同步複製相比,半同步複製在多個Slave節點中會選取一個節點進行半同步複製。也就是說,當Master提交一個事務的時候,在這個半同步複製的Slave端返回一個同步完成的Ack包之後,伺服器才會向使用者返回事務提交成功,而其他的節點則是採用傳統的非同步複製方式進行同步。
- 半同步是複製是基於非同步複製之上進行的,也就是說配置半同步複製之前需要先配置到非同步複製。
- 半同步複製可以保證在主節點發生故障的時候,總有一個節點的資料與主節點一樣。這樣在進行切換的時候,可以更加快速地把這個Slave節點設定成主節點來使用。
Master節點:Node1
由於上面已經進行了非同步複製的配置,下面僅進行半同步複製的操作。
(1)Master安裝外掛並修改變數:mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
外掛的檔名字和路徑一般在rpm -ql mariadb-server那裡檢視。
這個外掛的庫檔案是安裝好之後就直接有的,只是沒有預設安裝。
(2)啟用選項mysql> SET GLOBAL VARIABLES rpl_semi_sync_master_enabled=1;
Slave節點:Node2
(1)slave安裝外掛並修改變數:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL VARIABLES rpl_semi_sync_slave_enabled=1;
這裡需要注意的是,node1作為主節點使用的是master模組。node2,node3作為從節點使用slave模組
(2)檢視半同步複製的全域性變數
mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
設定rpl_semi_sync_master_enabled=1的效果
第一行是ON則表示半同步複製已經開啟。
(3)檢視半同步複製的全域性變數
mysql> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 645 |
| Rpl_semi_sync_master_net_wait_time | 645 |
| Rpl_semi_sync_master_net_waits | 1 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 5 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 783 |
| Rpl_semi_sync_master_tx_wait_time | 783 |
| Rpl_semi_sync_master_tx_waits | 1 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 1 |
+--------------------------------------------+-------+
第一行Rpl_semi_sync_master_clients顯示1,表示有一臺主機是半同步複製的狀態。
最後需要說明的是,semi複製的MySQL5.7中效能有明顯的改善。
假如真的需要使用半同步複製,建議使用5.7的版本。(一般三例項的,從用半同步,從的從用非同步)
總結半同步複製:
什麼是半同步複製?我們知道在預設情況下,MySQL的複製是非同步的,這意味著主伺服器及其從伺服器是獨立的。
非同步複製可以提供最佳的效能,因為主伺服器在將更新的資料寫入它的二進位制日誌(Binlog)檔案中後,
無需等待驗證更新資料是否已經複製到從伺服器中,就可以自由處理其它進入的事務處理請求。但這也同時帶來了很高的風險,
如果在主伺服器或從伺服器端發生故障,會造成主從資料的不一致,甚至在恢復時造成資料丟失。
半同步複製是從MySQL5.5開始引入了一種半同步複製功能,該功能可以確保主伺服器和訪問鏈中至少一臺從伺服器之間的資料
一致性和冗餘。在這種配置結構中,一臺主伺服器和其許多從伺服器都進行了配置,這樣在複製拓撲中,
至少有一臺從伺服器在父主伺服器進行事務處理前,必須確認更新已經收到並寫入了其中繼日誌(Relay Log)。當出現超時,
源主伺服器必須暫時切換到非同步複製模式重新複製,直到至少有一臺設定為半同步複製模式的從伺服器及時收到資訊。
非同步複製(Asynchronous replication)
MySQL預設的複製即是非同步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理,這樣就會有一個問題,主如果crash掉了,此時主上已經提交的事務可能並沒有傳到從上,如果此時,強行將從提升為主,可能導致新主上的資料不完整。
全同步複製(Fully synchronous replication)
指當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。因為需要等待所有從庫執行完該事務才能返回,所以全同步複製的效能必然會收到嚴重的影響。
半同步複製(Semisynchronous replication)
介於非同步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於非同步複製,半同步複製提高了資料的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網路中使用。
下面來看看半同步複製的原理圖:
半同步複製的潛在問題
客戶端事務在儲存引擎層提交後,在得到從庫確認的過程中,主庫當機了,此時,可能的情況有兩種
事務還沒傳送到從庫上
此時,客戶端會收到事務提交失敗的資訊,客戶端會重新提交該事務到新的主上,當當機的主庫重新啟動後,以從庫的身份重新加入到該主從結構中,會發現,該事務在從庫中被提交了兩次,一次是之前作為主的時候,一次是被新主同步過來的。
事務已經傳送到從庫上
此時,從庫已經收到並應用了該事務,但是客戶端仍然會收到事務提交失敗的資訊,重新提交該事務到新的主上。
無資料丟失的半同步複製
針對上述潛在問題,MySQL 5.7引入了一種新的半同步方案:Loss-Less半同步複製。
針對上面這個圖,“Waiting Slave dump”被調整到“Storage Commit”之前。
當然,之前的半同步方案同樣支援,MySQL 5.7.2引入了一個新的引數進行控制-rpl_semi_sync_master_wait_point
rpl_semi_sync_master_wait_point有兩種取值
AFTER_SYNC
這個即新的半同步方案,Waiting Slave dump在Storage Commit之前。
AFTER_COMMIT
老的半同步方案,如圖所示。
半同步複製的安裝部署
要想使用半同步複製,必須滿足以下幾個條件:
1. MySQL 5.5及以上版本
2. 變數have_dynamic_loading為YES
3. 非同步複製已經存在
1、MySQL的非同步複製和半同步複製 - 簡書 http://www.jianshu.com/p/d877cbe9f0f0
2、Mysql5.6.21半同步 http://www.mamicode.com/info-detail-576734.html
3、MySQL資料的主從複製、半同步複製和主主複製詳解 - CSDN部落格 http://blog.csdn.net/goustzhu/article/details/9339621
4、MySQL非同步複製、半同步複製詳解 - paul_hch - 部落格園 http://www.cnblogs.com/paul8339/p/6879329.html
5、MySQL半同步複製 - iVictor - 部落格園 http://www.cnblogs.com/ivictor/p/5735580.html
相關文章
- MySQL 半同步複製MySql
- MySQL半同步複製MySql
- MySQL的半同步複製MySql
- MySQL 8 複製(二)——半同步複製MySql
- MySQL主從複製、半同步複製和主主複製MySql
- MySQL主從複製、半同步複製和主主複製概述MySql
- mysql 5.7半同步複製MySql
- MySQL主從複製之半同步複製MySql
- 【MySQL】半同步與增強半同步複製MySql
- Mysql5.7半同步複製MySql
- mysql半同步複製的設定MySql
- MySQL的主從複製、半同步複製、主主複製詳解MySql
- MySQL5.7主從複製-半同步複製搭建MySql
- 配置mysql5.5主從複製、半同步複製、主主複製MySql
- MySQL 半同步複製+MMM架構MySql架構
- MySQL半同步複製--after_rollbackMySql
- mysql5.5半同步複製探究MySql
- mysql5.5中的半同步複製MySql
- 半同步複製報錯mysql8.0.25MySql
- MySQL半同步複製--after_commitMySqlMIT
- mysql5.5.9半同步複製功能部署MySql
- mysql線上建立半同步複製的從庫MySql
- MySQL 8 複製(一)——非同步複製MySql非同步
- 主從複製、雙主複製及半同步複製、以及基於SSL的複製
- MySQL增強(Loss-less)半同步複製MySql
- MySQL5.5半同步複製實現原理MySql
- MySQL 5.5半同步複製的配置與監控MySql
- MySQL主從複製之非同步複製MySql非同步
- #MySQL# mysql5.7新特性之半同步複製MySql
- MySQL5.7半同步複製報錯案例分析MySql
- MySQL 5.5 Semi-sync 半同步複製測試MySql
- MySQL(二):主從複製結構、半同步複製、雙主複製結構、利用SSL實現安全的MySQL主從複製MySql
- MySQL 5.7半同步複製after sync和after commit詳解MySqlMIT
- MySQL 5.5 主從複製非同步、半同步以及注意事項詳解MySql非同步
- Postgresql 9.6 搭建 非同步流複製 和 同步流複製 詳細教程SQL非同步
- Mariadb之半同步複製叢集配置
- MySQL級聯複製中資料同步MySql
- MySQL主從雙向同步複製MySql