天天看點

假事務之名,深入研究UNDO與REDO

 “有道無術,術尚可求;有術無道,止于術”。今天讓我們一起來看看dba+社群聯合發起人郭耀龍大師如何布道。     

專家簡介

假事務之名,深入研究UNDO與REDO

郭耀龍

dba+社群聯合發起人

超過5年oracle資料庫經驗,服務于大型制造業、銀行、政府、電信、電力等行業,曾主導某大型制造業的16核心系統從10g向11g平穩演進,擅長oracle資料庫架構規劃、性能調整、故障診斷、sql優化,熟悉oracle rac及maa架構,對大型it系統的oracle資料庫運維有較豐富的經驗。

假事務之名,深入研究UNDO與REDO

本文主要講述關于undo、redo的一些内容。由于undo、redo内容非常多,短時間内難以講訴清楚,故若水三千,我們隻取一瓢,我将從oracle事務切入,分析undo、redo在事務中的作用。

假事務之名,深入研究UNDO與REDO

分享一句出自《道德經》裡的話,我做了一個曲解,即:“道”了解為原理;“術”了解為實踐、操作,就是說如果我們懂得了事物的原理,那麼實踐性的東西我們是可以培養和訓練的,但是如果我們隻懂得表面的操作,而不懂原理,那我們就隻能停留在事物的表層,如果遇到新的情況,就難以應對。我認為做dba也是一樣,要能夠了解oracle的原理,才能處理一些深層次的問題,而不是在google無結果後就繳械投降。本篇文章的主要内容就是布道。

目錄 

1、undo在事務中的作用

解析undo段頭結構

解析undo塊、undo chain結構

2、redo在事務中的作用

解析redo結構、undo受redo保護的實質、cv對資料塊的作用

了解快速送出機制、delete實質

最近連續遇到3個由于ora-600錯誤導緻資料庫無法啟動的情況,其中兩個都是由于異常關機後導緻無法啟動,這種錯誤大部分情況是與redo、undo相關,但是怎樣來定位問題,怎樣解決?這就需要了解oracle redo、undo的原理,定位問題的方向一般都是解讀alert日志、trace日志、或者在mount階段使用一些跟蹤事件,比如10013、10015、10046等進行輔助分析。

當然還有最主要的一招,查mos,mos上有專門針對600錯誤的搜尋入口,在這裡根據錯誤代碼的第一個參數進行比對查找:

假事務之名,深入研究UNDO與REDO

但如果這裡比對不上,或者mos上給出的解決辦法無效,就還是得回到使用trace日志等分析定位問題,但是這裡的trace的解讀可能會是攔路虎,怎樣去解讀trace不是今晚的主題,不做深入,當然不同的trace解讀的方法也不盡相同,但是我自己有個體驗,就是對oracle的一些原理和資料結構了解越透徹,就越能讀懂trace檔案,我們隻需要讀懂其中的一些關鍵點,其餘可以進行猜測,就足以解決問題,就像英語的閱讀了解,隻需要讀懂1/3的内容,就能解答2/3的問題。這裡扯的有點遠了,我們回到今晚主題,希望通過今晚的分享能夠讓大家對undo、redo在oracle事務中的作用有一定了解,并通過對undo、redo的部分結構的解析,讓大家深入oracle内部,在後續處理相關問題時能夠有所幫助。

首先,先說下我對事務的了解。oracle資料庫根本上是一個程式,跟其他的應用系統程式無差别,應用系統的程式如果沒有業務,那程式代碼就無意義,oracle如果沒有事務運作,那oracle代碼也就無意義,是以,事務對于oracle就像業務對于應用系統一樣,是oracle的靈魂,從這個意義上看,oracle執行個體可以看做是用一段代碼在維護很多事務運作,事務是oracle執行個體運作的核心任務,事務産生的資料就是db(控制檔案、system檔案等可看作内部事務産生)。個人了解,僅供參考。

下面描述一下oracle事務的一個簡單過程:

1、在事務開始前,會申請redo資源、undo資源; redo的申請主要是要擷取記錄redo的記憶體資源,會涉及到redo allocation latch等資源的申請, undo資源申請是要擷取到一個undo段用來存儲undo資料(imu機制會稍有不同);

2、在undo段頭的事務表中申請一個槽位,記錄事務資訊,這些相關資訊也會以xid等形式寫入到資料塊的事務槽中;

3、undo段頭的事務表指向可用的undo塊,undo塊用于存儲具體的undo資訊;

4、事務開始,進行增、删、改、查等操作,redo記錄相關資訊、undo也記錄相關資訊,在事務涉及到的行頭還會設定行鎖标記;

5、事務送出或復原,結束事務。修改undo段頭事務表資訊,盡可能的修改相關資料塊的事務槽資訊、行鎖資訊,将相關事務資訊寫入redo log檔案。

上面隻是粗略的一個描述,其中涉及到很多概念,比如undo段頭、unod塊、事務槽、行鎖标記、redo記錄等,這些東西具體長什麼樣?是怎樣工作的呢?這裡讓我想起了一句話:愛情就像鬼一樣,誰都聽過,但誰也沒見過。下面我們就通過實驗來解析上面提到的這些概念,看一看是否真的有愛情。

 1  undo在事務中的作用 

1.1 解析undo段頭結構

假事務之名,深入研究UNDO與REDO

上面的實驗修改了表中的兩條記錄,且這兩條記錄是存放在不同的塊中先dump被修改的兩個資料塊進行觀察

假事務之名,深入研究UNDO與REDO

另外一個資料塊

假事務之名,深入研究UNDO與REDO

前面提到的事務槽和行鎖标記都出現了,我們看到愛情了!!!

事務槽中涉及到幾個重要的結構,下面進行下解釋:

xid=undo.segment.number+transaction.table.slot.number+wrap

uba = address of the last undo block used + sequence + last entry in undo record map

這兩個重要結構簡單的了解就是,xid指向了事務使用的undo段号、事務表中的槽位号、以及槽位被覆寫的次數;uba指向事務使用的最後一個undo塊、seq值、以及最後一條undo記錄。

事務槽中還有一個flag段,這個段有不同的取值,代表事務的不同狀态,可以通過修改這個标志實作手工送出事務,常見的取值有以下幾種:

----    事務是活動的,或者在塊清除前送出事務

c---    事務已經送出并且清除了行鎖定

--u-    快速送出

再回到前面的兩個塊的dump資料可以發現,兩個資料塊的事務槽中都有一個未送出的事務,都是使用了第二個事務槽,兩個塊的xid完全相同,即兩個塊使用的是同一個undo段中的同一個事務表槽位,uba的前兩部分也完全相同,即使用的是同一個undo塊,第三部分不一樣,說明兩個塊的前鏡像使用了兩個條undo record進行記錄。

從xid資訊可以知道,事務使用的是第6号復原段,下面dump 6号undo段頭進行觀察:

假事務之名,深入研究UNDO與REDO
假事務之名,深入研究UNDO與REDO

上圖就是undo段頭中的事務表,又看到愛情了!!!

下面對其中的幾個重要列進行解釋:

index:表示slot 編号

state:表示狀态,9 表示事務inactive,10表示active.

uel:跟送出清單有關

dba:表示該事務對應的undo block dba位址

1.2 解析undo塊、undo chain結構

根據前面兩個塊的xid(0x0006.01f.000001a5)可知,事務使用的是1f号槽位,從前面事務表的圖中可以看出,該槽位的state列為10,即事務未送出,其對應的undo block的位址為c03fba。

将該dba位址進行轉換:

假事務之名,深入研究UNDO與REDO

使用的undo塊是3号檔案的16314号塊,下面dump該塊進行觀察:

假事務之名,深入研究UNDO與REDO

這裡有兩個重要結構,irb指向事務的最後一條undo記錄,即復原的起點,icl指向事務的第一條undo記錄,即復原的終點。

從前面資料塊dump的uba(0x00c03fba.0072.15、0x00c03fba.0072.14)的第三部分可知,事務對應的undo記錄為14、15,觀察這兩條記錄:

假事務之名,深入研究UNDO與REDO
假事務之名,深入研究UNDO與REDO

這裡需要注意三點:

redo記錄中的rci指向的是事務的前一條undo記錄;

前鏡像的内容中隻記錄了被修改列内容;

undo塊中存在着一條連結清單,這個連結清單見下圖:

假事務之名,深入研究UNDO與REDO

這就是undo chain的一部分,與事務的混滾操作有關,undo塊的irb指向事務undo record的最後一條記錄 ,該記錄中的rci指向前一個undo record記錄,以此類推,最後一個undo record的ric為空,表示事務的起點,也是復原的終點。

下圖是完整的undo chain:

假事務之名,深入研究UNDO與REDO

這裡大家可以擴充思考一下,oracle的save point是如何實作的,是不是會與undo chain有關?如果修改rci值是不是可以實作復原部分事務?

下面我們來看一個網上流傳比較廣的一個圖:

假事務之名,深入研究UNDO與REDO

從前面我們的實驗可以看出,這個圖是有歧義的,undo鏡像不是塊級别的,是以不是一個資料塊對應一個undo塊,undo鏡像其實是列級别的,隻有被更改的列才會被記錄。

undo在事務中的工作方式我們就先分析到這。

 2  redo在事務中的作用 

2.1 解析redo結構、undo受redo保護的實質、cv對資料塊的作用

下面來看一看redo是如何工作的:

假事務之名,深入研究UNDO與REDO

接下來dump 405号塊進行觀察(這裡隻選取表資料部分)

假事務之名,深入研究UNDO與REDO

使用bbed觀察dba+這列的行頭資訊

假事務之名,深入研究UNDO與REDO

下面删除其中的兩條資料(這兩條資料是位于不同的塊中)

假事務之名,深入研究UNDO與REDO

dump上面兩個scn之間的redo進行觀察

假事務之名,深入研究UNDO與REDO
假事務之名,深入研究UNDO與REDO
假事務之名,深入研究UNDO與REDO

下面對redo dump進行分析:

1、 redo log是以change vector為最小機關構成的,就是上面的change #n部分;

2、 一個redo record包含多個cv(change vector);

3、 op表示操作類型,不同的值表示不同的操作類型;

4、 redo中包含了前鏡像,這就是redo保護undo的實質;

5、 上面的操作涉及兩個塊,但是隻有一條redo record,是以redo record是可以包含多個塊的,但是一個cv隻能針對一個塊,cv是一個資料塊塊版本演進的結果,cv隻能向前推進資料塊的版本,不能後退,對于復原操作,會由于undo的應用而生成新的cv,這個cv依然是推進資料塊版本,要使資料塊版本回退的唯一方法是媒體恢複。

2.2 了解快速提價機制、delete實質

下面再次dump 405号塊(包含dba+的資料塊)

假事務之名,深入研究UNDO與REDO

注意,這裡nrow顯示還有兩行資料,但是删除行的資料沒有在dump中顯示;行鎖标記也未釋放,但是事務已經送出了,這就是oracle的快速送出、和延遲塊清除機制,隻是保證修改undo段頭事務表資訊,塊頭和行頭資訊不一定進行修改。

那麼delete到底發生了什麼?下面用bbed進行觀察:

假事務之名,深入研究UNDO與REDO

發現被删除的資料依然在塊中,隻是行頭标記被修改,這就是delete的實質。是以在資料被覆寫之前是可以通過修改行頭标記恢複被delete的資料的。

還記得我們開始的那句話嗎?愛情就像鬼一樣,誰都聽過,但誰也沒見過。通過上面的實驗,我們應該看到了一些東西。真愛還是有的!

時間,教會了我們很多東西。有些我們曾經認為根本沒有的,後來發現,它确确實實存在着,而有些我們深信不疑的,後來卻明白,根本就沒有。比如,愛情…

<b></b>

<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2015-11-20</b>