概述
MySQL整體來看,其實就有兩塊:一塊是Server層,它主要做的是MySQL功能層面的事情;還有一塊是引擎層,負責存儲相關的具體事宜。InnoDB引擎特有的日誌是redo log,而Server層的日誌稱爲binlog。binlog記錄了對MySQL數據庫執行更改的所有操作,大體作用:
- 恢復:某些數據的恢復需要二進制日誌。
- 複製(replication):通過複製和執行二進制日誌使一臺遠程的MySQL數據庫(一般爲slave或standby)與一臺MySQL數據庫(一般爲master或primary)進行同步。(阿里cannel開源框架)
- 審計(audit):用戶可以通過二進制日誌中的信息進行審計,判斷是否有對數據庫進行注入的攻擊。
mysql複製原理
- master在每個事務更新數據完成之前,將該操作記錄串行地寫入到binlog文件中,也稱爲二進制文件。
- slave開啓一個I/O Thread,該線程與master建立連接,master則會啓動binlog dump 線程並取binlog事件。如果讀取的進度已經跟上了master,就進入睡眠狀態並等待master產生新的事件。salve的I/O線程將接收到的事件寫入到relay log(中繼日誌)中,且slave連接master的信息及同步進度數據都會保存在master.info文件中(具體內容參考下面複製方式)。
- slave 中的 SQL Thread會讀取relay log(中繼日誌),並順序執行該日誌中的SQL事件,從而與主數據庫中的數據保持一致。
mysql複製模式
- ROW(行模式):記錄那條數據修改了,注意:記錄的是這條記錄的全部數據,即使只更新了一個字段,binlog裏也會記錄所有字段的數據
- 優點:他不記錄sql語句的上下文信息,日誌內容會非常清楚的記錄每條數據詳細的變更細節,即使只更新了一個字段,binlog裏也會記錄所有字段的數據。因爲可靠性強,基本選成這種
- 缺點:binlog日誌會非常大,mysql主從同步時,會產生大量磁盤IO
- Statement(語句模式): 每一條會修改數據的sql都會記錄在binlog中。
- 優點:不需要記錄每一行的變化,減少了binlog日誌量,節約了IO,提高性能。
- 缺點:由於記錄的只是執行語句,爲了這些語句能在slave上正確運行,因此還必須記錄每條語句在執行的時候的一些相關信息,以保證所有語句能在slave得到和在master端執行時候相同 的結果。另外mysql 的複製,像一些特定函數功能,slave可與master上要保持一致會有很多相關問題。
- Mixed(混合模式):在Mixed模式下,一般的語句修改使用statment格式保存binlog,如一些函數,statement無法完成主從複製的操作,則採用row格式保存binlog,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種。
MySQL主從複製方式
前提:binlog文件是順序存儲結構的。
- 基於日誌點複製
- 時間time,根據時間找time到binlog文件中與此時間最近的事務pos進行同步
- 位置pos,根據位置pos找到binlog文件中與此位置最近的事務pos進行同步
- 基於GTID複製
- GTID是全局事務ID,其保證爲每個在master上提交的事務在複製集羣中可以生產一個唯一ID。GTID的生成策略是source_id(也就是server的uuid,在auto.conf文件裏面可以看到):transaction_id(自增序列)。解決Master-Master拓撲模式,binlog迴路問題
- 根據gtid,直接在binlog文件中找到進行同步
區別
- 基於日誌點複製
- 對sql查詢沒有什麼限制
- 故障轉移時重新獲取master的日誌點信息比較困難(因爲偏移點是批量增長的,時間的話有可能一樣)。如果指定錯誤會造成遺漏或者重複,造成主從不一致。
- 基於GTID複製
- 不支持非事務引擎。對執行的sql有一定的限制。
- 可以很方便的進行故障轉移,記錄master最後事務的GTID值。(按事務分,比較清晰)
Mysql複製類型
- MySQL 5.5版本之前,一直採用的是這種異步複製的方式。主庫的事務執行不會管備庫的同步進度,如果備庫落後,主庫不幸crash,那麼就會導致數據丟失.
- 在MySQL在5.5中就順其自然地引入了半同步複製,主庫在應答客戶端提交的事務前需要保證至少一個從庫接收並寫到relay log中。
- MySQL在5.7.17中引入了一個全新的技術,稱之爲InnoDB Group Replication。目前官方MySQL 5.7.17基於Group replication的全同步技術已經問世,全同步技術帶來了更多的數據一致性保障
異步複製
MySQL默認的複製即是異步的.
- 主庫將事務Binlog事件寫入到Binlog文件中
- 主庫通知一下Dump線程發送這些新的Binlog
- 主庫就會繼續處理提交操作(sync binlog, engine Commit)
- 返回客戶端(此時不會保證這些Binlog傳到任何一個從庫節點上)
最大的問題
master和slave事務更新的不同步,當業務併發上來時,slave因爲要順序執行master批量事務,導致很大的延遲。此時,master如果crash掉了,master上已經提交的事務可能沒有傳到slave上,如果此時,強行將從提升爲主,可能導致新主上的數據不完整。
半同步複製
爲解決異步複製的不足,MySQL 5.5~5.6可安裝semisync_master.so插件,使用after_commit模式的半同步複製
- 主庫將事務Binlog事件寫入到Binlog文件中
- 主庫通知一下Dump線程發送這些新的Binlog
- 主庫就會繼續處理提交操作(sync binlog, engine Commit),並向從庫發生Event。
- dumper線程等待接收slave的ack工作
- 返回客戶端
最大的問題
主庫將事務在存儲引擎層(engine Commit)提交後,主庫發生了crash,Slave端還沒有讀到該事務的events。此時,雖然主庫沒有返回當前客戶端,但事務已經提交,其他客戶端會讀取到已提交事務。現在強行將從提升爲主,那麼之前讀到的事務就不見了,出現了幻讀。
針對上述的問題,5.7.2引入了Loss-less Semi-Synchronous插件,支持after_sync模式的半同步複製
6. 主庫將事務Binlog事件寫入到Binlog文件中
7. 主庫通知一下Dump線程發送這些新的Binlog
8. 主庫就會繼續處理提交操作(sync binlog),並向從庫發生Event。
9. Receiver線程等待接收slave的ack工作
10. 主庫就會繼續處理提交操作engine Commit
11. 返回客戶端
兩者區別
- 獨立出一個Ack Receiver線程 ,專門用於接收slave返回的ack請求,這將之前dump線程的發送和接受工作分爲了兩個線程來處理。
- 無損複製在write binlog完成後,就傳輸binlog,但還沒有去寫commit log,意味着當前這個事物對數據庫的修改,其他事物也是不可見的。因此,不會出現幻讀,數據丟失風險。
實際使用中還碰到一種情況從庫IO線程有延遲時,主庫會自動把半同步複製降爲異步複製;當從庫IO延遲沒有時,主庫又會把異步複製升級爲半同步複製。
全同步複製
又稱組複製。基於傳統異步複製和半同步複製的缺陷——數據的一致性問題無法保證,官方在5.7.17版本正式推出組複製(MySQL Group Replication,簡稱MGR)。
MGR依靠分佈式一致性Paxos協議(變體),實現了分佈式下數據的最終一致性,並且所有以前特點
- 高可用:一臺機子掛了,其它正常
- 可擴展:可加節點,新加節點會同步老節點數據(必須基於GTID)
- 容錯:容忍 f 個故障機所需的服務器數量 n 爲:n = 2 * f + 1。
mysql複製常用拓撲結構
複製的體系結構有以下一些基本原則:
- 每個slave只能有一個master;
- 每個slave只能有一個唯一的服務器ID;
- 每個master可以有很多slave;
- 如果你設置log_slave_updates,slave可以是其它slave的master,從而擴散master的更新。
常見的拓撲結構有:
- master和slave
- 主動-被動模式的Master-Master
- 帶從服務器的Master-Master結構
- master和分發master和slave
- 級聯複製架構 Master –Slaves - Slaves
備份恢復
“複製是備份”是我們經常碰到一個誤區,複製不是備份。如果意外發生主庫"drop database",備庫能否幫我們恢復所有的數據?而我們的備份方案往往是根據恢復需求而來的。
備份方案
-
邏輯備份還是物理備份
- 邏輯備份:由數據庫服務器完成生成邏輯備份,比如dump將表以sql 的方式導出
- 物理備份:基於文件,只需要將需要的文件複製到其他地方即可完成備份,比如binlog。InnoDB需要停止數據庫服務(FLUSH TABLES WITH READ LOCK)把緩存中的數據都刷到磁盤,或者直接關停Mysql
-
在線備份還是離線備份
- 離線備份:將Mysql關停,備份數據(大多情況無法接受)
- 物理備份:Mysql運行期間進行備份,大致要考慮
- 鎖時間:需要持有鎖多長時間,例如備份期間持有的全局FLUSH TABLES WITH READ LOCK。將數據導出
- 備份時間和負載: 複製備份到目的地需要多久及對服務器性能的影響有多少(Perconna XtraBackup工具有控流產品)
- 恢復時間:把備份鏡像從存儲位置複製到MySQL服務器,重放二進制日誌需要多久
-
快照方式
- 複製數據文件產生副本
- 文件系統快照,LVM
- 硬盤快照,RAID
-
全量備份還是增量備份
- 全量備份:全部備份下來
- 增量備份:上次全量備份後,所發生改變的數據進行備份
互聯網複製備份架構選擇
- 複製拓撲採用主動-被動模式的Master-Master
- 在被動Master(備庫)使用 XtraBackup 進行 每週全量,第日增量的物理備份
- 在被動Master(備庫),接入canal等開源框架並向其它庫分發(模擬從庫)
滿足以下問題:
- 選擇性複製:模擬從庫可以根據自己的需要拉取相關數據
- 分離功能:Master只做OLTP.OLAP在模擬從庫做
- 數據歸檔:模擬從庫,可不接收Master的delete事件。Master最好保證邏輯設計,由DBA統一刪除。最好使用唯一的ID,以防止歸檔的時間出現錯誤
- 文件系統快照:停機被動Master,全量備份Mysql數據文件.然後再flush logs,將後面提交的寫到新的binlog中,方便增量備份。
- 數據一致性:binlog事件是基於事務的,不能防止邏輯設計很差的應用
主要參考
《高性能Mysql》
《MySQL 5.7半同步複製技術》
《MySQL 8 複製(七)——組複製基本原理》