MySQL --- 讀書筆記 --- 事務日誌
事務的ACID特性是基於什麼機制實現的
- 事務的隔離性是由
鎖機制
實現的 - 而原子性、一致性、永續性由事務的
redo
和undo
日誌來保證的-
redo
日誌,叫做重做日誌,提供再寫入操作,恢復提交事務修改的頁操作,用來保證事務的永續性。是儲存引擎生成的日誌,記錄的是物理級別
上的頁修改操作,比如頁號xxx,偏移量yyy,寫入zzz資料。主要為了保證資料的可靠性 -
undo
日誌,叫做回滾日誌,回滾行記錄到某個特定版本,用來保證事務的原子性、一致性。是儲存引擎生成的日誌,記錄的是邏輯操作
的日誌,比如對某一行資料進行INSERT語句操作,那麼undo日誌就會記錄一條與之相反的DELETE操作。主要用於事務的回滾和一致性非鎖定讀(MVCC)
-
1. redo日誌
InnoDB
是以頁為單位管理儲存空間的,在訪問頁之前,都需要將頁從磁碟
上快取到Buffer Pool
中才可以訪問。所有的記錄變更都需要先更新Buffer Pool
上的資料,然後Buffer Pool
中的髒頁
會以一定的頻率重新整理到磁碟
,通過快取來優化CPU和磁碟之間的鴻溝,保證整體效能不會下降太快
1.1 為什麼需要redo日誌
一方面,快取可以幫助消除CPU和磁碟之間速度差,checkpoint
機制可以保證資料的最終落盤,然而checkpoint
不是每次變更都會觸發,而是由master執行緒隔一段時間去處理的。那麼在最壞情況下,一定會出現資料丟失。
另一方面,事務包含永續性
那麼,我們不需要在每次修改的時候,就馬上重新整理髒頁到磁碟,如果修改的資料量很小,太浪費資源,而且修改的頁不一定是連續的,出現隨機I/O後,磁碟更新更慢。所以,我只需要記錄一下,修改了什麼。
InnoDB
採用了WAL
技術(Write-Ahead Logging
),這種技術的思想是先寫日誌,再寫磁碟,只有日誌寫入成功,才算事務提交成功,當發生宕機且資料未刷到磁碟的時候,可以通過redo日誌恢復
1.2 redo日誌的好處、特點
優點
儲存表空間ID、頁號、偏移量、以及需要更新的值,所需的空間小,刷盤快
- 降低了刷盤頻率
- 佔用空間小
特點
- 日誌是順序寫入磁碟,順序I/O效率更高
- 事務執行過程中,日誌不斷記錄
1.3 redo日誌的組成
- redo log buffer
在伺服器啟動時,就申請了一大片的連續空間
,預設是16MB
,這邊記憶體空間被劃分成若干個連續的redo log block
,一個block佔用512byte
- redo log file
1.4 redo的整體流程
1.5 redo的刷盤策略
注意,redo log buffer刷盤到redo log file的過程並不是真正的刷到磁碟中,只是刷入檔案系統快取
(page cache)中,真正的寫入是由作業系統來決定。那麼對於InnoDB來說就有一個問題,如果系統宕機了,資料就沒了。
針對這種情況,InnoDB給出了innodb_flush_log_at_trx_commit
引數,該引數控制事務提交的時候,如何將redo log buffer中的日誌重新整理到redo log file。它有三種策略
- 設定0:表示事務提交時不進行重新整理(系統預設每隔1s進行一次redo日誌的同步)
- 設定1:每次事務提交都將進行同步,刷盤操作(預設)
- 設定2:每次提交事務都只把redo log buffer寫入
page cache
,不進行同步,由os決定同步
2. Undo日誌
在事務中,更新
資料之前,需要寫入一個undo log
此外,undo log
會產生redo log
,這是因為undo log
也需要永續性
2.2 undo日誌的作用
- 回滾資料
undo
是邏輯日誌
,因此只是將資料庫恢復到原來的樣子,所有修改都被邏輯取消了,但是資料結構和頁本身在回滾之後可能大不相同。
這是因為在多使用者併發系統中,可能會有成百上千的併發事務,資料庫的主要任務是協調對資料記錄的併發訪問。比如一個事務修改當前一個頁的幾個記錄,同時也有一個事務修改同一個頁的其他幾個記錄,因此,不能將一個頁回滾到事務開始的樣子,這樣會影響其他事務正在進行的工作
- MVCC
在InnoDB中MVCC
的實現是通過undo日誌
來完成的。當用戶讀取一條記錄時,若記錄已經被其他事務佔用了,當前事務可以通過undo讀取之前的行版本資訊,以此實現非鎖定讀取
undo日誌的生成過程
1. 簡要
2. 詳細
行記錄都有的隱藏記錄:事務ID和回滾指標
回滾指標:當新增或者修改一個行記錄,會首先產生一個undo log,然後記錄的回滾指標就會指向這個undo log,同時如果是更新操作,那麼新的undo log會有指向舊的undo log的指標