<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
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步:先將原始資料從磁碟中讀入記憶體中來,修改資料的記憶體拷貝,產生髒資料
第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 buffer同樣是在記憶體中,如果提交事務之後,redo log buffer還沒來得及將資料重新整理到redo log file進行持久化,此時發生宕機照樣會丟失資料。如何解決?刷盤策略。
InnoDB中給出了innodb_flush_log_at_trx_commit引數控制redo log buffer重新整理到redo log file時的三種策略:
值為0的情況:
因為有1s的間隔,所以最壞情況下會丟失1秒的資料。
值為1的情況:
commit時需要先主動重新整理redo log buffer到redo log file,如果中途宕機了,事務也就失敗了,不會有任何損失,真正能保證事務的永續性。但是效率最差。
值為2的情況:是根據os決定。
可以調整為0或2提高事務的效能,但是喪失了ACID特性
undo log用於保證事務的原子性和一致性。作用有兩個:①提供回滾操作 ②多版本控制MVVC
回滾操作
前面redo log中說過,後臺執行緒會不定時的去重新整理buffer pool中的資料到磁碟,但是如果該事務執行期間出現各種錯誤(宕機)或者執行rollback語句,那麼前面刷進去的操作都是需要回滾的,保證原子性,undo log就是提供事務回滾的。
MVVC
當讀取的某一行被其他事務鎖定時,它可以從undo log中分析出該行記錄以前的資料版本是怎樣的,從而讓使用者能夠讀取到當前事務操作之前的資料——快照讀。
快照讀:SQL讀取的資料是歷史版本,不用加鎖,普通的SELECT就是快照讀。
undo log的組成部分:
select操作不會產生undo log
在InnoDB儲存引擎中,undo log使用rollback segment回滾段進行儲存,每隔回滾段包含了1024個undo log segment。 MySQL5.5之後,一共有128個回滾段。即總共可以記錄128 * 1024個undo操作。
每個事務只會使用一個回滾段,一個回滾段在同一時刻可能會服務於多個事務。
事務提交後不能立即刪除該undo log,可能有些事務會想要讀取之前的資料版本(快照讀)。所以事務提交時將undo log放入一個連結串列中,稱為版本鏈,undo log的刪除與否由一個稱為purge的執行緒判斷。
undo log分為:
insert undo log
因為insert操作的記錄,只對事務本身可見,對其他事務不可見(這是事務隔離性的要求),故該undo log可以在事務提交後直接刪除。不需要進行purge操作。
update undo log
update undo log記錄的是對delete和update操作產生的undo log。該undo log可能需要提供MVCC機制,因此不能在事務提交時就進行刪除。提交時放入undo log連結串列,等待purge執行緒進行最後的刪除。
假設有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
對於InnoDB引擎來說,每個行記錄除了記錄本身的資料之外,還有幾個隱藏的列:
當我們執行INSERT時:
begin; INSERT INTO user (name) VALUES ('tom');
插入的資料都會生成一條insert undo log,並且資料的回滾指標會指向它。undo log會記錄undo log的序號、插入主鍵的列和值...,那麼在進行rollback的時候,通過主鍵直接把對應的資料刪除即可。
當我們執行UPDATE時:
對於更新的操作會產生update undo log,並且會分更新主鍵的和不更新主鍵的,假設現在執行:
UPDATE user SET name='Sun' WHERE id=1;
這時會把新的undo log記錄加入到版本鏈中,它的undo no是1,並且新的undo log的回滾指標會指向老的undo log (undo no=0)。
假設現在執行:
UPDATE user SET id=2 WHERE id=1;
對於更新主鍵的操作,會先把原來的資料deletemark標識開啟,這時並沒有真正的刪除資料,真正的刪除會交給清理執行緒去判斷,然後在後面插入一條新的資料,新的資料也會產生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的資料刪除
binlog即binary log,二進位制紀錄檔檔案,也叫作變更紀錄檔(update log)。它記錄了資料庫所有執行的更新語句。
binlog主要應用場景:
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。
兩個側重點也不同, redo log讓InnoDB有了崩潰恢復的能力,binlog保證了MySQL叢集架構的資料一致性。
在執行更新語句過程,會記錄redo log與binlog兩塊紀錄檔,以基本的事務為單位,redo log在事務執行過程中可以不斷寫入,而binlog只有在提交事務時才寫入,所以redo log與binlog的寫入時機不一樣。
redo log與binlog兩份紀錄檔之間的邏輯不一致,會出現什麼問題?
以update語句為例,假設id=2的記錄,欄位c值是0,把欄位c值更新成1,SQL語句為update T set c=1 where id=2。
假設執行過程中寫完redo log紀錄檔後,binlog紀錄檔寫期間發生了異常,會出現什麼情況呢?
由於binlog沒寫完就異常,這時候binlog裡面沒有對應的修改記錄。因此,之後用binlog紀錄檔恢復資料或者slave讀取master的binlog時,就會少這一次更新,恢復出來的這一行c值是0,而原庫因為redo log紀錄檔恢復,這一行c值是1,最終資料不一致。
為了解決兩份紀錄檔之間的邏輯一致問題,InnoDB儲存引擎使用兩階段提交方案。將redo log拆成了兩個步驟prepare和commit,這就是兩階段提交。
讓redo log和bin log最終的提交繫結到一起,前面說過的,事務commit時預設需要讓redo log先同步完才算commit成功,所以如果繫結到一起的話,bin log也具有該特性了,就保證了資料不會丟失。
使用兩階段提交後,寫入binlog時發生異常也不會有影響,因為MySQL根據redo log紀錄檔恢復資料時發現redo log還處於prepare階段,並且沒有對應binlog紀錄檔,就會提交失敗,回滾資料。
另一個場景,redo log的commit階段發生異常,那會不會回滾事務呢?
並不會回滾事務,它會執行上圖框住的邏輯,雖然redo log是處於prepare階段,但是能通過事務id找到對應的binlog紀錄檔,所以MySQL認為是完整的,就會提交事務恢復資料。
到此這篇關於MySQL紀錄檔專項之redo log和undo log介紹的文章就介紹到這了,更多相關MySQL redo log與undo log內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45