揭祕Oracle資料庫truncate原理
第一章 Oracle核心系列2-揭祕Oracle資料庫truncate原理
DBAplus社群 | 2015-11-30 23:45
一、Truncate簡介
無數次事故告訴我們,Truncate是一項很危險的動作。一不小心搞錯,就會帶來毀滅性的打擊。我們都知道當Truncate命令發起之後,Oracle實際上並沒有在刪除底層資料塊上的資料,而是要等到重用的時候才會把這一部分資料回收,於是這給了我們一個能夠恢復資料庫的機會。
二、知己知彼
對於Truncate單表來說,其實就相當於摧毀我們的一個段,我們資料庫中的物理結構是由段區塊三個構成的。首先我們要最需要了解的就是一張“圖譜”?圖譜是什麼?就是一個段的組成結構,而最能表現段的構成的就是一個三級點陣圖塊的結構圖。
我們可以看到一個段最先是由段頭塊構成的,段頭其實就是第1個L3塊,只有當這些無法記錄下的時候,才會產生第2個L3級塊,不過這種情況非常少見,段頭塊指向了若干的L2點陣圖塊,每個L2點陣圖塊又指向了若干L1點陣圖塊,L1點陣圖塊則指向了真正的資料塊。
1.建立實驗環境所需要的表
實驗環境建立完成之後,我們就需要摸清楚我們的這個段A的點陣圖及資料塊分佈情況,我們不直接從檢視裡面查,這裡我們考慮需要通過bbed的方式從資料塊中獲取點陣圖及資料塊分佈情況。
2.段頭塊/L3點陣圖塊指向了哪些L2點陣圖塊
段由哪些區間構成?這個資訊我們需要從段頭塊中獲取出來。當你建立一個段後,即使你沒有往裡面插入任何資料,系統也是會預先分配一些區給你的。所以段頭塊是那個塊,我們可以通過dba_segments查詢出來。就算truncate了這個段,我們仍然能夠從dba_segments中查詢到段頭的資訊。
找到了段頭塊,我們就可以用bbed挖掘下資訊。
這裡我們可以看到段頭塊的第一個offset是23。那麼我們的段頭塊指向的L2點陣圖塊在offset 5192的位置。這裡請記住段頭塊的標示是23。
從這裡我們既可以找到我們的L2點陣圖塊,81004001,這裡只有1個L2塊,因為後面都是00000000(空),因為涉及到作業系統位元組序的問題,這裡需要轉換換成01400081。轉換後我們可以使用下列查詢找到檔案號和塊號。
3.L2點陣圖塊指向了哪些L1點陣圖塊
接下來我們可以繼續讀我們的L2點陣圖塊來尋找我們的L1點陣圖塊。可以看到L2的第一個offset是21。請記住L2點陣圖塊的標示是21。
L2指向L1資料塊的位置從offset 116開始。到哪兒結束需要看後面有沒有00000000(空)
從dump出來的地方我們來看,前面是一個地址,後面跟著是01000100,比較規律,大概7組之後就變成00000000(空)了。 跟上面一樣因為位元組序的問題,這裡我們需要將80004001轉換成01400080。然後我們通過下列查詢得到了區塊的位置。而後面的01000100,前面的01則這個L1下面的塊全部填滿,無空資料塊,後面的01則代表這個塊是instance 1產生的。而最後的一個05000100,05則代表著這個L1下面還有空塊,可以插入。而後面的01我們說過代表著是instance。如果這個系統是個rac的系統,節點2也插入了資料,那麼這裡就會顯示05000200。
通過上述查詢,我們找到了7個L1塊的資訊。
4.L1點陣圖塊指向了哪些資料塊
前面我們查到了我們的L2塊上指向的L1塊,並且清楚的知道哪個L1下面是滿的,哪個L1下面還有空閒塊。我們就從拿最後一個有空閒塊的L1點陣圖塊進行分析。
可以看到L1的第一個offset是20。請記住L1點陣圖塊的標示是20。
L1指向資料塊的位置從offset 204開始。到哪兒結束需要看後面有沒有00000000(空)
大家可以看到這裡的值是e0004001,08000000,00000000,下一組值是e8004001,08000000,08000000,然後面就是00000000(空)。
這兩個的意思是告訴我們L1指向資料塊的起始位置,比如e0004001,就是檔案5,塊224,也就是它自己本身。08000000就代表著這個塊後面的連續7個塊都是的。而e8004001,08000000,08000000,就是檔案5,塊232,08000000就代表著這個塊後面的連續7個塊也是的。而最後一個08000000則代表著offset,這裡我們可以不用去管它。所以這裡我們就能夠知道我們的L1塊下面具體的資料塊有:224(它本身),225,226,227,228,229,230,231,232,233,234,235,236,237,238,239。我們來用下列語句查證一下。
可以看到223後面直接就是225,直接此處跳空,這是因為我們的224是L1點陣圖塊,後面緊跟著我們剛剛說的225,226,227,228,229,230,231,232,233。但是問題是,這裡看不到後面的234到239?這是因為234到239還是空閒沒有格式化過的塊,但是它已經被L1鎖定了。那麼我們的L1能不能看到這些情況呢?我們可以觀察offset 396。
這裡可以看到的是11111111,11000000。那麼這個代表什麼意思呢?如果這個塊是full的話,就是1,是unformatted的話就是0,正好和我們前面看到的吻合。
三、Truncate如何恢復?
1.Data Object ID恢復
前面我們介紹了我們的段的組成形式,這裡來總結一下,首先是段頭塊,它指向了L2塊,L2塊指向了L1塊,而L1塊則指向了我們真實的物理資料塊。試著想想,如果我們發起truncate之後,Oracle會怎麼做?
我們先來看一下物件,當我們建立物件的之後,OBJECT_ID和data_object_id都會是一樣的,但是當我們發生truncate之後,我們的object_id不會變,而data_object_id則會變掉。
這裡可以看到我們Truncate表之後,data_object_id從75722變成了75727。我們分別看一下我們的段頭塊,L2點陣圖塊,L1點陣圖塊,資料塊,這個ID是否有變化。分別從檢查塊130,129,224,225
通過對各個塊的dump,發現段頭和L2點陣圖塊的data_obj_id已經發生了改變,從ca270100變成了cf270100,而只有第一個L1發生了變化,資料塊則沒有發生改變。
那我們是不是把data_obj_id修改回來就能夠恢復資料呢?
這裡還需要修改資料字典,否則會報錯。
2.段頭高水位資訊恢復
修改了這些東西后,我們會發現資料還是沒有。我們還需要修改一些資訊。一個很重要的資訊就是段頭上的高水位資訊。在Truncate之前,段頭上會記載。前面我們在講L1塊的時候說過:
可以看到223後面直接就是225,直接此處跳空,這是因為我們的224是L1點陣圖塊,後面緊跟著我們剛剛說的225,226,227,228,229,230,231,232,233。但是問題是,這裡看不到後面的234到239?這是因為234到239還是空閒沒有格式化過的塊,但是它已經被L1鎖定了。
所以我們現在的高水位的塊是234,一般做全表掃描的查詢就會查高水位以下(234)的塊。我們來看下我們現在的高水位。
注意看這裡的高水位是83004001,轉換成檔案號和塊號,剛好是檔案5塊131。而前面的00000000,03000000,則代表著是擴充套件0,block 3,代表著高水位的位置。剛好是第一個extent的第三個塊。128是L1,129是L2,130是段頭塊。而131則是第一個可以使用的資料塊。所以這裡記錄了extent 0,block為3則代表了檔案5的131號塊。而08000000則代表了extent的大小,我們每個extents是由8個塊組成的。
那在truncate之前,我們的高水位的塊是檔案5塊234,我們從塊128開始,每8個塊是一個extent,234是第14個extent的第三個塊。後面的6個塊是沒有插入資料的空塊。這個在前面我dump 最後一個L1塊得知。回顧一下,這裡下面的塊狀態顯示11111111 11000000。
所以我們這個地方要把高水位從00000000 03000000 08000000 83004001修改成0d000000 02000000 08000000 ea004001。0d000000代表13,表明是第十四個擴充套件,02000000代表02,表明是第三個塊開始,而08000000還是一樣代表著這個擴充套件是8個塊的大小,而ea004001則代表著檔案5塊234。
修改完成之後,重新整理buffer cache,然後重新查詢。
3.Extents資訊恢復
可以看到資料量不對,這是因為我們Truncate之後,在段頭上只剩下了一個Extent的資訊。而我們的Extents是有14個的,這需要我們在修改如下幾個地方。Offset 264代表著我們Extents的數量,,這裡修改成0e代表了14個extents。
修改完Extents的數量之後,還需要新增對應的Extents Map的資訊。因為我們的Extents Map資訊也被刪除了。從我們的offset 280開始。
80004001 08000000這個Extents是我們第一個Extents。代表了檔案5的塊128。我們可以依次類推下列的資訊出來。而08000000則代表有8個資料塊構成一個Extents。
當然這些Extents Map修改完成之後,我們還需要在新增Auxillary Map。那什麼是輔助的Map呢?我們從Offset 2736開始。
這裡的80004001 83004001,代表這Extents中,L1塊的地址和Data Block的地址,可以看到在Extents 1上面,它的L1塊是128,而資料塊是從131開始的。因為我們的129是L2,130是段頭。所以下面我們構造其他的資料的時候,我們也要遵循這個規律。我們的Extents 2,它的L1還是128塊,但是它的資料塊確是從136開始的。而Extents 3,它的L1就是第二個L1塊,也就是144,而它的資料塊的開始則是從145開始的。依次類推下去。結果如下:
修改完成這些後,我們就能夠查到我們全部的資料了。
此時我們切勿執行一些其他的操作,應該儘快的使用CTAS的方式將這個表進行備份或者是匯出。因為段頭塊L2和L1的資訊還一些是沒有修改的。
至此,Truncate恢復完成。仔細的研究你才會發現,其實最重要的是摸清楚整個段的構造情況,只要你對整個段的構造情況,瞭若指掌,基本上恢復是很簡單的。
所以對於Truncate恢復,我總結以下步驟:
1. 遍歷所有資料檔案的資料塊,尋找offset 1是23的,23代表段頭塊,同時還要和相應的Data Object Id相同的,這個需要檢索offset 272的位置。
2. 找到了段頭塊,我們就可以通過offset 5192尋找到我們的L2塊。
3. 找到了L2塊,我們就可以通過offset 116找到所有的L1塊。找到了L1塊,我們就等於找到了資料塊。
4. 至此,我們就可以開始反向的構造段頭塊。
5. 修改段頭塊、L2塊和第一個L1塊的Data Object Id.,同時在修改資料字典。
6. 修改段頭塊的高水位資訊。當然這裡的高水位塊的辨別,一定會是在最後一個Extents上,你可以設定到最後一個Extnets的最後一個塊,這個資訊的準備性其實無所謂,全表掃描的時候它一定會掃描這個塊下面所有的塊。
7. 修改段頭上的Extents資訊。
以上步驟完成之後,資料就可以查到,首要步驟就是CTAS重建該物件。
About Me
....................................................................................................................................................
本文來自於微信公眾號轉載文章,若有侵權,請聯絡小麥苗及時刪除
ITPUB BLOG:http://blog.itpub.net/26736162
QQ:642808185 若加QQ請註明您所正在讀的文章標題
【版權所有,文章允許轉載,但須以連結方式註明源地址,否則追究法律責任】
....................................................................................................................................................
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2080727/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 揭祕Oracle雲(一):建立雲資料庫Oracle資料庫
- 揭祕Oracle雲(二):建立自治雲資料庫Oracle資料庫
- oracle資料庫啟動過程大揭祕Oracle資料庫
- 【資料庫資料恢復】如何恢復Oracle資料庫truncate表的資料資料庫資料恢復Oracle
- 資料湖揭祕—Delta Lake
- 【資料庫資料恢復】Oracle資料庫誤truncate table的資料恢復案例資料庫資料恢復Oracle
- 【資料庫資料恢復】oracle資料庫誤truncate table怎麼恢復資料?資料庫資料恢復Oracle
- 【資料庫資料恢復】誤truncate table的Oracle資料庫資料恢復方案資料庫資料恢復Oracle
- php陣列原理遍歷原理揭祕PHP陣列
- OPPO雲資料庫訪問服務技術揭祕資料庫
- [譯]揭祕基本資料型別資料型別
- 揭祕webpack外掛的工作原理Web
- Calico 網路通訊原理揭祕
- 記憶體池原理大揭祕記憶體
- FastTunnel-內網穿透原理揭祕AST內網穿透
- React Fiber 資料結構揭祕React資料結構
- SQL資料庫中Truncate的用法SQL資料庫
- 徹底揭祕keep-alive原理Keep-Alive
- 揭祕Flutter Hot Reload(原理篇)Flutter
- 一張圖揭祕Google眼鏡工作原理Go
- 一張圖揭祕谷歌眼鏡工作原理谷歌
- 星圖資料:揭祕618全網大資料大資料
- 揭祕RedisGraph: Redis內嵌高效能記憶體圖資料庫Redis記憶體資料庫
- 行業動態 | 利用Cassandra資料庫揭開家族祖先的祕密行業資料庫
- 獨家 | 揭祕2021雙11背後的資料庫硬核科技資料庫
- 資料庫:drop、truncate、delete的區別資料庫delete
- 【北亞資料恢復】oracle資料庫執行truncate table命令怎麼恢復資料?資料恢復Oracle資料庫
- widget state重新整理介面原理揭祕
- 揭祕並行資料倉儲的成本CF並行
- MySQL truncate原理MySql
- 【揭祕】資料庫面試葵花寶典,讓你面試一次過薦資料庫面試
- oracle logminer恢復truncate table的資料Oracle
- 13個“神祕”資料,幫你揭祕“男人”這東西!——資訊圖
- 揭開微盟百萬商家營銷大戰背後的資料庫祕密資料庫
- 大資料揭祕:學歷真的能改變命運?大資料
- 從根源揭祕HashMap的資料儲存過程HashMap儲存過程
- 資料庫原理資料庫
- Oracle中truncate table後的資料恢復(Oracle資料恢復工具-ODU)Oracle資料恢復