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