wordpress產品傭金杭州百度整站優(yōu)化服務
MySQL事務日志—redo日志
事務有4種特性: 原子性、一致性、隔離性和持久性。
那么事務的四種特性到底是基于什么機制實現?
- 事務的原子性、一致性由事務的 undo 日志
- 事務的隔離性由鎖機制和MVCC實現。
- 事務的持久性由redo 日志來保證。
兩類日志概述:
- REDO LOG 稱為重做日志,用于保存已提交事務的頁修改操作, 保證事務的持久性。
- UNDO LOG 稱為回滾日志, 回滾行記錄到某個特定版本, 用來保證事務的原子性、一致性。
redo日志作用
背景:在真正訪問頁面之前,需要把在磁盤上的頁緩存到內存中的 Buffer Pool之后才可以訪問。所有的變更都必須先更新緩沖池中的數據,然后緩沖池中的臟頁會以一定的頻率被刷入磁盤(checkPoint機制 ) ,通過緩沖池來優(yōu)化CPU和磁盤之間的鴻溝, 這樣就可以保證整體的性能不會下降太快。
問題:事務提交并不會觸發(fā)check point機制馬上進行持久化,所以有可能存在事務內容丟失的情況。
redo日志就是保證事務提交后的持久化的一種機制。如果發(fā)生宕機,只需要保證數據頁的修改記錄已經保存到了在redo log中,之后重啟就就可以通過redo log去重新刷盤,保證了持久化。
為什么不是直接刷盤,而是把內存數據的修改記錄到redo日志里?redo日志不也是磁盤中的嗎?
- 數據修改量與刷盤的數據量的差距太大,因為mysql是以頁為單位進行IO,而修改的數據量可能只有幾個字節(jié)。
- 直接刷盤效率太低,因為SQL修改的磁盤頁不一定連續(xù),所以說是隨機IO。
使用redo日志的優(yōu)點?
- 降低了完整刷盤的頻率,每次只記錄頁面修改的內容即可
- redo log是順序寫入磁盤的,屬于順序IO,效率高
redo log什么時候產生?
實時產生,每執(zhí)行一個SQL語句對應的數據修改都會記錄在redo log中,而不是事務提交才記錄。
redo日志工作原理
redo log的組成
Redo log可以簡單分為以下兩個部分:
-
重做日志的緩沖 ( red o log buffer) , 保存在內存中, 是易失的。
-
-
重做日志文件 ( redo log file) , 保存在硬盤中, 是持久的。如var/lib/mysql目錄下的ib_logfile0和 ib _logfile1 文件即為REDO日志。
redo log工作流程
InnoDB的更新操作采用的是 Write Ahead Log(預先日志持久化)策略, 即先寫日志, 再寫入磁盤。
mysql事務對數據進行修改,大致過程:
- 開始一個事務
- 執(zhí)行SQL語句,先將原始數據從磁盤中讀入內存的buffer pool中來
- 記錄數據舊值到undo log以便于回滾,然后再對內存中的buffer pool數據進行修改
- 將內存頁的修改情況記錄到redo log buffer(內存中)
- 如果事務中途失敗,則通過undo log回滾
- commit事務,根據刷盤策略的配置決定采取什么行為,默認:把redo buffer數據直接追加到redo磁盤文件中
- 按照一定頻率執(zhí)行真正的刷盤(check point機制)
- 如果事務成功commit但沒有成功刷盤的時候(步驟5-6之間),發(fā)生宕機,則重啟后會根據redo日志中的記錄再執(zhí)行刷盤
redo日志刷盤策略
redo log刷盤策略是指將redo buffer同步到redo log磁盤文件中的過程
注意:redo log buffer刷盤到 redo log file的過程并不是真正的刷到磁盤中去, 只是刷入到文件系統緩征 ( page cache) 中去 , 真正的寫入會交給系統自己來決定。那么對于InnoDB來說就存在一個問題, 如果交給系統來同步, 同樣如果系統宕機,那么數據也丟失了 (雖然整個系統宕機的概率還是比較小的) 。
針對這種情況, InnoDB給出 innodb _ flush _ log _ at _ trx _ commit參數, 該參數控制 commit提交事務時, 如何將 redo log buffer中的日志刷新到 red o log file中。它支持三種策略:
- 設置為0: 表示每次事務提交時不進行刷盤操作。(系統默認 master thread每隔1s進行一次重做日志的同步)
- 設置為1 : 表示每次事務提交時都將進行同步, 刷盤操作 (默認值)
- 設置為2: 表示每次事務提交時都只把 red o log buffer 內容寫入 page cache, 不進行同步。由 os自己決定什么時候同步到磁盤文件。(其實也是交給master thread處理)
拓展:master thread是InnoDB存儲引擎的后臺線程, 每隔1 秒, 就會把 redo log buffer 中的內容寫到文件系統緩存( page cache) , 然后調用刷盤操作。三種刷盤策略都會收到master thread的影響。
策略一:事務提交,立馬同步到redo log文件
優(yōu)點:安全性很高,只要事務提交了,數據就是安全的
缺點:速度慢
策略二:事務提交,只保存到文件系統的page cache
優(yōu)點:速度快,安全性也相對較高,因為只要把修改記錄保存到page cache中了,即使MySQL崩潰了,數據也還是能夠保證持久化,除非整個系統宕機了(概率小)
缺點:有概率產生事務數據丟失的情況,丟失1s的數據(等待master thread同步的1s的過程中宕機了)
策略三:事務提交,什么也不干
優(yōu)點:速度快
缺點:安全性差,1s內發(fā)生MySQL奔潰或者OS宕機,都會丟失事務的修改數據
總結
redo buffer是實時變化的,而刷盤不是實時進行的,根據同步時機,可分為如下三種:
- 事務commit時,將redo buffer同步到操作系統的文件緩存cache中,然后馬上將文件緩存cache同步寫入到redo log文件中(默認,做兩步)
- 事務commit時,只將redo buffer同步到操作系統的文件緩存cache中,具體什么時候同步到redo log文件中,取決于后臺子線程(做一步,另一步交給后臺線程)
- 事務commit時,什么也不做,什么時候同步完全取決于后臺子線程(什么都不做,都交給后臺線程)
三種策略的安全性由高到低,速度由慢到快,但出于安全考慮,最好還是選擇默認的。