truncate表恢復測試

創建測試表,truncate

SQL> conn t1/t1
Connected.

SQL> create table t4 as select * from user_objects;

Table created.

SQL> truncate table t1.t4;

Table truncated.

停止業務對錶空間的操作,可以將表空間readonly,收集表的元數據,索引等信息略。

查看對象信息

SQL> conn / as sysdba
Connected.
SQL> select owner,object_name from dba_objects where object_name='T4' and owner='T1';

OWNER                          OBJECT_NAME                    
------------------------------ ------------------------------ 
T1                             T4                                      

查詢最後一次ddl時間


SQL> select owner,object_name,data_object_id,to_char(last_ddl_time,'yyyy-mm-dd hh24:mi:ss') from dba_objects where object_name='T4' and owner='T1';

OWNER                          OBJECT_NAME          DATA_OBJECT_ID TO_CHAR(LAST_DDL_TI
------------------------------ -------------------- -------------- -------------------
T1                             T4                            87205 2020-03-17 12:46:40

查詢時間點對應的data_object_id

SQL> SELECT obj#,OWNER#,dataobj# FROM obj$ AS OF TIMESTAMP TO_TIMESTAMP('2020-03-17 12:46:40', 'YYYY-MM-DD HH24:MI:SS') WHERE NAME = 'T4';

      OBJ#     OWNER#   DATAOBJ#
---------- ---------- ----------
     87204         83      87204

創建新的表空間防止數據被覆蓋


SQL> create tablespace test datafile size 100m;

Tablespace created.

SQL> create table t4 tablespace test  as select * from t1.t4 where rownum<1;

Table created.

修改dataobj#

SQL> update obj$ set dataobj#=87204 where obj#=87204;

1 row updated.

SQL> commit;

Commit complete.

SQL> alter system flush shared_pool;

System altered.

查看錶已顯示object no longer exists

SQL> select * from t1.t4
  2  ;
select * from t1.t4
                 *
ERROR at line 1:
ORA-08103: object no longer exists

恢復數據到新建的表

declare
   v_fno number;
   v_s_bno number;
   v_e_bno number;
   v_rowid rowid;
   nrows number;
begin
   for i in (select relative_fno,block_id,blocks 
               from dba_extents 
                          where owner='T1' and segment_name='T4' and extent_id=0 
             union all
             select relative_fno,block_id,blocks 
               from dba_free_space 
              where tablespace_name in 
                          (select tablespace_name 
                             from dba_tables 
                                where owner='T1' and table_name='T4')
                         union all
                         select relative_fno,block_id,blocks from (
                         select relative_fno,block_id,blocks,row_number()over(partition by owner,segment_name,PARTITION_NAME order by extent_id desc) rn
               from dba_extents 
              where tablespace_name in 
                          (select tablespace_name 
                             from dba_tables 
                                where owner='T1' and table_name='T4') and extent_id>0)
                           where rn=1) loop
   v_fno:=i.relative_fno;
   v_s_bno:=i.block_id;
   v_e_bno:=i.block_id+i.blocks-1;
       for j in v_s_bno .. v_e_bno loop
        begin
         for x in 0 .. 999 loop
           v_rowid:=dbms_rowid.rowid_create(1,87204,v_fno,j,x);
           insert into sys.T4 select * from T1.T4 where rowid=v_rowid;
         end loop;
        exception 
          when others then 
            null;
        end;
        commit;
       end loop;           
    end loop;
end;
/

查看數據


SQL> select * from t4;

OBJECT_NAME          SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE         CREATED   LAST_DDL_ TIMESTAMP        STATUS  T G S  NAMESPACE EDITION_NAME
-------------------- ------------------------------ ---------- -------------- ------------------- --------- --------- ------------------- ------- - - - ---------- ------------------------------
T4                                                       87204          87204 TABLE               17-MAR-20 17-MAR-20 2020-03-17:12:46:14 VALID   N N N        1
T11                                                      87190          87190 TABLE               17-MAR-20 17-MAR-20 2020-03-17:11:47:11 VALID   N N N        1
T3                                                       87203          87203 TABLE               17-MAR-20 17-MAR-20 2020-03-17:12:45:25 VALID   N N N        1

將dataobj#改回原值時插入也一樣報錯

SQL> update obj$ set dataobj#=87205 where obj#=87204;

1 row updated

SQL> alter system flush shared_pool;

System altered.

SQL> select * from t1.t4;

no rows selected

SQL>  insert into t1.t4 select * from t4;
 insert into t1.t4 select * from t4
                *
ERROR at line 1:
ORA-00600: internal error code, arguments: [ktspfmdb:objdchk_kcbnew_3], [0], [87205], [4], [], [], [], [], [], [], [], []

刪除原表重建備份表結構插入數據重建索引


SQL> drop table t1.t4 purge;

Table dropped.

SQL> create table t1.t4;

Table created.

SQL> insert into t1.t4 select * from t4;

附:

DBMS_ROWID.ROWID_CREATE (
    rowid_type           IN NUMBER,
    object_number    IN NUMBER,
    relative_fno          IN NUMBER,
    block_number     IN NUMBER,
    row_number       IN NUMBER)

參數:
rowid_type:rowid類型(restricted或者extended)。設置rowid_type爲0時,代表restricted ROWID(此時,將忽略參數object_number):設置rowid_type爲1時,代表extended ROWID。
object_number:數據對象編號(僅restricted類型rowid可用)。
relative_fno:所在數據文件編號。
block_number:該數據文件中的數據塊編號。
row_number:在該塊中的行編號。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章