MySQL做爲當前最流行的關係型數據庫,在各個行業的系統中扮演着最重要的角色。隨着你們對數據價值承認的逐步加深,數據的可靠性是最常被問到的一個問題。MySQL是如何保證數據可靠性的?京東智聯雲RDS-MySQL又作了哪些優化和新特性來保證用戶數據的可靠性和一致性?本篇文章將爲你們一一揭祕。數據庫
MySQL的Innodb存儲引擎支持ACID(原子性Atomicity,一致性Consistency,隔離性Isolation,持久性Durability)特性,正是由於保證了一致性和持久性,因此數據纔是可靠的。不少關係型數據庫爲保障數據庫的可靠性,同時最大限度地提高性能,採用了預寫日誌(Write-Ahead Logging)的方法,MySQL也不例外。它將數據變化先寫入日誌,而後馬上返回給客戶端更新成功,真正的數據再異步更新到磁盤的數據文件。若是中間系統發生故障,只要日誌在數據就不會丟失,這就保證了數據的可靠性。緩存
MySQL寫入的日誌就是binlog和redo log文件,下面咱們來介紹下兩種日誌的寫入流程。安全
事務執行過程當中,MySQL會將全部變動記錄到binlog cache中,在事務commit的時候一塊兒寫入binlog文件中。網絡
binlog cache是由參數binlog_cache_size控制,默認32KB,若是事務很大,變動內容超過了binlog cache,則會寫到磁盤中。經過命令show global status like 'Binlog_cache_disk_use';能夠查看binlog cache寫入磁盤的次數,若是數量過多,建議調大binlog_cache_size參數值。架構
每一個線程都會分配binlog cache,可是都共用一份binlog文件。流程圖以下:併發
在寫入到系統的日誌文件中有兩個步驟,write和fsync。wirte是寫入操做系統的緩存,fsync是持久化到磁盤文件,這個操做會佔用系統的IOPS,而它們操做的時機是經過參數sync_binlog控制。運維
l sync_binlog=0,事務提交時,只作write操做,由操做系統本身控制fsync操做。這個是最危險的,一旦操做系統宕機,binlog cache中的變動內容所有會丟失。異步
l sync_binlog=1,事務提交時,都會作write和fsync操做。安全性最高,可是性能損耗也是最大的。高併發
l sync_binlog=N,事務提交時,會作write操做,累積N個事務時作fsync操做。一旦操做系統宕機,會丟失binlog cache中部分變動內容。性能
事務執行過程當中,也是先寫入內存redo log buffer中,而後再寫入到磁盤文件。其中redo log buffer是全部線程共用的。與binlog寫到文件同樣,寫redo log也有write和fsync兩個操做,它們操做的實際是經過參數innodb_flush_log_at_trx_commit控制。
l innodb_flush_log_at_trx_commit=0,事務提交時,只將變動內容寫到redo log buffer,由後臺Master線程每秒write和fsync到磁盤文件。
l innodb_flush_log_at_trx_commit=1,事務提交時,執行write和fsync操做。這是最安全的配置。
l innodb_flush_log_at_trx_commit=2,事務提交時,只執行write操做,即只寫到操做系統的緩存中,由後臺Master線程每秒fsync到磁盤文件。
關於這個參數與數據可靠性之間的關係以下表所示:
innodb_flush_log_at_trx_commit
數據庫進程異常
操做系統異常
0
丟失最多1s的數據
丟失最多1s的數據
1
不丟數據
不丟數據
2
不丟數據
丟失最多1s的數據
參數sync_binlog=1與innodb_flush_log_at_trx_commit=1就是DBA常說的「雙1」配置,也是線上環境數據最安全最可靠的配置。
再對比下binlog和redo log的不一樣之處:
binlog
redo log
記錄者
MySQL server
Innodb引擎
記錄時間
事務commit的時候
多種條件觸發,隨時記錄
記錄內容
邏輯日誌
row格式或者statement格式
物理日誌
數據頁的變化,冪等的
binlog和redo log是如何配合起到數據可靠性的做用呢,就不得不提到兩階段提交。它能夠保證binlog和redo log的數據一致性。下圖是事務提交時兩個日誌的記錄流程:
若是在此過程當中出現系統異常,每一個狀態下都是能夠保證數據一致性的。
狀態
處理
若是innodb已經commit,那binlog必定有該事務的event。
事務是一致性的,無需處理。
若是innodb已經prepare,binlog已經有記錄該事務的event,可是innodb未commit。
前滾,innodb須要繼續提交這些事務。
若是innodb已經preprare,binlog沒有記錄event,說明從庫也沒有複製這些event。
回滾。
若是innodb未完成prepare,binlog也應該沒有記錄event。
回滾。
innodb_suport_xa參數,這個參數控制是否打開兩段式提交。默認開啓,若是關閉了,事務則會以不一樣順序的方式寫入binlog。若是宕機恢復、xtarbackup恢復,都是會有數據不一致的風險。這個參數在MySQL5.7.10後就廢棄了,必須開啓。
MySQL發展到如今,集羣也從主備異步複製、半同步複製、group replication不斷髮展和演變。可是它們的核心基礎都是binlog,能夠說MySQL的數據複製都依賴於它,而集羣間的數據一致性更是與binlog有關。主要有兩個點須要特別注意。
a) 大事務。binlog只有在事務commit時纔會記錄到文件,而後從庫才能讀取到數據變動,因此當有大事務的時候,主庫提交後從庫纔開始執行。
b) 大併發。5.6和5.7版本都支持並行複製,可是並行度有限,當主庫併發較高時,從庫會出現延遲。
c) 表結構。主庫表沒有主鍵,binlog是row格式的,主庫執大量行數的更新SQL時,從庫會執行屢次全表掃描,形成延遲。
d) 等待鎖。從庫通常會承擔備份功能,使用xtrabackup進行備份會執行FLUSH NO_WRITE_TO_BINLOG TABLES和FLUSH TABLES WITH READ LOCK操做,在特殊狀況下,這兩個操做會堵塞複製的SQL線程,形成延遲。
e)
京東智聯雲RDS-MySQL集羣使用主從複製架構,爲了保證用戶存儲數據可靠性和安全性,咱們對關鍵流程作了一系列優化和改善工做。以用戶數據安全爲己任,以用戶體驗爲中心。
l 硬件,採用高性能的NVME硬盤,最新型號物理機配置。
l 網絡,跨AZ機器的網絡延遲在1.2ms之內,配置萬兆網卡。
l 數據面,參考京東高併發、高可靠的業務系統優化經驗,京東智聯雲對RDS操做系統配置、MySQL參數配置作了一些列優化,保證數據庫集羣數據的可靠性。
l 控制面,針對集羣的延遲,有多組延遲監控、報警;針對不一樣延遲緣由,會觸發不一樣的優化邏輯,自動下降延遲。
當物理機出現問題或者作數據遷移時,都會涉及MySQL集羣的高可用操做,由於MySQL集羣的複製特色,有可能會出現數據丟失的狀況。京東智聯雲RDS-MySQL在切換時是要保證用戶數據一致性優先的,在判斷集羣數據徹底可靠的狀況下,再作切換操做,保證用戶的數據不丟失,不寫花。
主備切換邏輯圖
MySQL高可用切換流程的複雜性,不在切換的過程,而是觸發切換條件的判斷,下面介紹下RDS-MySQL自動高可用切換的判斷流程。
高可用流程切換完成後,會對集羣數據作一致性校驗,並觸發創建新從庫的流程。
數據庫備份是數據安全的最重要屏障,當出現極端狀況下,集羣全部節點的數據都不可用,就須要依賴備份保證數據的可靠性和安全性。咱們對RDS-MySQL的備份、恢復流程作了一系列優化,保證用戶系統在災備時恢復時間儘可能短,恢復數據儘量最新。
京東智聯雲RDS-MySQL的用戶在使用過程當中,出現過不少數據可靠性相關的案例,下面舉一些典型案例來分享:
問題
因爲用戶併發較大,集羣從庫出現延遲。
發現
從庫對於用戶是不可見的,因此從庫延遲用戶是無需感知的。
經過後臺的監控系統,觸發從庫延遲報警,運維人員才發現這個問題。
解決
後臺任務會掃描全部報警信息,當掃描到延遲報警後,會結合該實例的其餘信息定位故障緣由,而後自動調整集羣數據庫配置,達到下降延遲的目的。延遲報警解除後,恢復集羣配置。
意義
RDS-MySQL部分報警已經實現了「負載異常檢測」、「自動診斷」、「線上配置優化」、「優化效果跟蹤」的閉環處理。
可幫助用戶快速、安全、準確地處理集羣數據安全隱患。
問題
用戶由於人爲誤操做,致使刪除了線上系統的部分數據。
發現
用戶提工單,想快速恢復刪除表的數據到指定時間點。
解決
控制檯提供單庫、單表按時間點快速恢復的功能。技術服務人員直接反饋給用戶該功能的使用文檔。用戶經過自助操做,完成對刪除數據的恢復操做。
意義
RDS-MySQL將備份和恢復功能用到極致,兩類備份方式對應多種恢復流程,方便用戶快速、安全地實現恢復數據庫需求。
RDS-MySQL恢復流程支持:
經過上述內容,想必你們已經對MySQL是如何保證數據可靠性有了初步瞭解,若是還想進一步體驗體驗MySQL 服務,請點擊【閱讀原文】連接體驗試用。
原文連接: