【Oracle】利用線上重定義的方式改變普通表為分割槽表

楊奇龍發表於2012-03-13
將普通表改為分割槽表有如下幾種方式:
1 建立一個和原表一樣的分割槽表A_NEW ; 
  將insert A_NEW SELECT * FROM A; 
  將表A 命名為A_OLD 將A_NEW 該名為A;
2 利用在先重定義的方式!也是接下來要介紹的方法!
第一種方式需要停止應用對A的寫訪問;使用線上重定義的方式可以對應用透明!
測試例子如下:
1 建立測試表
建立普通表:
@bigtab.sql --tom 的大表建立指令碼!
建立中間分割槽PART_TAB,使用PART_TAB來替換bigtab
YANG@yangdb>  CREATE TABLE PART_TAB
  2     (    ID NUMBER,
  3          OWNER VARCHAR2(30) NOT NULL ENABLE,
  4          OBJECT_NAME VARCHAR2(30) NOT NULL ENABLE,
  5          SUBOBJECT_NAME VARCHAR2(30),
  6          OBJECT_ID NUMBER NOT NULL ENABLE,
  7          DATA_OBJECT_ID NUMBER,
  8          OBJECT_TYPE VARCHAR2(19),
  9          CREATED DATE NOT NULL ENABLE,
10          LAST_DDL_TIME DATE NOT NULL ENABLE,
11          TIMESTAMP VARCHAR2(19),
12          STATUS VARCHAR2(7),
13          TEMPORARY VARCHAR2(1),
14          GENERATED VARCHAR2(1),
15          SECONDARY VARCHAR2(1),
16          NAMESPACE NUMBER NOT NULL ENABLE,
17          EDITION_NAME VARCHAR2(30)
18     )  PARTITION BY RANGE (id) 
19       (PARTITION P1 VALUES LESS THAN (100000), 
20        PARTITION P2 VALUES LESS THAN (200000), 
21        PARTITION P3 VALUES LESS THAN (300000), 
22        PARTITION P4 VALUES LESS THAN (400000),
23        PARTITION P5 VALUES LESS THAN (MAXVALUE)
24  );
Table created.
2 驗證是否可以進行線上重定義:
YANG@yangdb> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(user, 'BIGTAB', DBMS_REDEFINITION.CONS_USE_PK);
PL/SQL procedure successfully completed.
3 執行表的線上重定義:
YANG@yangdb> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'BIGTAB', 'PART_TAB');
PL/SQL procedure successfully completed.
第一步完成的時候 可以在session 2中檢視:
YANG@yangdb> SELECT COUNT(*) FROM BIGTAB;
  COUNT(*)
----------
    500000
YANG@yangdb> SELECT COUNT(*) FROM PART_TAB PARTITION (P2);
  COUNT(*)
----------
    100000
YANG@yangdb> SELECT COUNT(*) FROM PART_TAB PARTITION (P3);
  COUNT(*)
----------
    100000
YANG@yangdb>
4 執行把中間表的內容和資料來源表進行同步。
在session 2 中對原表進行dml 操作並提交:
YANG@yangdb>update bigtab set id=id-1 where rownum <10000;
9999 rows updated.
YANG@yangdb> commit;
Commit complete.
在session 1 對錶進行同步變化的資料!根據資料量的大小要等待相應的時間!
YANG@yangdb>execute dbms_redefinition.sync_interim_table(user,'BIGTAB','PART_TAB');
PL/SQL procedure successfully completed.
同步完成之後再次在session 中查詢中間表並沒有和原表一樣:
YANG@yangdb> SELECT ID FROM BIGTAB WHERE ROWNUM < 10;

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
9 rows selected.
YANG@yangdb> 
YANG@yangdb> SELECT ID FROM PART_TAB WHERE ROWNUM < 10;
        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
9 rows selected.
等到結束之後才可以再次檢視的時候 兩邊一致!
5 執行結束線上定義過程
YANG@yangdb> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(user, 'BIGTAB', 'PART_TAB');
PL/SQL procedure successfully completed.
6 檢視資料字典,可以看到改表已經成為了分割槽表。
YANG@yangdb> select table_name,partition_name,high_value  from user_tab_partitions;
TABLE_NAME      PARTITION_NAME  HIGH_VALUE
--------------- --------------- ---------------
BIGTAB          P1              100000
BIGTAB          P2              200000
BIGTAB          P3              300000
BIGTAB          P4              400000
BIGTAB          P5              MAXVALUE
YANG@yangdb> SELECT COUNT(*) FROM BIGTAB;
  COUNT(*)
----------
      6264
YANG@yangdb> SELECT COUNT(*) FROM PART_TAB PARTITION (P2);
  COUNT(*)
----------
      6246

至此普通錶轉為分割槽操作完成
如果執行線上重定義的過程中出錯,可以在執行dbms_redefinition.start_redef_table之後到執行dbms_redefinition.finish_redef_table之前的時間裡執行:DBMS_REDEFINITION.abort_redef_table(user, 't', 'PART_TAB')以放棄執行線上重定義。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-718458/,如需轉載,請註明出處,否則將追究法律責任。

相關文章