1、複製的意義html
mysql的複製功能是構建基於MySql大規模,高性能應用的基礎,咱們能夠經過爲服務器配置一個或多個備庫來進行數據同步;複製功能不只有利於構建高性能的應用,同時也是高可用性,可擴展行,災難恢復,備份以及數據倉庫等工做的基礎mysql
2、複製的方式sql
Mysql支持3種方式:基於語句的複製、基於行的複製、混合複製。對應的binlog的格式也有三種:STATEMENT,ROW,MIXED數據庫
(1)基於語句的複製(SBR)緩存
每一條會修改數據的sql語句會記錄到binlog中。優勢是不須要記錄每一條sql語句和每一行的數據變化,減小了binlog日誌量,節約IO,提升性能。缺點是在某些狀況下會致使master-slave中的數據不一致(如RAND(),UUID(),存儲過程,觸發器等)服務器
(2)基於行的複製(RBR)多線程
不記錄每條sql語句的上下文信息,轉而需記錄哪條數據被修改了,修改爲什麼樣了。而且不會出現某些特定狀況下的存儲過程、觸發器等在基於語句複製的模式下致使沒法被正確複製的問題。缺點是會產生大量的日誌,尤爲是alter table的時候會讓日誌暴漲,沒法準確的判斷執行了那些sql,此外在備庫上改表的schema時會出現複製失敗,好比沒有在最後加列或刪除列架構
(3)混合複製(MRB)併發
以上兩種模式的混合使用,MySQL會根據執行的SQL語句選擇日誌保存方式,通常的複製使用STATEMENT模式保存binlog,對於STATEMENT模式沒法複製的操做使用ROW模式保存binlog。oracle
3、與複製相關的文件
mysql-bin.index:在服務器上開啓二進制日誌的同時會生成一個和二進制日誌同名的但以.index做爲後綴的文件,該文件用於記錄磁盤上的二進制日誌文件,這裏的「index」並非指表的索引,而是說這個文件的每一行包含了一個二進制的文件名,Mysql依賴於這個文件,除非在這個文件裏有記錄不然mysql識別不了二進制文件
mysql-relay-bin-index:中繼日誌的索引文件和mysql-bin.index的做用相似
master.info:這個文件用於保存備庫連接到主庫所須要的信息,格式爲存文本,不一樣的mysql版本,其記錄的信息也可能不一樣;此文件不能刪除,不然備庫在重啓後沒法鏈接到主庫。此外這個文件以文本的形式記錄了複製用戶的密碼,因此要注意對此文件的權限控制
relay-log.info:這個文件包含了當前備庫負責的二進制日誌和中繼日誌座標(例如,備庫複製在主庫複製的位置),一樣也不用刪除這個文件,不然備庫在重啓後將沒法獲知從哪一個位置開始複製,可能致使重放已經執行的語句
4、複製的原理
一、主庫把數據更改記錄在二進制日誌中(Binary Log)中(這些記錄被稱爲二進制日誌事件)
二、備庫啓動一個工做進程,稱爲I/O線程,經過I/O線程向主庫創建一個普通的客戶端鏈接,備庫還會啓動一個SQL線程
三、在主庫上啓動一個特殊的二進制轉儲(binlog dump)線程(該線程沒有對應的SQL命令)
四、主庫上的二進制轉儲線程會讀取主庫上的二進制日誌中的事件經過socket鏈接發送給從庫,備庫上的I/O線程會將接收到的事件記錄到中繼日誌中;主庫上的二進制轉儲線程不會對事件進行輪詢,若是該進程追遇上了主庫,它將進入睡眠狀態,直到主庫發送信號量通知其有新的事件產生時纔會被喚醒
五、備庫的SQL線程執行最後一步,該線程從中繼日誌中讀取事件並在備庫中執行,從而實現備庫數據的更新。當SQL線程追遇上I/O線程時,中繼日誌一般已經在系統緩存中,因此中繼日誌的開銷很低。SQL線程執行的事件也能夠經過配置選項來決定是否寫入備庫的二進制日誌中
5、複製的場景
一、同步複製場景
MySQL Cluster(NDB)採用同步複製,保證集羣內數據的強一致性。
其基於shared-nothing架構的內存存儲引擎,應用場景有限,業務不多采用。
二、異步複製場景
數據寫入主庫即返回,從庫經過IO線程拉取日誌,再經過SQL線程進行異步回放。
優勢:寫入主庫便可,無數據複製代價
缺點:業務數據讀取不一致;主庫crash時,從庫數據和主庫不一致
應用場景:對數據讀取一致性要求不高的業務
三、半同步複製場景
1) 半同步
MySQL 5.5引入了半同步複製(semisync),保證至少有一個slave與master一致。
http://dev.mysql.com/doc/refman/5.6/en/replication-semisync.html
master把數據寫入後,將binlog發給slave,半同步複製不要求slave執行,slave收到日誌後就發送ack便可,master收到第一個ack後,事務纔算結束。
但這種方式可能會形成主從數據不一致:當master innodb commit執行成功,再把binlog同步給slave以前crash,就會形成數據不一致。
2) 分組半同步
採用半同步複製,同機房的從庫大機率首先返回ack,這樣跨機房容災成爲空談。因而發展出了分組半同步(semisync + group slave),將不一樣機房劃分爲不一樣的group,每一個機房(group)至少有一個從庫返回ack,事務纔算完成。
優勢:半同步和分組半同步最大限度的保證了數據一致性
缺點:
引入同步(等待ack)形成的性能問題
單機房故障會hang住事務,須要退化爲異步
數據仍然存在不一致可能
主庫在commit和binlog同步之間crash
半同步在超時後會退化爲異步(默認10000ms)
3) 無損半同步
因爲MySQL 5.5,5.6版本的半同步存在數據不一致問題(先commit後同步),MySQL 5.7.2引入了無損(loessness)半同步,即數據寫完slave的relay log後再commit。
https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html
http://my-replication-life.blogspot.com/2013/09/loss-less-semi-synchronous-replication.html
6、並行複製的方式
一、基於庫級別的並行複製
mysql5.6版本
io_thread:根據binlog dump協議從主庫拉取binlog, 並將binlog轉存到本地的relaylog;
Coordinator_thread:負責讀取relay log,將讀取的binlog event以事務爲單位分發到各個worker thread進行執行;在必要時本身執行binlog event
worker_thread(sql_thread):執行分配到的binlog event,各個線程之間互不影響
多線程原理:
sql_thread的分發是依據當前事務鎖操做的數據庫名稱來進行分發,若是事務是跨分片的,須要等待已分配的改數據庫的事務所有執行完畢,纔會繼續分發
二、基於GroupCommit的並行複製
mysql5.7版本,並行複製的實現添加了另一種並行的方式,即主庫在orderd_commit中的第二階段的時候,將同一批commit的binlog打上一個相同的seqno標籤,同一時間戳的事務在備庫是能夠同時執行的,所以簡化了並行複製的邏輯,並打破了mysql5.6版本相同Db不能並行複製的限制。備庫在執行時,具備同一seqno的事務在備庫能夠併發的執行,互補干擾,也不須要綁定信息,後一批seqno的事務須要等待前一批seqno的事務執行完後才能夠執行
優勢:對SRB和RBR都支持
缺點:事務越大,DML操做越多,主庫上能同時提交的概率越小,從庫上回復的並行度也就越小
業務正常壓力模式下,主庫同時提交的事務並很少,歷史備份或者從庫schema change後在追若干前的數據所須要的時間沒法顯著的縮短
三、基於表級別的並行複製
將原有mysql5.6的基於Db基本的分發改爲db_name+table_name,不一樣db_name+table_name的能夠分發給不一樣的worker_thread進行執行
四、基於行級別的並行複製
基於Mysql Row格式的binlog記錄了每一行的全部字段信息,所以能夠在從中取出每一行的primary key或者unique key,經過db_name+table_name+primary_key來進行衝突檢查,對於不衝突的事務能夠並行執行,達到行級別的並行複製缺點:只支持RBR
7、其餘知識點
一、server id
server_id定義在my.cnf中 server_id = xxx,必須明確指定一個惟一的服務器ID,默認的服務器ID一般爲1(這和版本相關,一些mysql版本根本不容許使用這個值)。使用默認值可能會致使和其餘服務器的ID衝突,所以要保證它是惟一且不變的
Mysql在複製過程當中爲了防止環形無限複製,當SQL線程讀取中繼日誌的時候,會丟去事件中記錄的服務器ID和該服務器自己ID相同的事件,從而打破複製過程當中的無限循環。在某些複製拓撲結構下打破無限循環很是重要,例如主-主複製結構
二、redo log 和 bin log
與oracle 不一樣,mysql 的主庫與備庫的同步是經過 binlog 實現的,而redo日誌只作爲mysql 實例的crash recovery使用。
mysql在4.x 的時候放棄redo 的同步策略而引入 binlog的同步,一個重要緣由是爲了兼容其它非事務存儲引擎,不然主備同步是沒有辦法進行的。
redo 日誌同步屬於物理同步方法,簡單直接,將修改的物理部分傳送到備庫執行,主備共用一致的 LSN,只要保證 LSN 相同便可,同一時刻,只能主庫或備庫一方接受寫請求; binlog的同步方法屬於邏輯複製,分爲statement 或 row 模式,其中statement記錄的是SQL語句,Row 模式記錄的是修改以前的記錄與修改以後的記錄,即前鏡像與後鏡像;備庫經過binlog dump 協議拉取binlog,而後在備庫執行。若是拉取的binlog是SQL語句,備庫會走和主庫相同的邏輯,若是是row 格式,則會調用存儲引擎來執行相應的修改。