程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> oracle利用DBMS

oracle利用DBMS

編輯:Oracle數據庫基礎
 

7*24的業務運營系統中,對一個表進行在線重定義將是很棘手的事,因為業務實時的在對這個表進行進行插入,刪除修改等操作,那麼是否可以在線重定義表呢,Oracle9i提供了在線重定義表包(DBMS_REDEFINITION),在修改表結構的同時可以進行DML操作。

1.構造原始數據表

SQL> create table red_test --原始表,需要對這個表進行在線重定義

2 as

3 select te_seq.nextval as id ,t.owner,t.object_name,10 as tvalue from dba_objects t ;

Table created

SQL> alter table RED_TEST --增加主鍵

2 add constraint pri_redtest primary key (id);

Table altered

SQL> create index idc_retest_owner on red_test(owner) ;

Index created

需求:把red_test進行在線重定義,把tvuale字段更改為sal字段,並且sal=tvalue*10

2.驗證是否可以在線重定義

SQL> EXEC Dbms_Redefinition.Can_Redef_Table(\'etl\', \'red_test\',DBMS_REDEFINITION.CONS_USE_PK);

PL/SQL procedure successfully completed

3.建立中間表

SQL> CREATE TABLE RED_TEST_MIDDLE AS

2 SELECT id,owner,object_name,tvalue as sal FROM red_test WHERE 1=2;

Table created

SQL> alter table RED_TEST_MIDDLE

2 add constraint pri_redtest123 primary key (id);

Table altered

4.進行在線重定義

SQL> EXEC Dbms_Redefinition.Start_Redef_Table( \'ETL\',\'RED_TEST\',\'RED_TEST_MIDDLE\',\'ID

ID, OWNER OWNER, OBJECT_NAME OBJECT_NAME,TVALUE*10 SAL\');

PL/SQL procedure successfully completed

6.同步中間表,主要是同步重定義過程中變化的數據

SQL> EXEC dbms_redefinition.sync_interim_table(\'ETL\', \'RED_TEST\', \'RED_TEST_MIDDLE\');

PL/SQL procedure successfully completed

7.測試在原始表繼續插入是否還會同步

SQL> insert into RED_TEST select te_seq.nextval as id ,t.owner,t.object_name,999 from dba_objects t ;

34193 rows inserted

SQL> commit;

Commit complete

--重定義過程原始表發生dml的數據會保留MV log,這就是為什麼原始表要有主鍵的原因,當然也可以利用rowid

SQL> select count(*) from Mlog$_red_test;--原始產生的dml操作會記錄在mv log

COUNT(*)

----------

34193

8.完成重定義

SQL> EXEC Dbms_Redefinition.Finish_Redef_Table( \'ETL\', \'RED_TEST\', \'RED_TEST_MIDDLE\');

PL/SQL procedure successfully completed

9.檢查是否完成了重定義

SQL> select ix.table_name,ix.index_name from user_indexes ix where ix.table_name=\'RED_TEST\';

TABLE_NAME INDEX_NAME

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

RED_TEST PRI_REDTEST123

SQL> select ix.table_name,ix.index_name from user_indexes ix where ix.table_name=\'RED_TEST_MIDDLE\' ;

TABLE_NAME INDEX_NAME

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

RED_TEST_MIDDLE IDC_RETEST_OWNER

RED_TEST_MIDDLE PRI_REDTEST

--比較一下中間表和原始表的索引,發覺僅僅是同步了數據,索引並不能同步過去,所以在正式環境中,應該先建立索引在完成重定義,建立索引可以放在第5步來做

10.刪除中間表

SQL> drop table RED_TEST_MIDDLE ;

Table dropped

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

一般會有這個需求,需要將在線大表(5G以上)更改為分區表,Dbms_Redefinition在線重定義非常慢,可能需要好幾個小時,大表又是實時的業務操作,這就存在很大的失敗風險。有朋友曾經在線重定義過程中失敗導致業務癱瘓,建議還是少用,或是不用,知道有這麼回事就可以了。

個人覺得如下步驟比較保險,但是需要停機

a) export the table

b) create a new empty table that has the partition definition on it

c) import the table with IGNORE=Y
 

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved