日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Oracle在线重定义

發布時間:2025/7/14 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle在线重定义 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://boylook.itpub.net/post/43144/520542


Oracle9i之前,表數據的整理是通過 alter table XXX move [tablespace XX]進行的。如果表非常大,IO又不快的時候,move的過程可能相當漫長,不能算是HA特性。因此在HA的在線維護中,基本不會利用move來重組大型表,而且move后的表需要重建索引。而在9i引入的dbms_redefinition。該過程的內部原理其實就是采用了MV的機制,類似在原表建立一個prebuilt的MV然后一直增量刷新到數據差別最小。Oracle在很小的停頓中,完成最后一點的增量同步,達到完全同步后,把原表與新表換個名字,由于換名操作僅僅是數據字典,所以最終切換時間非常短。
--首先建立一個用來測試外鍵約束的表test_refed


SQL> create table test_refed(id number primary key);

Table created.

SQL> insert into test_refed select rownum from dba_objects where rownum<10001;

10000 rows created.

SQL> commit;

Commit complete.

--創建我們準備修改表定義的表test,未分區

SQL> create table test(id number,fid number);

Table created.

SQL> insert into test select rownum,rownum from dba_objects where rownum<1001;

1000 rows created.

SQL> commit;

Commit complete.

--添加主鍵約束以及外鍵約束,并在外鍵上建立索引

SQL> alter table test add constraint pk_test primary key(id);

Table altered.

SQL> alter table test add constraint fk_test_refed_id foreign key(fid) references test_refed(id);

Table altered.

SQL> create index idx_test_fid on test(fid);

Index created.

--創建基于test表的觸發器

SQL> create trigger tr_test
2 before insert on test for each row
3 begin
4 null;
5 end;
6 /

Trigger created.

--準備工作:調用dbms_redefinition.can_redef_table來驗證boylook.test是否可以在線重定義。一般情況沒有主鍵等會報錯。
SQL> begin
2 dbms_redefinition.can_redef_table('BOYLOOK','TEST');
3 end;
4 /

PL/SQL procedure successfully completed.

--創建需要重新定義的過渡表inter_test,這是一個分區表,以后將把原表所有數據在線轉移到該表當中。注意到,該表比原表test還多一個字段c

SQL> create table inter_test(id number,fid number,c number)
2 partition by range(id)
3 (partition p1 values less than(400),
4 partition p2 values less than(800),
5 partition p3 values less than(maxvalue));

Table created.

SQL> alter table inter_test add constraint pk_inter_test primary key(id);

Table altered.

--執行在線重定義
注:調用這個存儲過程需要create/alter/drop/lock/select any table權限

SQL> exec dbms_redefinition.start_redef_table('BOYLOOK','TEST','INTER_TEST','id id,fid fid,0 c');

PL/SQL procedure successfully completed.

--驗證數據是否刷了過去
SQL> select count(*) from inter_test;

COUNT(*)
----------
1000

--繼續對原表test進行操作
SQL> insert into test select rownum+1000,rownum+1000 from dba_objects where rownum <=24;

24 rows created.

SQL> commit;

Commit complete.

SQL> select count(*) from test;

COUNT(*)
----------
1024

SQL> select count(*) from inter_test;

COUNT(*)
----------
1000

--執行表同步
注:這一步不是必須的,但是對于比較大的表,中間運行增量同步有助于減少切換時間

SQL> exec dbms_redefinition.sync_interim_table('BOYLOOK','TEST','INTER_TEST');

PL/SQL procedure successfully completed.

--我們發現數據同步的過來
SQL> select count(*) from inter_test;

COUNT(*)
----------
1024

--將原表test的約束,索引,觸發器遷移過來
注:這里最好要檢查一下授權。檢查test以前的權限,并給中間表inter_test賦予同樣的權限。否則原表的權限不會轉移到新表

SQL> alter table inter_test add constraint fk_inter_refed_id foreign key(fid) references test_refed(id);

Table altered.

SQL> create index idx_inter_test_fid on inter_test(fid);

Index created.

SQL> create or replace trigger tr_inter_test
2 before insert on inter_test for each row
3 begin
4 null;
5 end;
6 /

Trigger created.

--執行重定義完成的過程。Oracle完成了表test到表inter_test的換名工作,只是所有的約束,索引或觸發器名稱還是保持著原來表上面的名稱

SQL> exec dbms_redefinition.finish_redef_table('BOYLOOK','TEST','INTER_TEST');

PL/SQL procedure successfully completed.

SQL> desc test;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
FID NUMBER
C NUMBER

SQL> desc inter_test;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
FID NUMBER

SQL> select table_name,partition_name from user_tab_partitions where table_name ='TEST';

TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
TEST P1
TEST P2
TEST P3

SQL> select table_name,constraint_name,status from user_constraints where table_name in('TEST','INTER_TEST');

TABLE_NAME CONSTRAINT_NAME STATUS
------------------------------ ------------------------------ --------
INTER_TEST PK_TEST ENABLED
INTER_TEST FK_TEST_REFED_ID DISABLED
TEST PK_INTER_TEST ENABLED
TEST FK_INTER_REFED_ID ENABLED

SQL> select table_name,index_name from user_indexes where table_name in('TEST','INTER_TEST');

TABLE_NAME INDEX_NAME
------------------------------ ------------------------------
TEST PK_INTER_TEST
TEST IDX_INTER_TEST_FID
INTER_TEST PK_TEST
INTER_TEST IDX_TEST_FID

SQL> select table_name,trigger_name from user_triggers where table_name in('TEST','INTER_TEST');

TABLE_NAME TRIGGER_NAME
------------------------------ ------------------------------
TEST TR_INTER_TEST
INTER_TEST TR_TEST

SQL> select * from test where rownum <=10;

ID FID C
---------- ---------- ----------
1 1 0
2 2 0
3 3 0
4 4 0
5 5 0
6 6 0
7 7 0
8 8 0
9 9 0
10 10 0

10 rows selected.

--刪除過渡表了,收工。這時也可以考慮修改索引,約束觸發器的名稱與原來保持一致

SQL> drop table inter_test cascade constraints purge;

Table dropped.

轉載于:https://blog.51cto.com/boylook/1298615

總結

以上是生活随笔為你收集整理的Oracle在线重定义的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。