當前位置:編程學習大全網 - 遊戲軟體 - truncate table 如何恢復

truncate table 如何恢復

不小心Truncate表的事情也是有的, 其中大部份時因為工具連錯了庫, 從兒跑錯了角本. 遇到這種事情而沒有備份時怎麽辦呢? 首先要停止數據庫, 將這個表所在的表空間的文件拷貝出來, 因為Oracle在Truncate只時將相應Segment的第壹個塊格式化掉了, 而後面的都還存在, 到下次用時到才真正地重新格式化. 下面來講壹個Truncate表後進行恢復的例子: SQL> CREATE TABLE T_TRUNCATE AS SELECT * FROM TAB;

Table created.

SQL> SELECT COUNT(*) FROM T_TRUNCATE;

COUNT(*)

----------

14

SQL> ALTER SYSTEM CHECKPOINT;

System altered.

SQL> TRUNCATE TABLE T_TRUNCATE;

Table truncated.

SQL> ALTER SYSTEM CHECKPOINT;

System altered.

在Truncate時只是Segment Header格式化了, 並將Data Object ID換成壹個新的值, 我們可以在AUL中用DESC命令來查看:

AUL> desc anysql.t_truncate

Storage(OBJ#=9976 OBJD=9977 TS=4 FILE=4 BLOCK=5235 CLUSTER=0)

No. SEQ INT Column Name Type

--- --- --- ----------------------------- ----------------

1 1 1 TNAME VARCHAR2(30) NOT NULL

2 2 2 TABTYPE VARCHAR2(7)

3 3 3 CLUSTERID NUMBER

要恢復這個表的數據, 首先要在AUL中運行SCAN EXTENT命令, 因為Segment Header被格式化了, 所以Extent Map也可能丟失, 而Scan Extent則將掃描整個數據文件並將Extent分配信息寫入AULEXT.TXT文件:

AUL> SCAN EXTENT FILE 4

2006-12-18 21:32:10

2006-12-18 21:32:24

恢復的關鍵是要獲得這個表原來的Data Object ID, 在這個例子中我在Truncate表後什麽也沒有做就關閉數據庫進行恢復了. 從上面的DESC命令可以看出表的Segment Header是(4,5235), 而新的Data Object ID是9977, 老的Data Object ID我們可以從Segment Header的後面壹個數據塊中得到, 如果這個表有幾個Free List Group, 則可能還要再後面幾個塊. 用AUL的ORADUMP命令來看壹下後面壹個塊:

AUL> ORADUMP FILE 4 BLOCK 5236

RDBA=0x01001474(4/5236)=16782452,type=0x06,fmt=0xa2,seq=0x02,flag=0x04

seg/obj=0x000026f8=9976,csc=0x0000.0006caf5,itc=3,typ=1 - DATA

FLG=0x32, fls=0, nxt=0x01001471(4/5233)=16782449

......

可以看到原來的Data Object ID是9976, 現在可以恢復了, 先不指定原來的Data Object ID試試?

AUL> unload table anysql.t_truncate;

2006-12-18 21:33:37

Unload OBJD=9977 FILE=4 BLOCK=5235 CLUSTER=0 ...

2006-12-18 21:33:37

接下來指定原來的Data Object ID, 再試試?

AUL> unload table anysql.t_truncate object 9976;

2006-12-18 21:33:45

Unload OBJD=9976 FILE=4 BLOCK=5235 CLUSTER=0 ...

P_MV_FACT_SALES|TABLE

TIME_DIM|TABLE

FACT_SALES|TABLE

MV_FACT_SALES|TABLE

SEG$|TABLE

NUMTEST|TABLE

T_OBJECTS|TABLE

T_LOBTEST|TABLE

T_INCLOB|TABLE

CF_XXK|TABLE

T_TESTDMP|TABLE

T_CLOBDEMO|TABLE

T_BLOBDEMO|TABLE

T_TRUNCATE|TABLE

2006-12-18 21:33:45

可以看到14條數據全回來了, 當然數據庫是復雜的, 如果是壹個很大的表, 還是不能保證可以100%恢復的.

最近至少看到二次錯誤地截斷(Truncate)表的例子, 並在網上詢問如何恢復, 在這兒我給出AUL/MyDUL的解決方案, 下面是我用的壹個測試表:

ASQL> DESC TRUNCDEMO

NO# NAME NULLABLE TYPE

--- ----------------- -------- ------------

1 COL1 VARCHAR2(20)

ASQL> SELECT * FROM TRUNCDEMO;

COL1

-----

ROW 1

ROW 2

2 rows returned.

接下來我們來截斷表, 其實這個操作只是重新格式化了段頭塊(Segment Header), 並分配壹個新的數據對象號(Data Object ID), 當然空間分配信息也改了, 除非加了重用空間選項(Reuse Storage). 來看壹下這個操作的前後變化:

ASQL> SELECT DATA_OBJECT_ID, OBJECT_NAME FROM USER_OBJECTS;

DATA_OBJECT_ID OBJECT_NAME

-------------- -----------

13676 TRUNCDEMO

1 rows returned.

ASQL> truncate table truncdemo;

Truncate Table Succeed.

ASQL> SELECT DATA_OBJECT_ID, OBJECT_NAME FROM USER_OBJECTS;

DATA_OBJECT_ID OBJECT_NAME

-------------- -----------

13677 TRUNCDEMO

1 rows returned.

由於在System表空間中已經記錄了新的信息, 因此用當前的System信息是不能恢復過來的,在AUL/MyDUL中可以當作沒有System時的情況來處理,在下面的命令中, 我們用Truncate後的數據對象號就不能進行恢復, 而使用Truncate以前的就可以, 當然空間不能被重新利用了是恢復的前提.

AUL> unload object 13676 column varchar file 4;

2006-09-18 22:38:58

ROW 1

ROW 2

2006-09-18 22:39:04

AUL> unload object 13677 column varchar file 4;

2006-09-18 22:39:10

2006-09-18 22:39:10

AUL>

因此在意外發生Truncate後, 如果沒有備份可以恢復, 首先要做的事是備份壹下當前的文件, 免得空間被重用. 而Truncate之前的數據對象號在AUL/MyDUL中是很容易找出來的. 到此已經說明了如何恢復Truncate表了.

  • 上一篇:64位AutoCAD2010中文簡體版怎麽安裝與激活
  • 下一篇:深圳氣候怎麽樣
  • copyright 2024編程學習大全網