一、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:可以理解為CREATE一類的語句;
DDL:INSERT、UPDATE和DELETE語句都是;
二、主從復制存在的問題
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往返耗時的延遲。
2. 主庫配置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,使用並行復制
更多優化方案措施歡迎廣大博友補充並糾正啦...