數據庫主從複製原理與主從延時問題優化

https://www.cnblogs.com/syncnavigator/p/10189644.html
https://blog.csdn.net/cwb521sxm/article/details/97303289
https://blog.csdn.net/zhanghan18333611647/article/details/91638443

一、MySQL的數據庫主從複製原理
MySQL的主從複製都是單線程的操作,主庫對所有DDL和DML產生的日誌寫進binlog,由於binlog是順序寫,所以效率很高。Slave的IO Thread線程從主庫中binlog中讀取取日誌。Slave的SQLThread線程將主庫的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是隨即的,不是順序的,成本高很多。由於SQL Thread也是單線程的,如果slave上的其他查詢產生lock爭用,又或者一個DML語句(大事務、大查詢)執行了幾分鐘,那麼所有之後的DML會等待這個DML執行完纔會繼續執行,這就導致了延時。

主從同步延遲的引發原因

1、Master負載

2、Slave負載

3、網絡延遲

4、機器配置(cpu、內存、硬盤)

總之,當主庫的併發較高時,產生的DML數量超過slave的SQL Thread所能處理的速度,或者當slave中有大型query語句產生了鎖等待那麼延時就產生了。

同步延遲的解決方案

最簡單的減少slave同步延時,儘量讓主庫的DDL快速執行。還有就是主庫是寫,對數據安全性較高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置,而slave則不需要這麼高的數據安全,完全可以講sync_binlog設置爲0或者關閉binlog,innodb_flushlog也可以設置爲0來提高sql的執行效率,從庫關閉binlog記錄。另外就是使用比主庫更好的硬件設備作爲slave。
在業務架構上將不同的業務分佈到不同的物理數據庫上,同一個業務分庫架構,在業務層與數據庫之間增加分佈式緩存以便減少主庫的壓力。
在mysql 5.7版本後開始支持多線程並行複製技術enhanced multi-threaded slave(簡稱MTS)。
MySQL並行同步機制

並行同步在MySQL5.6就開始支持,只不過在5.6時是基於schema的,也就是基於庫的,相比於5.7的機制要遜色的多。MySQL 5.7纔可稱爲真正的並行複製,這其中最爲主要的原因就是slave服務器的回放與主機是一致的。即master服務器上是怎麼並行執行的slave上就怎樣進行並行回放。不再有庫的並行複製限制。

從MySQL官方來看,其並行複製的原本計劃是支持表級的並行複製和行級的並行複製,行級的並行複製通過解析ROW格式的二進制日誌的方式來完成。但是最終出現給小夥伴的確是在開發計劃中稱爲:MTS: Prepared transactions slave parallel applier。該並行複製的思想最早是由MariaDB的Kristain提出,並已在MariaDB 10中出現,相信很多選擇MariaDB的小夥伴最爲看重的功能之一就是並行複製。

MySQL 5.7並行複製的思想簡單易懂,一言以蔽之:一個組提交的事務都是可以並行回放,因爲這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何衝突(否則就不可能提交)。爲了兼容MySQL 5.6基於庫的並行複製,5.7引入了新的變量slave-parallel-type,其可以配置的值有:

• DATABASE:默認值,基於庫的並行複製方式

• LOGICAL_CLOCK:基於組提交的並行複製方式

MySQL在binlog中定義了兩個Logical_clock的變量:

• max_c ommitted_transaction:記錄上次組提交時的logical_clock,代表上述mysqlbinlog中的last_committed

• transaction_counter:記錄當前組提交中各事務的logcial_clock,代表上述mysqlbinlog中的sequence_number

通過工具檢查binlog文件,可以發現較之原來的二進制日誌內容多了last_committed和sequence_number,last_committed表示事務提交的時候,上次事務提交的編號,如果事務具有相同的last_committed,表示這些事務都在一組內,可以進行並行的回放。例如上述last_committed爲0的事務有6個,表示組提交時提交了6個事務,而這6個事務在從機是可以進行並行回放的。

提升同步的策略中,有很多實現,包括MySQL各版本的實現及MariaDB等分支的實現上,按按粒度區分的三個策略,粒度從粗到細是按庫、按表、按行,而MySQL5.7按照commit_id的策略適用範圍更廣,改進策略併發性更優。

MySQL主從複製實際上基於二進制日誌,原理可以用一張圖來表示:

MySQL數據庫主從同步延遲分析及解決方案

分爲四步走:

  1. 主庫對所有DDL和DML產生的日誌寫進binlog;

  2. 主庫生成一個 log dump 線程,用來給從庫I/O線程讀取binlog;

  3. 從庫的I/O Thread去請求主庫的binlog,並將得到的binlog日誌寫到relay log文件中;

  4. 從庫的SQL Thread會讀取relay log文件中的日誌解析成具體操作,將主庫的DDL和DML操作事件重放。

關於DDL和DML

SQL語言共分爲四大類:查詢語言DQL,控制語言DCL,操縱語言DML,定義語言DDL。

DQL:可以簡單理解爲SELECT語句;

DCL:GRANT、ROLLBACK和COMMIT一類語句;

DML:數據庫操作語言:SQL中處理數據庫中的數據

其主要命令有INSERT,UPDATE,DELETE等,

DDL:數據庫定義語言:定義數據庫的結構。

其主要命令有CREATE,ALTER,DROP

二、主從複製存在的問題

  1. 主庫宕機後,數據可能丟失;

  2. 主從同步延遲。

三、MySQL數據庫主從同步延遲產生原因
原因分析

MySQL的主從複製都是單線程的操作,主庫對所有DDL和DML產生的日誌寫進binlog,由於binlog是順序寫,所以效率很高。Slave的SQL Thread線程將主庫的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是隨即的,不是順序的,成本高很多。另一方面,由於SQL Thread也是單線程的,當主庫的併發較高時,產生的DML數量超過slave的SQL Thread所能處理的速度,或者當slave中有大型query語句產生了鎖等待那麼延時就產生了。

常見原因:Master負載過高、Slave負載過高、網絡延遲、機器性能太低、MySQL配置不合理。

四、主從延時排查方法
通過監控 show slave status 命令輸出的Seconds_Behind_Master參數的值來判斷:

NULL,表示io_thread或是sql_thread有任何一個發生故障;

0,該值爲零,表示主從複製良好;

正值,表示主從已經出現延時,數字越大表示從庫延遲越嚴重。

五、解決方案
解決數據丟失的問題:

  1. 半同步複製

從MySQL5.5開始,MySQL已經支持半同步複製了,半同步複製介於異步複製和同步複製之間,主庫在執行完事務後不立刻返回結果給客戶端,需要等待至少一個從庫接收到並寫到relay log中才返回結果給客戶端。相對於異步複製,半同步複製提高了數據的安全性,同時它也造成了一個TCP/IP往返耗時的延遲。

  1. 主庫配置sync_binlog=1,innodb_flush_log_at_trx_commit=1

sync_binlog的默認值是0,MySQL不會將binlog同步到磁盤,其值表示每寫多少binlog同步一次磁盤。

innodb_flush_log_at_trx_commit爲1表示每一次事務提交或事務外的指令都需要把日誌flush到磁盤。

注意:將以上兩個值同時設置爲1時,寫入性能會受到一定限制,只有對數據安全性要求很高的場景才建議使用,比如涉及到錢的訂單支付業務,而且系統I/O能力必須可以支撐!

解決從庫複製延遲的問題:

  1. 優化網絡

  2. 升級Slave硬件配置

  3. Slave調整參數,關閉binlog,修改innodb_flush_log_at_trx_commit參數值

  4. 升級MySQL版本到5.7,使用並行複製

  5. 1 如何寫頻繁,水平拆分,減少單片寫數量
    7 避免複雜DML操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章