网站黄色在线观看视频,男人和女人操逼有免费的视频吗2018高清,91熟女丨老女人丨高潮丰满,丝袜高潮流白浆潮喷在线播放

中國站

中國站

國際版

聯(lián)系我們

400-002-9968

售前咨詢

售后服務(wù)

注冊 登錄

博客 > 一篇文搞懂Undo Log(重做日志)和 Redo Log(回滾日志)

一篇文搞懂Undo Log(重做日志)和 Redo Log(回滾日志)

  • 標(biāo)簽:
  • 數(shù)據(jù)庫
  • Undo Log
  • Redo Log
  • 數(shù)據(jù)庫日志

瀏覽量:3053次評論:0次

作者:銳成網(wǎng)絡(luò)整理時間:2024-08-13 17:52:23

在數(shù)據(jù)庫中Undo Log(重做日志)和 Redo Log(回滾日志)是兩個非常重要的概念,為了方便大家更好的了解他們,我們將詳細介紹Undo Log和 Redo Log概念和區(qū)別。不過在搞懂Undo Log和 Redo Log之前,我們先了解幾個概念。

一篇文搞懂Undo Log(重做日志)和 Redo Log(回滾日志)

事務(wù)和ACID

我們學(xué)數(shù)據(jù)庫的時候經(jīng)??吹绞聞?wù)和ACID的說法。

什么是事務(wù)呢?

在數(shù)據(jù)庫系統(tǒng)中,一個事務(wù)是指:由一系列數(shù)據(jù)庫操作組成的一個完整的邏輯過程。

例如銀行轉(zhuǎn)帳:

1.從原賬戶扣除金額; 

2.向目標(biāo)賬戶添加金額。

這兩個數(shù)據(jù)庫操作的總和,構(gòu)成一個完整的邏輯過程,不可拆分。這個過程被稱為一個事務(wù),具有ACID特性。

那什么又是ACID呢?

維基百科上ACID的定義如下:

ACID,是指數(shù)據(jù)庫管理系統(tǒng)(DBMS)在寫入或更新資料的過程中,為保證事務(wù)(transaction)是正確可靠的,所必須具備的四個特性:原子性(atomicity,或稱不可分割性)、一致性(consistency)、隔離性(isolation,又稱獨立性)、持久性(durability)。

  • 原子性(Atomic):在同一項業(yè)務(wù)處理過程中,事務(wù)保證了多個對數(shù)據(jù)的修改,要么同時成功,要么一起被撤銷。比如轉(zhuǎn)賬,要么轉(zhuǎn)賬成功,要么轉(zhuǎn)賬失敗,不存在轉(zhuǎn)了一半的情況。
  • 隔離性(Isolation):在不同的業(yè)務(wù)處理過程中,事務(wù)保證了各自業(yè)務(wù)正在讀、寫的數(shù)據(jù)互相獨立,不會彼此影響。數(shù)據(jù)庫一般有四種隔離級別:讀未提交(Read Uncommitted)、讀已提交(Read Committed)、可重復(fù)讀(Repeatable Read)、可串行化(Serializable)。
  • 持久性(Durability):事務(wù)應(yīng)當(dāng)保證所有被成功提交的數(shù)據(jù)修改都能夠正確地被持久化,也就是保存到磁盤上了,不會丟失數(shù)據(jù)。
  • 一致性(Consistency):保證系統(tǒng)中的數(shù)據(jù)是正確的,不同數(shù)據(jù)間不會產(chǎn)生矛盾,結(jié)果是一致的。

其實原子性、隔離性、持久性的最終目的就是為了數(shù)據(jù)的一致性。

如何實現(xiàn)原子性和持久性

原子性保證了一個事務(wù)中的多個操作要么都成功,要么都失敗,不存在成功一半的情況。持久性保證了事務(wù)一旦生效,就不會因為任何原因?qū)е聰?shù)據(jù)被修改或者丟失。

那么如果才能實現(xiàn)原子性和持久性呢?

我們很容易就能想到,數(shù)據(jù)庫把數(shù)據(jù)寫入磁盤不就行了嗎?

是的,這是正確的方法,但問題是“寫入磁盤”這個操作不是原子的,寫操作可以有開始寫入、寫入中、寫入成功,甚至還有寫入失敗等狀態(tài)。

而且一個事務(wù)中經(jīng)常包含多個操作,比如我們?nèi)ゾW(wǎng)上下單買東西,一般涉及到這幾個操作:從我們的賬戶中扣款、在商家的賬戶增加貨款、把商品的庫存減掉等等。這些操作是在一個事務(wù)中的,也就是說要么全部成功,要么全部失敗。

崩潰恢復(fù)

如果我們的賬戶中扣了100塊錢,這個操作成功寫入了磁盤,而在給商家增加100塊錢的時候系統(tǒng)崩潰了(這么倒霉?),或者停電了(不會吧?),導(dǎo)致寫入失?。ń?jīng)常會出現(xiàn)吧?)。

為了避免這種情況發(fā)生,數(shù)據(jù)庫就得想辦法知道系統(tǒng)崩潰前完整的操作是怎么樣的,這樣等服務(wù)器恢復(fù)后,數(shù)據(jù)庫要把還沒來得及寫入磁盤的那一部分?jǐn)?shù)據(jù)重新寫入,給商家的賬號上加100塊錢,完成未竟的事業(yè)。

那么問題來了,系統(tǒng)恢復(fù)后數(shù)據(jù)庫如何知道之前事務(wù)的所有信息呢?

好記性不如爛筆頭,我們先寫下來不就行了嗎?

Redo Log(回滾日志)

這就要求數(shù)據(jù)庫在寫磁盤之前要把事務(wù)所有的操作都先記錄下來,比如修改什么數(shù)據(jù)、數(shù)據(jù)物理上位于哪個內(nèi)存頁和磁盤塊中、從什么值改成什么值等等,以日志的形式先寫到磁盤中。

只有在日志記錄全部都安全落盤,然后在最后寫上“Commit Record”后,表示所有的操作記錄我都寫完啦。

這時候數(shù)據(jù)庫才會根據(jù)日志上的信息,對真正的數(shù)據(jù)進行修改,修改完成后,在日志中加入一條“End Record”,表示我已經(jīng)按照日志里的步驟都做完啦,事務(wù)持久化的工作也就做完了。

這種事務(wù)實現(xiàn)方法被稱為“Commit Logging”。

這種方式實現(xiàn)數(shù)據(jù)持久性、原子性的原理如下:

首先, 一旦日志成功寫入了Commit Record,那就表示事務(wù)相關(guān)的所有信息都已經(jīng)寫到日志中了,如果修改數(shù)據(jù)的過程中系統(tǒng)崩潰了,重啟后只要再根據(jù)日志的內(nèi)容重新操作一遍就行了,這就保證了持久性。

其次,如果日志還沒寫完系統(tǒng)就崩潰了,系統(tǒng)重啟后,數(shù)據(jù)庫一看日志里沒有Commit Record,這話就說明日志是不全的,還沒有寫完,那么就將這部分日志標(biāo)記為回滾狀態(tài),整個事務(wù)就回滾了,這就保證了原子性。

換句話說就是,我先把我要改的東西記錄在日志里,我再根據(jù)日志統(tǒng)一寫到磁盤中,萬一我在寫入磁盤的過程中暈倒了,等我醒來的時候,我先查看日志的完整性。

如果日志是完整的,里面有Commit Record,我就照著日志重新做一遍,最后也能成功。如果日志是不完整的,里面沒有Commit Record,我就回滾整個事務(wù),什么都不做。

這個日志就叫做 Redo Log,也就是“重做日志”,中途崩潰的數(shù)據(jù)庫,根據(jù)這個日志把事務(wù)重做一遍。

Undo Log(重做日志)

不過Redo Log有個問題,就是效率太慢。

因為數(shù)據(jù)庫對數(shù)據(jù)的所有真實修改,都必須發(fā)生在事務(wù)提交之后,并且在日志寫入了 Commit Record 之后才能進行,沒有寫完Redo Log,數(shù)據(jù)庫是不敢先寫的。

即使事務(wù)提交前磁盤 I/O 有足夠空閑、即使某個事務(wù)修改的數(shù)據(jù)量非常龐大,占用大量的內(nèi)存緩沖,無論何種理由,都決不允許在事務(wù)提交之前就開始修改磁盤上的數(shù)據(jù),萬一系統(tǒng)崩潰了,數(shù)據(jù)出差誰負(fù)責(zé)呀?

但是當(dāng)一個事務(wù)中數(shù)據(jù)量特別大的時候,等全部變更寫入Redo Log然后再統(tǒng)一寫入磁盤,這樣性能就不是很好,就會很慢,老板就會不開心。

那能不能在事務(wù)提交之前,偷偷地先寫一點數(shù)據(jù)到磁盤呢(偷跑)?

答案是可以的,這就是STEAL策略,但是問題來了,你偷摸地寫了數(shù)據(jù),萬一事務(wù)要回滾,或者系統(tǒng)崩潰了,這些提前寫入的數(shù)據(jù)就變成了臟數(shù)據(jù),必須想辦法把它恢復(fù)才行。

這就需要引入Undo Log(回滾日志),在偷摸寫入數(shù)據(jù)之前,必須先在Undo Log中記錄都寫入了什么數(shù)據(jù),改了什么地方,到時候事務(wù)回滾了,就按照Undo Log日志,一條條恢復(fù)到原來的樣子,就像沒有改過一樣。

Undo Log還有一個作用,就是實現(xiàn)多個行版本控制(MVCC),當(dāng)讀取的某一行被其他事務(wù)鎖定時,它可以從 Undo Log 中獲取該行記錄以前的數(shù)據(jù)是什么,從而提供該行版本信息,讓用戶讀取。

總結(jié)

Undo Log(重做日志) 和 Redo Log(回滾日志)之間的區(qū)別,沒那么高深,我們只要按字面意思理解就行了。

Redo Log(重做日志)是為了系統(tǒng)崩潰之后恢復(fù)數(shù)據(jù)用的,讓數(shù)據(jù)庫照著日志,把沒做好的事情重做一遍。 有了Redo Log,就可以保證即使數(shù)據(jù)庫發(fā)崩潰重啟后,之前提交的記錄都不會丟失,這個能力稱為 crash-safe。

Undo Log(回滾日志)是為了回滾用的。 在事務(wù)提交之前就開始寫數(shù)據(jù),萬一事務(wù)到最后又打算不提交了,要回滾,或者系統(tǒng)崩潰了,這些提前寫入的數(shù)據(jù)就變成了臟數(shù)據(jù),這時候就必須用Undo Log恢復(fù)了。

這種在寫磁盤之前先寫日志的方式就叫做:Write-Ahead Logging(WAL),WAL讓性能更高了,不過同時也更復(fù)雜了,雖然復(fù)雜點,但是效果很好,mysql、sqlite、postgresql、sql server等數(shù)據(jù)庫都實現(xiàn)了WAL機制。

重要聲明:本文來自編程我也會,經(jīng)授權(quán)轉(zhuǎn)載,有部分增減,版權(quán)歸原作者所有,不代表銳成觀點,轉(zhuǎn)載的目的在于傳遞更多知識和信息。

我的評論

還未登錄?點擊登錄

微信掃碼溝通
微信掃碼溝通

微信掃碼溝通

AI
return head