MySQL事务日志
文章目錄
- 一、事務日志介紹
- 二、REDO LOG
- 1、為什么需要REDO日志?
- 2、REDO日志的好處、特點:
- 3、REDO日志的組成
- 4、REDO的整體流程
- 5、redo log的刷盤策略
- 6、redo log file
- 三、UNDO LOG
- 1、為什么需要UNDO日志?
- 2、UNDO日志的作用
- 3、UNDO日志的存儲結構
- 4、undo log的分類
- 5、事務日志的執行過程
一、事務日志介紹
事務有4種特性:原子性、一致性、隔離性和持久性
- 事務的隔離性由 鎖機制 實現。
- REDO LOG 稱為 重做日志 ,提供再寫入操作,恢復提交事務修改的頁操作,用來保證事務的持久性。
- UNDO LOG 稱為 回滾日志 ,回滾行記錄到某個特定版本,用來保證事務的原子性、一致性。
二、REDO LOG
1、為什么需要REDO日志?
因為數據庫需要REDO日志去保證事務的持久性!
那么如何去保證事務的持久性了?
簡單的做法就是:在事務提交完成之前把該事務所修改的所有頁面都刷新到磁盤,但是這個做法是沒有必要的,每一次修改都將頁面刷新到磁盤,是比較耗時間的,而且會產生事務回滾。
另一個做法,就是事務提交時才將修改的所有頁面都刷新到磁盤,即使后來系統崩潰,在重啟后也能把這種修改恢復出來,但是沒必要每次把頁面刷新到磁盤,只需要把 修改 了哪些東西 記錄一下 就好,這就是REDO日志。
redo log 不是隨著事務的提交才寫入的,而是在事務的執行過程中,便開始寫入 redo log 中。
2、REDO日志的好處、特點:
好處:
- redo日志降低了刷盤頻率
- redo日志占用的空間非常小
特點:
- redo日志是順序寫入磁盤的
- 事務執行過程中,redo log不斷記錄
3、REDO日志的組成
REDO LOG可以簡單分為以下兩個部分:redo log buffer、redo log file
- redo log buffer(重做日志的緩沖):保存在內存中,是易失的。
參數設置:innodb_log_buffer_size
redo log buffer 大小,默認 16M,最大值是4096M,最小值為1M。
- redo log file(重做日志文件):保存在硬盤中,是持久的。
4、REDO的整體流程
以一個更新事務為例,redo log 流轉過程,如下圖所示
- 第1步:先將原始數據從磁盤中讀入內存中來,修改數據的內存拷貝
- 第2步:生成一條重做日志并寫入redo log buffer,記錄的是數據被修改后的值
- 第3步:當事務commit時,將redo log buffer中的內容刷新到 redo log file ,對 redo log file采用追加寫的方式
- 第4步:定期將內存中修改的數據刷新到磁盤中
5、redo log的刷盤策略
redo log的寫入并不是直接寫入磁盤的,InnoDB引擎會在寫redo log的時候先寫redo log buffer,之后以 一定的頻率 刷入到真正的redo log file 中。
這里的一定頻率怎么看待呢?這就是我們要說的刷盤策略。
InnoDB給出 innodb_flush_log_at_trx_commit參數,該參數控制 commit提交事務時,如何將 redo log buffer 中的日志刷新到 redo log file 中。它支持三種策略:
- 設置為0 :
表示每次事務提交時不進行刷盤操作。(通過系統默認master thread每隔1s進行一次重做日志的同步)
- 設置為1 :
表示每次事務提交時都將進行同步,刷盤操作( 默認值 )
- 設置為2 :
表示每次事務提交時都只把 redo log buffer 內容寫入 page cache(操作系統的緩存),不進行同步。由os自己決定什么時候同步到磁盤文件。
注意,redo log buffer刷盤到redo log file的過程并不是真正的刷到磁盤中去,只是刷入到 文件系統緩存(page cache)中去(這是現代操作系統為了提高文件寫入效率做的一個優化),真正的寫入會交給系統自己來決定(比如page cache足夠大了)。
6、redo log file
6.1、相關參數設置
- innodb_log_group_home_dir :指定 redo log 文件組所在的路徑,默認值為./,表示在數據庫的數據目錄下。MySQL的默認數據目錄( var/lib/mysql )下默認有兩個名為 ib_logfile0 和ib_logfile1 的文件,log buffer中的日志默認情況下就是刷新到這兩個磁盤文件中。此redo日志文件位置還可以修改。
- innodb_log_files_in_group(log_files文件個數):指明redo log file的個數,命名方式如:ib_logfile0,iblogfile1…iblogfilen。默認2個,最大100個。
- innodb_flush_log_at_trx_commit:控制 redo log 刷新到磁盤的策略,默認為1。
- innodb_log_file_size(log_files文件個數中單個大小):單個 redo log 文件設置大小,默認值為 48M 。最大值為512G,注意最大值指的是整個 redo log 系列文件之和,即(innodb_log_files_in_group ×innodb_log_file_size )不能大于最大值512G。
根據業務修改其大小,以便容納較大的事務。編輯my.cnf文件并重啟數據庫生效,如下所示
[root@localhost ~]# vim /etc/my.cnf innodb_log_file_size=200M6.2、日志文件組和checkpoint
日志文件組示意圖:
總共的redo日志文件大小其實就是: innodb_log_file_size × innodb_log_files_in_group 。
采用循環使用的方式向redo日志文件組里寫數據的話,會導致后寫入的redo日志覆蓋掉前邊寫的redo日志?
當然!所以InnoDB的設計者提出了checkpoint的概念。
如果 write pos 追上 checkpoint ,表示日志文件組滿了,這時候不能再寫入新的 redo log記錄,MySQL 得停下來,清空一些記錄,把 checkpoint 推進一下。
三、UNDO LOG
redo log是事務持久性的保證,undo log是事務原子性的保證。
在事務中 更新數據 的 前置操作 其實是要先寫入一個 undo log 。
1、為什么需要UNDO日志?
因為數據庫需要UNDO日志去保證事務的原子性!
事務需要保證原子性,也就是事務中的操作要么全部完成,要么什么也不做。但有時候執行到一半會出現一些情況,比如:
- 情況一:事務執行過程中可能遇到各種錯誤,比如服務器本身的錯誤,操作系統錯誤,甚至是突然斷電導致的錯誤。
- 情況二:程序員可以在事務執行過程中手動輸入ROLLBACK語句結束當前事務的執行。
以上情況出現,我們需要把數據改為原先的樣子,這個過程稱之為回滾,這樣就可以造成一個假象:這個事務看起來什么都沒做,所以符合原子性要求。
undo log 用來回滾行記錄到某個版本。事務未提交之前,Undo 保存了未提交之前的版本數據,Undo 中的數據可作為數據舊版本快照供其他并發事務進行快照讀。是為了實現事務的原子性而出現的產物,在 MySQL innodb 存儲引擎中用來實現多版本并發控制
2、UNDO日志的作用
- 作用1:回滾數據
- 作用2:MVCC(多版本并發控制)
3、UNDO日志的存儲結構
(1)回滾段與undo頁
InnoDB對undo log的管理采用段的方式,也就是 回滾段(rollback segment) 。每個回滾段記錄了1024 個 undo log segment,而在每個undo log segment段中進行 undo頁 的申請。
- 在 InnoDB1.1版本之前 (不包括1.1版本),只有一個rollback segment,因此支持同時在線的事務限制為 1024 。雖然對絕大多數的應用來說都已經夠用。
- 從1.1版本開始InnoDB支持最大 128個rollback segment ,故其支持同時在線的事務限制提高到了 128*1024 。
(2)回滾段與事務
(3)回滾段中的數據分類
- 第一類:未提交的回滾數據(uncommited undo information)
- 第二類:已經提交但未過期的回滾數據(committed undo information)
- 第三類:失誤已經提交并過期的數據(expired undo information)
4、undo log的分類
在InnoDB存儲引擎中,undo log分為:
- insert undo log
- update undo log
5、事務日志的執行過程
- 第一步:準備更新數據
- 第二步:查看Buffer Pool中是否有對應的數據,若有,則直接跳到第三步,否則需要從磁盤中加載數據
- 第三步:記錄Undo Log
- 第四步:執行器更新數據
- 第五步:將更新后的數據寫入Redo Log Buffer
- 第六步:以對應的刷盤策略,將Redo Log Buffer中的數據刷新到磁盤
- 第七步:寫入BinLog到Binlog文件
總結
- 上一篇: 基于SSM实现在线考试系统
- 下一篇: ubuntu系统下c语言入门以及编写简单