使用DBMS_REDEFINITION線上重定義表普通表為分割槽表

尛樣兒發表於2010-05-01


    這篇文章是使用DBMS_REDEFINITION包線上重定義將普通錶轉換為分割槽表”線上“功能的簡單測試,有關線上重定義表的更多內容請參考本文最後的連結。


首先線上重定義表可用於以下情況:

1.重組表資料,壓縮空間。
2.把表從一個表空間遷移到另一個表空間。
3.把表從普通錶轉化成分割槽表,把分割槽錶轉化成普通表。
4.線上刪除欄位。
5.修改一些職能重組才能修改的引數。


線上重定義表,亮點在於線上2字,實際操作中是如何體現線上2字的呢?下面的是將普通錶轉化成分割槽表的例子。

會話1:
[root@blliu ~]# su - oracle
[oracle@blliu ~]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Sat May 1 17:45:25 2010

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> connect xiaoyang/xiaoyang
Connected.
SQL>

#建立原始表
SQL> create table test
(
  APPLIEDTIME DATE not null,
  METERCODE   INTEGER not null,
  OBJID       INTEGER not null,
  DATA        NUMBER(18,4)
);  2    3    4    5    6    7

Table created.

#新增主鍵(必須有主鍵才能進行線上重定義表)
SQL> alter table test add constraint pk_test primary key(appliedtime,metercode,objid);

Table altered.

#插入模擬資料
SQL> declare
  2  v_d date :=to_date('2010-1-1','yyyy-mm-dd');
  3  metercode number;
  4  objid number;
  5  begin
  6  for i in 1..10000 loop
  7  v_d:=v_d+2/24/60/60;
  8  metercode :=abs(dbms_random.random mod 9);
  9  objid :=abs(dbms_random.random mod 99);
 10  insert into test values(
 11  v_d,
 12  metercode,
 13  objid,
 14  dbms_random.random);
 15  end loop;
 16  end;
 17  /

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

#建立重定義後的分割槽表
SQL> create table test111
  2  (
  3    APPLIEDTIME DATE not null,
  4    METERCODE   INTEGER not null,
  5    OBJID       INTEGER not null,
  6    DATA        NUMBER(18,4)
  7  )
  8  partition by range (appliedtime)(
  9  partition unit_power_second_t100102 values less than (to_date('2010-1-2','yyyy-mm-dd')),
 10  partition unit_power_second_t100103 values less than (to_date('2010-1-3','yyyy-mm-dd')),
 11  partition unit_power_second_t100104 values less than (to_date('2010-1-4','yyyy-mm-dd')),
 12  partition unit_power_second_t100105 values less than (to_date('2010-1-5','yyyy-mm-dd')),
 13  partition unit_power_second_t100106 values less than (to_date('2010-1-6','yyyy-mm-dd')),
 14  partition unit_power_second_t100107 values less than (to_date('2010-1-7','yyyy-mm-dd')),
 15  partition unit_power_second_t100108 values less than (to_date('2010-1-8','yyyy-mm-dd')),
 16  partition unit_power_second_t100109 values less than (to_date('2010-1-9','yyyy-mm-dd')),
 17  partition unit_power_second_t100110 values less than (to_date('2010-1-10','yyyy-mm-dd')),
 18  partition unit_power_second_t100111 values less than (to_date('2010-1-11','yyyy-mm-dd')),
 19  partition unit_power_second_t100112 values less than (to_date('2010-1-12','yyyy-mm-dd')),
 20  partition unit_power_second_t100113 values less than (to_date('2010-1-13','yyyy-mm-dd')),
 21  partition unit_power_second_t100114 values less than (to_date('2010-1-14','yyyy-mm-dd')),
 22  partition unit_power_second_t100115 values less than (to_date('2010-1-15','yyyy-mm-dd')),
 23  partition unit_power_second_t100116 values less than (to_date('2010-1-16','yyyy-mm-dd')),
 24  partition unit_power_second_t100117 values less than (to_date('2010-1-17','yyyy-mm-dd')),
 25  partition unit_power_second_t100118 values less than (to_date('2010-1-18','yyyy-mm-dd')),
 26  partition unit_power_second_t100119 values less than (to_date('2010-1-19','yyyy-mm-dd')),
 27  partition unit_power_second_t100120 values less than (to_date('2010-1-20','yyyy-mm-dd')),
 28  partition unit_power_second_t100121 values less than (to_date('2010-1-21','yyyy-mm-dd')),
 29  partition unit_power_second_t100122 values less than (to_date('2010-1-22','yyyy-mm-dd')),
 30  partition unit_power_second_t100123 values less than (to_date('2010-1-23','yyyy-mm-dd')),
 31  partition unit_power_second_t100124 values less than (to_date('2010-1-24','yyyy-mm-dd')),
 32  partition unit_power_second_t100125 values less than (to_date('2010-1-25','yyyy-mm-dd')));

Table created.

#模擬在業務系統執行DML操作
SQL> update test set metercode=1 where metercode=0;

1111 rows updated.

會話2:

#dbms_redefinition包的儲存過程和函式
SQL> desc dbms_redefinition
PROCEDURE ABORT_REDEF_TABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 ORIG_TABLE                     VARCHAR2                IN
 INT_TABLE                      VARCHAR2                IN
 PART_NAME                      VARCHAR2                IN     DEFAULT
PROCEDURE CAN_REDEF_TABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 TNAME                          VARCHAR2                IN
 OPTIONS_FLAG                   BINARY_INTEGER          IN     DEFAULT
 PART_NAME                      VARCHAR2                IN     DEFAULT
PROCEDURE COPY_TABLE_DEPENDENTS
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 ORIG_TABLE                     VARCHAR2                IN
 INT_TABLE                      VARCHAR2                IN
 COPY_INDEXES                   BINARY_INTEGER          IN     DEFAULT
 COPY_TRIGGERS                  BOOLEAN                 IN     DEFAULT
 COPY_CONSTRAINTS               BOOLEAN                 IN     DEFAULT
 COPY_PRIVILEGES                BOOLEAN                 IN     DEFAULT
 IGNORE_ERRORS                  BOOLEAN                 IN     DEFAULT
 NUM_ERRORS                     BINARY_INTEGER          OUT
 COPY_STATISTICS                BOOLEAN                 IN     DEFAULT
PROCEDURE FINISH_REDEF_TABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 ORIG_TABLE                     VARCHAR2                IN
 INT_TABLE                      VARCHAR2                IN
 PART_NAME                      VARCHAR2                IN     DEFAULT
PROCEDURE REGISTER_DEPENDENT_OBJECT
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 ORIG_TABLE                     VARCHAR2                IN
 INT_TABLE                      VARCHAR2                IN
 DEP_TYPE                       BINARY_INTEGER          IN
 DEP_OWNER                      VARCHAR2                IN
 DEP_ORIG_NAME                  VARCHAR2                IN
 DEP_INT_NAME                   VARCHAR2                IN
PROCEDURE START_REDEF_TABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 ORIG_TABLE                     VARCHAR2                IN
 INT_TABLE                      VARCHAR2                IN
 COL_MAPPING                    VARCHAR2                IN     DEFAULT
 OPTIONS_FLAG                   BINARY_INTEGER          IN     DEFAULT
 ORDERBY_COLS                   VARCHAR2                IN     DEFAULT
 PART_NAME                      VARCHAR2                IN     DEFAULT
PROCEDURE SYNC_INTERIM_TABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 ORIG_TABLE                     VARCHAR2                IN
 INT_TABLE                      VARCHAR2                IN
 PART_NAME                      VARCHAR2                IN     DEFAULT
PROCEDURE UNREGISTER_DEPENDENT_OBJECT
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 UNAME                          VARCHAR2                IN
 ORIG_TABLE                     VARCHAR2                IN
 INT_TABLE                      VARCHAR2                IN
 DEP_TYPE                       BINARY_INTEGER          IN
 DEP_OWNER                      VARCHAR2                IN
 DEP_ORIG_NAME                  VARCHAR2                IN
 DEP_INT_NAME                   VARCHAR2                IN

#檢視test表是否能被線上重定義
SQL> exec dbms_redefinition.can_redef_table(uname=>'xiaoyang',tname=>'test');

PL/SQL procedure successfully completed.

#開始線上重定義,由於會話1有未提交的事務,現在線上重定義無法開始
SQL>  exec dbms_redefinition.start_redef_table(uname=>'xiaoyang',orig_table=>'test',int_table=>'test111');

會話1:

#回滾事務
SQL> rollback;

Rollback complete.

會話2:

#開始線上重定義表成功
SQL>  exec dbms_redefinition.start_redef_table(uname=>'xiaoyang',orig_table=>'test',int_table=>'test111');

PL/SQL procedure successfully completed.

會話1:

#模擬業務系統運算元據
SQL>  update test set metercode=1 where metercode=0;

1111 rows updated.

會話2:

#同步原始表和線上同步後的表,這步不是必須,只是為了更快速、順利的完成線上重定義工作
SQL> exec dbms_redefinition.SYNC_INTERIM_TABLE(uname=>'xiaoyang',orig_table=>'test',int_table=>'test111');

PL/SQL procedure successfully completed.

#由於會話1有未提交的事務,無法完成線上重定義表
SQL>  exec dbms_redefinition.finish_redef_table(uname=>'xiaoyang',orig_table=>'test',int_table=>'test111');

會話1:

#提交事務
SQL> commit;

Commit complete.

會話2:

#完成了線上重定義表
SQL>  exec dbms_redefinition.finish_redef_table(uname=>'xiaoyang',orig_table=>'test',int_table=>'test111');

PL/SQL procedure successfully completed.

#透過查詢發現原始表和定以後的表都被更新了資料。
#說明一點:線上重定義表在開始和結束的時候不能有鎖表的事務出現,但是在定義過程中允許有鎖表的情況出現,提交的資料最後能夠被重定義到新表。

SQL> select count(*) from test where metercode=0;

  COUNT(*)
----------
         0

SQL> select count(*) from test111 where metercode=0;

  COUNT(*)
----------
         0

    有關線上重定義表更詳細的資訊,請參考文章《使用DBMS_REDEFINITION包執行線上重定義表》:http://blog.itpub.net/23135684/viewspace-1765128/

--end--

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

相關文章