MySQL中的 redolog

什么是redo log

? ? ? ? 如果我們只在內存的 Bufer Pool中修改了頁面,假設在事務提交后突然發生了某個故障導致內存中的數據都失效了,那么這個已經提交的事務在數據庫中所做的更改也就跟著丟失了,這是我們所不能忍受的。那么,如何保證這個持久性呢?一個很簡單的做法就是在事務提交完成之前,把該事務修改的所有頁面都刷新到磁盤。不過這個簡單粗暴的做法存在下面這些問題。

? ? ? ? 刷新一個完整的數據頁太浪費了。有時我們僅僅修改了某個頁面中的一個字節,但是由于InnoDB 是以頁為單位來進行磁盤I/O的,也就是說在該事務提交時不得不將一個完整的頁面從內存中刷新到磁盤。我們又知道,一個頁面的默認大小是16KB,因為修改了一個字節就要刷新 16KB的數據到磁盤上,顯然太浪費了。隨機 I/O 刷新起來比較慢。

? ? ? ? 一個事務可能包含很多語句,即使是一條語句也可能修改許多頁面,“倒霉催”的是該事務修改的這些頁面可能并不相鄰。這就意味著在將某個事務修改的 Bufer Pool中的頁面刷新到磁盤時,需要進行很多的隨機 I/O。隨機 I/O 比順序 I/O 要慢,尤其是對于傳統的機械硬盤。

? ? ? ? ?所以,其實沒有必在每次提交事務時就把該事務在內存中修改過的頁面全部刷新到磁盤,只需要記錄有哪些就該就可以。

????????這樣在事務提交時,就會把上述內容刷新到磁盤中。即使之后系統崩潰了,重啟之后只要照上述內容所記錄的步驟重新更新一下數據頁,那么該事務對數庫中所體的修改可以恢復出來,這樣也就意味著滿足持久性的要求。

? ? ? ? 我們把這類日志叫做redo log日志。

????????redo 日志占用的空間非常小,在存儲表空間ID、頁號、偏移量以及需要更新的值時需要的存儲空間很小。
redo 日志是順序寫入磁盤的,在執行事務的過程中,每執行一條語句,就可能產生若干條 redo 日志,這些日志是按照產生的順序寫入磁盤的,也就是使用順序 I/O。

redolog日志格式

redo 日志中各個部分的詳細解釋如下:

type :這條 redo 日志的類型。
page number:頁號。
space ID:表空間 ID。
data :這條 redo 日志的具體內容。

簡單的redolog日志

????????如果沒有為某個表顯式地定義主鍵,并且表中也沒有定義不允許存儲 NULL值的 UNIQUE鍵,那么InnoDB 會自動為表添加一個名為row_id的隱藏列作為主鍵。為這個row id 隱藏列進行賦值的方式如下。服務器會在內存中維護一個全局變量,每當向某個包含row_id隱藏列的表中插入一條記錄時,就會把這個全局變量的值當作新記錄的row_id列的值,并且把這個全局變量自增1。
每當這個全局變量的值為256的倍數時,就會將該變量的值刷新到系統表空間頁號為7的頁面中一個名為MaxRowID的屬性中(前文介紹表空間結構時詳細說過該屬性。之所以不是每次自增該全局變量時就將該值刷新到磁盤,是為了避免頻刷盤)
當系統啟動時,會將這個MaxRowD屬性加載到內存中,并將該值加上 256之后賦
值給前面提到的全局變量(因為在系統上次關機時,該全局變量的值可能大于磁盤頁面中 Max Row ID 屬性的值)。
這個 Max RowID 屬性占用的存儲空間是8字節。當某個事務向某個包含 row_id隱藏列的表插入一條記錄,并且為該記錄分配的row_id值為256的倍數時,就會向系統表空間頁號頭7的頁面的相應偏移量處寫入8字節的值。但是我們要知道,這個寫入操作實際上是在Bufe Pool中完成的,我們需要把這次對這個頁面的修改以redolog日志的形式記錄下來。這樣在事務提交之后,即使系統崩潰了,也可以將該頁面恢復成崩潰前的狀態。在這種對頁畫的修改是極其簡單的情況下,redo 日志中只需要記錄一下在某個頁面的某個偏移量處修改了幾個字節的值、具體修改后的內容是啥就好了。這種極其簡單的redo 日志稱為物理日志,并且根據在頁面中寫入數據的多少劃分了幾種不同的redo 日志類型。

復雜一些的 redo 日志類型

????????有時,在執行一條語句時會修改非常多的頁面,包括系統數據頁面和用戶數據頁面(用戶數據指的就是聚簇索引和二級索引對應的 B+樹)。以一條INSERT 語句為例,它除了向 B+樹的頁面中插入數據外,也可能更新系統數據MaxRowID的值。不過對于用戶來說,平時更關心的是語句對B+樹所做的更新。

????????表中包含多少個索引,一條INSERT 語句就可能更新多少棵 B+樹。針對某一棵B+樹來說,既可能更新葉子節點頁面,也可能更新內節點頁面,還可能創建新的頁面(在該記錄插入的葉子節點的剩余空間比較少,不足以存放該記錄時,會進行頁面分裂,在內節點頁面中添加目錄項記錄)。

????????在語句執行過程中,INSERT語句對所有頁面的修改都得保存到redo log日志中去。這句話說的比較輕巧,做起來可就比較麻煩了。比如,在將記錄插入到聚簇索引中時,如果定位到的葉子節點的剩余空間足夠存儲該記錄,那么只更新該葉子節點頁面,并只記錄一條 MLOGWRITE STRING類型的redo日志,表明在頁面的某個偏移量處增加了哪些數據不就好了么?那就天真了。別忘了,一個數據頁中除了存儲實際的記錄之外,還有FileHeader、PageHeader、Page Directory等部分(在第5章有詳細講解)。所以每往葉子節點代表的數據頁中插入一條記錄,還有其他很多地方會跟著更新,比如:

可能更新 Page Directory 中的槽信息;
可能更新 Page Header 中的各種頁面統計信息,比如 PAGE_N_DIR_SLOTS 表示的槽數量可能會更改,PAGEHEAPTOP代表的還未使用的空間最小地址可能會更改,PAGENHEAP代表的本頁面中的記錄數量可能會更改……

????????說了這么多,就是想表達:在把一條記錄插入到一個頁面時,需要更改的地方非常多。這時如果使用前面介紹的簡單的物理redo 日志來記錄這些修改,可以有兩種解決萬案。

????????方案1:在每個修改的地方都記錄一條redo日志。按照這種方式來記錄redo 日志的缺點是顯而易見的,因為被修改的地方實在太多了,可能redo 日志占用的空間都要比整個頁面占用的空間多。
方案 2:將整個頁面第一個被修改的字節到最后一個被修改的字節之間所有的數據當成一條物理 redo 日志中的具體數據。
正是因為在使用上面這兩個方案來記錄某個頁面中做了哪些修改時,比較浪費空間,設計ImnoDB 的大叔本著勤儉節約的初心,提出了一些新的redo 日志類型。
MLOG REC INSERT(type 字段對應的十進制數字為9):表示在插入一條使用非緊湊行格式(REDUNDANT)的記錄時,redo日志的類型,MLOG COMP RECINSERT(type 字段對應的十進制數字為38):表示在插入一條使用緊湊行格式(COMPACT、DYNAMIC、COMPRESSED)的記錄時,redo 日志的類型。MLOG COMP PAGE CREATE(type 字段對應的十進制數字為 58):表示在創建一個存儲緊湊行格式記錄的頁面時,redo日志的類型。
MLOG_COMP REC DELETE(type 字段對應的十進制數字為 42):表示在刪除一條使用緊湊行格式記錄時,redo日志的類型。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916562.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916562.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916562.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構之 【排序】(非遞歸實現快速排序)

目錄 1.引入 2.非遞歸實現快排的思想 3.非遞歸實現快排圖解 4.完整代碼 1.引入 遞歸不可避免的話題就是防止棧溢出 所以程序員需要具備遞歸改非遞歸的能力 ,一般來說,抓住遞歸中變化的量是關鍵 void QuickSort(int* a, int left, int right){if (left…

CLAP文本-音頻基礎模型: LEARNING AUDIO CONCEPTS FROM NATURAL LANGUAGE SUPERVISION

一、TL;DR 現在的做法有什么問題?主流范式是 “一個類別標簽對應多個錄音”,需要提前標注預測預先定義的類別,只能做閉集理解,失去靈活性 我們怎么做?通過兩個編碼器和對比學習機制建立語言與音頻的關聯&a…

Flink2.0學習筆記:Stream API 常用轉換算子

EC0720/FLINKTASK-TEST-STREAM/demo at master stevensu1/EC0720 先看測試效果:控制臺 測試效果:監控服務端 主要的轉換算子包括: 轉換算子 filter:過濾包含“Flink”的輸入 轉換算子 map: 將每行數據前添加“Processed: ”并轉為大寫 轉…

一、Python環境、Jupyter與Pycharm

安裝Python由于RAG項目中所需要的Python版本必須高于3.8,經過篩選,最終選擇了3.10.11這個版本py --version Python 3.10.11安裝過程略過,但對于幾個基礎的命令作個筆記記錄where python找到python啟動器的位置D:\>where python C:\Users\x…

Flink CEP 動態模板與規則動態修改實踐完全手冊

1. Flink CEP:從靜態規則到動態江湖 Flink 的復雜事件處理(CEP)庫就像一個武功高強的俠客,能從數據流中精準捕獲特定模式,堪稱流處理界的“降龍十八掌”。但問題來了:傳統 CEP 規則通常是寫死在代碼里的,就像刻在石碑上的武功秘籍,改起來費勁不說,還得重啟應用,簡直…

vue3.2 + echarts5.6 + ant-design-vue 3.x 實現自定義 echarts 圖例

文章目錄概要技術細節效果概要 需求需要實現圖例移入顯示描述說明 故實現自定義圖例 技術細節 <template><div class"custom-legend"><divv-for"item in legends":key"item.name"class"legend-item":class"{ i…

【2025年7月25日】TrollStore巨魔商店恢復在線安裝

就在今日7月25日&#xff0c;TrollStore的在線安裝功能再次變得可用&#xff0c;這對于許多iPhone用戶來說無疑是個喜訊。在經歷了近三個月的中斷后&#xff0c;巨魔商店的企業證書意外的到來了&#xff0c;使得用戶能夠重新采用在線安裝的方式&#xff01; 在線安裝地址在文…

【05】C#入門到精通——C# 面向對象、類、靜態變量static、類與類之間的調用

文章目錄1 引入例子2 創建類2.1 類的訪問屬性2.2 英雄 特點類2.3 英雄信息打印3 靜態變量static4 類 調用 類4.1 非靜態 成員函數4.2 靜態 成員函數1 引入例子 比如游戲中 描述英雄的角色&#xff0c; 我們可以像下面這樣&#xff0c;給每一個英雄特點及擁有技能分別定義變量…

單片機的硬件結構

單片機的硬件結構 一、課程導入 在上一節課《認識單片機》中&#xff0c;我們知道單片機就像一個超級迷你的工廠&#xff0c;有著類似工廠的各個組成部分。而這個 “迷你工廠” 能正常運轉&#xff0c;離不開其內部嚴謹的硬件結構。就像一座大廈&#xff0c;只有基礎結構穩固且…

multiprocessing模塊使用方法(二)

spawn_main是Python multiprocessing模塊的核心內部函數&#xff0c;用于實現spawn啟動方法的子進程初始化。以下結合代碼Demo詳細說明其使用方法和推薦場景。一、spawn_main的功能與定位核心作用&#xff1a; 在spawn模式下啟動子進程&#xff0c;負責進程間通信管道的建立和資…

編程與數學 03-002 計算機網絡 07_路由算法

編程與數學 03-002 計算機網絡 07_路由算法一、靜態路由算法&#xff08;一&#xff09;手工配置路由表的方法&#xff08;二&#xff09;靜態路由的優缺點二、動態路由算法原理&#xff08;一&#xff09;距離矢量算法&#xff08;如貝爾曼 - 福特算法&#xff09;&#xff08…

使用Python,OpenCV計算跑圖的圖像彩色度

使用Python&#xff0c;OpenCV計算跑圖的圖像彩色度 這篇博客將介紹如何計算跑圖里最鮮艷的top25圖片和最灰暗的top25圖片并顯示色彩彩色度值展示。 效果圖 以下分別是最鮮艷top25和最灰暗top25對比效果圖&#xff1a; 最鮮艷top25效果圖&#xff1a; 最灰暗top25效果圖…

LeetCode 60:排列序列

LeetCode 60&#xff1a;排列序列問題定義與核心挑戰 給定整數 n 和 k&#xff0c;返回集合 {1,2,...,n} 的第 k 個字典序排列。直接生成所有排列再遍歷到第 k 個的方法&#xff08;時間復雜度 O(n!)&#xff09;會因 n≥10 時階乘爆炸而超時&#xff0c;因此需要 數學推導 貪…

亞遠景-傳統功能安全VS AI安全:ISO 8800填補的標準空白與實施難點

一、為什么需要ISO 8800&#xff1a;傳統安全標準的“盲區”傳統功能安全&#xff08;ISO 26262&#xff09;? 假設&#xff1a;系統行為可被完整規格化&#xff0c;失效模式可枚舉&#xff0c;風險可用概率-危害矩陣量化。? 盲區&#xff1a;對“設計意圖正確&#xff0c;但…

菜鳥教程 R語言基礎運算 注釋 和數據類型

菜鳥教程 R語言基礎運算 注釋 和數據類型 1.注釋 注釋主要用于一段代碼的解析&#xff0c;可以讓閱讀者更易理解&#xff0c;編程語言的注釋會被編譯器忽略掉&#xff0c;且不會影響代碼的執行。 一般編程語言的注釋分為單行注釋與多行注釋&#xff0c;但是 R 語言只支持單行注…

華為云ELB(彈性負載均衡)持續報異常

華為云ELB&#xff08;彈性負載均衡&#xff09;持續報異常&#xff0c;需結合實例類型&#xff08;共享型/獨享型&#xff09;和異常代碼進行針對性排查。以下是分步排查建議&#xff1a;一、根據實例類型排查網絡配置共享型實例 安全組規則&#xff1a;檢查后端服務器安全組是…

《R for Data Science (2e)》免費中文翻譯 (第2章) --- Workflow: basics

寫在前面 本系列推文為《R for Data Science (2)》的中文翻譯版本。所有內容都通過開源免費的方式上傳至Github&#xff0c;歡迎大家參與貢獻&#xff0c;詳細信息見&#xff1a; Books-zh-cn 項目介紹&#xff1a; Books-zh-cn&#xff1a;開源免費的中文書籍社區 r4ds-zh-cn …

開源深度學習新寵:Burn框架助您無憂高效建模

在日新月異的人工智能世界里&#xff0c;各類深度學習框架如雨后春筍般涌現&#xff0c;而Burn&#xff0c;作為新一代的深度學習框架&#xff0c;以其不妥協的靈活性、高效性和可移植性嶄露頭角。本文將深入探討Burn的核心功能、應用場景及具體使用方法&#xff0c;幫助您更好…

基于深度學習的圖像分割:使用DeepLabv3實現高效分割

前言 圖像分割是計算機視覺領域中的一個重要任務&#xff0c;其目標是將圖像中的每個像素分配到不同的類別中。近年來&#xff0c;深度學習技術&#xff0c;尤其是卷積神經網絡&#xff08;CNN&#xff09;&#xff0c;在圖像分割任務中取得了顯著的進展。DeepLabv3是一種高效的…

如何高效合并音視頻文件(時間短消耗資源少)(二)

英語字幕 1 00:00:06,480 --> 00:00:08,400 Good morning. We have a banger for you2 00:00:08,400 --> 00:00:09,840 today. We&amp;#39;re going to launch chatbt3 00:00:09,840 --> 00:00:11,519 agent. But before jumping into that, I&amp;#39;d4 00…