搜尋
首頁資料庫mysql教程MySQL日誌之redo log和undo log的知識點有哪些

MySQL日誌之redo log和undo log的知識點有哪些

May 28, 2023 pm 08:02 PM
mysqlredo logundo log

Redo Log

#REDO LOG稱為重做日誌,當MySQL伺服器意外崩潰或當機後,保證已經提交的交易持久化到磁碟中(持久性)。

InnoDB是以頁為單位去操作記錄的,增刪改查都會加載整個頁到buffer pool中(磁碟->內存),事務中的修改操作並不是直接修改磁碟中的數據,而是先修改記憶體中buffer pool中的數據,後台執行緒每隔一段時間再異步刷新到磁碟中。

buffer pool:可存放索引、數據,可加速讀寫,直接在記憶體中操作資料頁,有專門的執行緒去把buffer pool中的髒頁寫入磁碟。

為什麼不直接修改磁碟中的資料?

因為直接修改磁碟資料的話,它是隨機IO,修改的資料分佈在磁碟中不同的位置,需要來回的查找,所以命中率低,消耗大,而且一個小小的修改就不得不將整個頁刷新到磁碟,利用率低;

與之相對的是順序IO,磁碟的資料分佈在磁碟的一塊,所以省去了查找的過程,節省尋道時間。

使用後台執行緒以一定的頻率去刷新磁碟可以降低隨機IO的頻率,增加吞吐量,這是使用buffer pool的根本原因。

修改記憶體再異步同步到磁碟的問題:

因為buffer pool是在記憶體中的區域,系統意外崩潰的話資料有可能會遺失,有些髒資料可能會來不及刷新到磁碟,事務的持久性得不到保證。因此,引入了redo log。修改資料時,額外記錄一次日誌,內容是xx頁xx偏移量發生了xx變化,當系統崩潰時可以根據日誌內容進行恢復。

寫日誌和直接刷新磁碟的差別是:寫日誌是追加寫入,順序IO,速度更快,且寫入的內容相對更小

redo log由兩部分組成:

  1. redo log buffer(記憶體層面,預設16M,透過innodb_log_buffer_size參數可修改)

  2. redo log file(持久的,磁碟層面)

修改操作大致流程:

MySQL日誌之redo log和undo log的知識點有哪些

#第1步:先將原始資料從磁碟中讀入記憶體中來,修改資料的記憶體拷貝,產生髒資料

第2步:產生一則重做日誌並寫入redo log buffer,記錄的是資料被修改後的值

第3步:預設在交易提交後將redo log buffer中的內容刷新到redo log file,對redo log file採用追加寫的方式

第4步:定期將記憶體中修改的資料刷新到磁碟中(這裡說的是那些還沒及時被後台線程刷盤的髒數據)

通常所說的Write-Ahead Log(預先日誌持久化)指的是在持久化一個數據頁之前,先將記憶體中對應的日誌頁持久化。

redo log的好處:

  • 減少了磁碟重新整理頻率

  • redo log佔用空間小

  • redo log寫入速度快

redo log一定能保證交易的持久性嗎?

不一定,這要根據redo log的刷盤策略決定,因為redo log buffer同樣是在內存中,如果提交事務之後,redo log buffer還沒來得及將數據刷新到redo log file進行持久化,此時發生宕機照樣會遺失資料。如何解決?刷盤策略。

redo log刷盤策略

InnoDB中給出了innodb_flush_log_at_trx_commit參數控制redo log buffer刷新到redo log file時的三種策略:

  • 值為0:開啟一個後台線程,每1s刷新一次到磁碟中,提交事務時就不需要進行刷新了

  • 值為1:commit時再進行同步刷新(預設值),真正保證資料的持久性

  • 值為2:commit的時候,只是刷新進os的核心緩衝區,具體的刷盤時機不確定

值為0的情況:

MySQL日誌之redo log和undo log的知識點有哪些

因為有1s的間隔,所以最壞情況下會遺失1秒的資料。

值為1的情況:

MySQL日誌之redo log和undo log的知識點有哪些

commit時需要先主動刷新redo log buffer到redo log file,如果中途宕機了,交易也就失敗了,不會有任何損失,真正能保證事務的持久性。但是效率最差。

值為2的情況:是根據os決定。

可以調整為0或2提高事務的效能,但是喪失了ACID特性

其他參數

  • innodb_log_group_home_dir:指定 redo log檔案群組所在的路徑,預設值為 ./ ,表示在資料庫的資料目錄下。 MySQL的預設資料目錄下預設有兩個名為ib_logfile0和ib_logfile1的文件,log buffer中的日誌預設有刷新到這兩個磁碟檔案。

  • innodb_log_files_in_group:指明redo log file的數量,命名方式如:ib_logfile0,iblogfile1... iblogfilen。預設2個,最大100個。

  • 預設情況下,innodb_log_file_size的大小設定為48M,用於單一redo log檔案的大小設定。

Undo Log

undo log用來保證交易的原子性和一致性。作用有兩個:①提供回滾操作②多版本控制MVVC

回滾操作

前面redo log中說過,後台執行緒會不定時的去刷新buffer pool中的數據到磁碟,但是如果該事務執行期間出現各種錯誤(宕機)或者執行rollback語句,那麼前面刷進去的操作都是需要回滾的,保證原子性,undo log就是提供事務回滾的。

MVVC

當讀取的某一行被其他事務鎖定時,它可以從undo log分析出該行記錄先前的資料版本是怎樣的,從而讓使用者能夠讀取到目前事務操作之前的資料——快照讀取。

快照讀:SQL讀取的資料是歷史版本,不用加鎖,普通的SELECT就是快照讀。

undo log的組成部分:

  • 當insert記錄的時候,必須將該記錄的主鍵值記錄下來,這樣才可以回滾時刪除該數據。

  • 當update記錄的時候,必須將修改過的舊值全部記錄下來,回滾時更新為舊值即可。

  • 當delete的時候,必須將所有的記錄都記錄下來,回滾時再重新插入該內容的記錄。

select作業不會產生undo log

回滾段與undo頁

在InnoDB儲存引擎中,undo log使用rollback segment回滾段進行存儲,每隔回滾段包含了1024個undo log segment。 MySQL5.5之後,總共有128個回滾段。即總共可以記錄128 * 1024個undo操作。

每個交易只會使用一個回滾段,一個回滾段在同一時刻可能會服務多個交易。

刪除undo log無法立即執行在提交交易後,因為有些事務可能想要讀取先前的資料版本(快照讀取)。所以事務提交時將undo log放入一個鍊錶中,稱為版本鏈,undo log的刪除與否由一個稱為purge的執行緒判斷。

Undo類型

undo log分為:

insert undo log

因為insert操作的記錄,只對事務本身可見,對其他事務不可見(這是事務隔離性的要求),故該undo log可以在交易提交後直接刪除。不需要進行purge操作。

update undo log

Undo logs record the changes made to delete and update operations.。為了支援MVCC機制,因此無法在交易提交時立即刪除undo log。在提交時,將其加入撤銷日誌鍊錶,等待清理執行緒進行最終的刪除。

undo log的生命週期

假設有2個數值,分別為A=1和B=2,然後某個交易將A修改為3,B修改為4,修改過程可簡化為:

1.begin
2.記錄A=1到undo log
3.update A=3
4.記錄A=3到redo log
5.記錄B=2到undo log
6.update B=4
7.記錄B=4到redo log
8.將redo log刷新到磁碟
9.commit

  • 在1-8步驟的任一系統宕機,交易未提交,該交易就不會對磁碟上的資料做任何影響。

  • 如果在8-9之間當機,復原之後可以選擇回滾,也可以選擇繼續完成交易提交,因為此時redo log已經持久化。

  • 若在9之後系統當機,記憶體對映中變更的資料還沒來得及刷回磁碟,那麼系統復原之後,可以依照redo log把資料刷回磁碟。

MySQL日誌之redo log和undo log的知識點有哪些

詳細產生過程

對於InnoDB引擎來說,每個行記錄除了記錄本身的資料之外,還有幾個隱藏的欄位:

  • DB_ROW_ID∶記錄的主鍵id。

  • DB_TRX_ID:交易ID,當對某筆記錄發生修改時,就會將這個交易的Id記錄其中。

  • DB_ROLL_PTR︰回滾指針,版本鏈中的指針。

MySQL日誌之redo log和undo log的知識點有哪些

當我們執行INSERT:

begin;
INSERT INTO user (name) VALUES ('tom');

每次插入資料都會建立一個插入操作的撤銷日誌,資料的回溯指標會指向此日誌。 undo log會記錄undo log的序號、插入主鍵的列和值...,那麼在進行rollback的時候,透過主鍵直接把對應的資料刪除即可。

MySQL日誌之redo log和undo log的知識點有哪些

當我們執行UPDATE時:

執行更新操作時,會產生更新撤銷日誌,其中包含更新主鍵和不更新主鍵兩種情況。假設現在進行更新操作:

UPDATE user SET name='Sun' WHERE id=1;

MySQL日誌之redo log和undo log的知識點有哪些

這時會把新的undo log記錄加入到版本鏈中,它的undo no是1,並且新的undo log的回滾指標會指向舊的undo log (undo no=0)。

假設現在執行:

UPDATE user SET id=2 WHERE id=1;

MySQL日誌之redo log和undo log的知識點有哪些

對於更新主鍵的操作,會先把原來的資料deletemark標識打開,這時並沒有真正的刪除數據,真正的刪除會交給清理線程去判斷,然後在後面插入一條新的數據,新的數據也會產生undo log,並且undo log的序號會遞增。

可以發現每次對資料的變更都會產生一個undo log,當一筆記錄被變更多次時,那麼就會產生多個undo log,undo log記錄的是變更前的日誌,並且每個undo log的序號是遞增的,那麼當要回滾的時候,按照序號依序向前推,就可以找到我們的原始資料了。

undo log是如何回滾的

以上面的範例來說,假設執行rollback,那麼對應的流程應該是這樣:

1. 透過undo no= 3的日誌把id=2的資料刪除

2. 透過undo no=2的日誌把id=1的資料的deletemark還原成0

3. 透過undo no=1的日誌把id=1的資料的name還原成Tom

4. 透過undo no=0的日誌把id=1的資料刪除

MySQL MVVC多版本並發控制

擴展

bin log

Binary log, also known as update log, is a type of log file in binary format that records changes made to a database.。它記錄了資料庫所有執行的更新語句。

binlog主要應用場景:

  • 資料復原:如果MySQL意外停止,可以透過此日誌進行復原、備份

  • # #資料複製:master把它的二進位日誌傳遞給slaves來達到master-slave資料的一致性

  • show variables like '%log_bin%';
查看bin log日誌:

mysqlbinlog -v "/var/lib/mysql/binlog/xxx.000002"

使用日誌恢復資料:

mysqlbinlog [option] filename|mysql –uuser -ppass;

刪除二進位日誌:

PURGE {MASTER | BINARY} LOGS TO ‘指定日志文件名'
PURGE {MASTER | BINARY} LOGS BEFORE ‘指定日期'

寫入時機

交易執行過程中,先把日誌寫到bin log cache ,交易提交的時候,再把binlog cache寫到binlog檔。因為一個事務的binlog不能被拆開,無論這個事務多大,也要確保一次性寫入,所以系統會給每個執行緒分配一個區塊記憶體作為binlog cache。

MySQL日誌之redo log和undo log的知識點有哪些

binlog與redo log比較

  • #InnoDB儲存引擎層產生的redo log是一種實體日誌,用於記錄“對於哪些資料頁進行了什麼樣的修改」。

  • 而binlog是邏輯日誌,記錄內容是語句的原始邏輯,類似給ID=2這一行的c欄位加1,屬於服務層。

兩個重點也不同, redo log讓InnoDB有了崩潰復原的能力,binlog保證了MySQL叢集架構的資料一致性。

兩階段提交

在執行更新語句過程,會記錄redo log與binlog兩塊日誌,以基本的事務為單位,redo log在事務執行過程中可以不斷寫入,而binlog只有在提交事務時才寫入,所以redo log與binlog的寫入時機不一樣。

MySQL日誌之redo log和undo log的知識點有哪些

redo log與binlog兩份日誌之間的邏輯不一致,會出現什麼問題?

以update語句為例,假設id=2的記錄,字段c值是0,把字段c值更新成1,SQL語句為update T set c=1 where id=2。

假設執行過程中寫完redo log日誌後,binlog日誌寫期間發生了異常,會出現什麼情況呢?

MySQL日誌之redo log和undo log的知識點有哪些

因為binlog異常中斷寫入,因此其中沒有對應的修改記錄。因此,之後用binlog日誌恢復資料或slave讀取master的binlog時,就會少這次更新,恢復出來的這一行c值是0,而原庫因為redo log日誌恢復,這一行c值是1,最終數據不一致。

MySQL日誌之redo log和undo log的知識點有哪些

InnoDB儲存引擎採用雙階段提交方案來處理兩份日誌之間的邏輯一致性問題。兩階段提交是指將redo log分為prepare和commit兩個步驟處理。

讓redo log和bin log最終的提交綁定到一起,前面說過的,事務commit時預設需要讓redo log先同步完才算commit成功,所以如果綁定到一起的話,bin log也具有該特性了,就保證了資料不會遺失。

MySQL日誌之redo log和undo log的知識點有哪些

使用兩階段提交後,寫入binlog時發生異常也會有影響,因為MySQL根據redo log日誌復原資料時發現redo log仍處於prepare階段,且沒有對應binlog日誌,就會提交失敗,回溯資料。

MySQL日誌之redo log和undo log的知識點有哪些

另一個場景,redo log的commit階段發生異常,那會不會回溯事務呢?

MySQL日誌之redo log和undo log的知識點有哪些

並不會回滾事務,它會執行上圖框住的邏輯,雖然redo log是處於prepare階段,但是能透過交易id找到對應的binlog日誌,所以MySQL認為是完整的,就會提交交易恢復資料。

以上是MySQL日誌之redo log和undo log的知識點有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
解釋InnoDB緩衝池及其對性能的重要性。解釋InnoDB緩衝池及其對性能的重要性。Apr 19, 2025 am 12:24 AM

InnoDBBufferPool通過緩存數據和索引頁來減少磁盤I/O,提升數據庫性能。其工作原理包括:1.數據讀取:從BufferPool中讀取數據;2.數據寫入:修改數據後寫入BufferPool並定期刷新到磁盤;3.緩存管理:使用LRU算法管理緩存頁;4.預讀機制:提前加載相鄰數據頁。通過調整BufferPool大小和使用多個實例,可以優化數據庫性能。

MySQL與其他編程語言:一種比較MySQL與其他編程語言:一種比較Apr 19, 2025 am 12:22 AM

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

學習MySQL:新用戶的分步指南學習MySQL:新用戶的分步指南Apr 19, 2025 am 12:19 AM

MySQL值得學習,因為它是強大的開源數據庫管理系統,適用於數據存儲、管理和分析。 1)MySQL是關係型數據庫,使用SQL操作數據,適合結構化數據管理。 2)SQL語言是與MySQL交互的關鍵,支持CRUD操作。 3)MySQL的工作原理包括客戶端/服務器架構、存儲引擎和查詢優化器。 4)基本用法包括創建數據庫和表,高級用法涉及使用JOIN連接表。 5)常見錯誤包括語法錯誤和權限問題,調試技巧包括檢查語法和使用EXPLAIN命令。 6)性能優化涉及使用索引、優化SQL語句和定期維護數據庫。

MySQL:初學者的基本技能MySQL:初學者的基本技能Apr 18, 2025 am 12:24 AM

MySQL適合初學者學習數據庫技能。 1.安裝MySQL服務器和客戶端工具。 2.理解基本SQL查詢,如SELECT。 3.掌握數據操作:創建表、插入、更新、刪除數據。 4.學習高級技巧:子查詢和窗口函數。 5.調試和優化:檢查語法、使用索引、避免SELECT*,並使用LIMIT。

MySQL:結構化數據和關係數據庫MySQL:結構化數據和關係數據庫Apr 18, 2025 am 12:22 AM

MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

MySQL:解釋的關鍵功能和功能MySQL:解釋的關鍵功能和功能Apr 18, 2025 am 12:17 AM

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。

SQL的目的:與MySQL數據庫進行交互SQL的目的:與MySQL數據庫進行交互Apr 18, 2025 am 12:12 AM

SQL用於與MySQL數據庫交互,實現數據的增、刪、改、查及數據庫設計。 1)SQL通過SELECT、INSERT、UPDATE、DELETE語句進行數據操作;2)使用CREATE、ALTER、DROP語句進行數據庫設計和管理;3)複雜查詢和數據分析通過SQL實現,提升業務決策效率。

初學者的MySQL:開始數據庫管理初學者的MySQL:開始數據庫管理Apr 18, 2025 am 12:10 AM

MySQL的基本操作包括創建數據庫、表格,及使用SQL進行數據的CRUD操作。 1.創建數據庫:CREATEDATABASEmy_first_db;2.創建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入數據:INSERTINTObooks(title,author,published_year)VA

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)