Oracle Online Redefinition線上重定義(上)
面對越來越多的7*24系統,運維人員進行工作可用的時間視窗變的越來越小。就在有限的時間視窗中,硬體檢修、網路改造配置佔據了很多時間。對資料庫物件進行日常維護,越來越成為我們需要關注的問題。
進行資料重排、表分割槽、欄位型別修改、欄位增改這樣的操作,在開發和測試環境上是比較容易進行的。即使資料表很大,操作耗時可能會很高,我們也能夠透過一些非技術的手段贏取操作時間窗。但是對於投產系統而言,操作過程中的長時間鎖定可能是業務不能接受的。這個時候,就可以考慮Oracle的一些Online操作技術。
在筆者之前的一些文章中,介紹過一些online處理方法,如刪除海量資料表,暫時隱去unused特定資料列,11g中預設值列最佳化等等。本篇我們介紹Oracle的Online Redefinition(線上重定義)特性。
1、 基礎知識
Oracle Online Redefinition可以保證在資料表進行DDL型別操作,如插入、刪除資料列,分割槽處理的時候,還能夠支援DML操作,特別是insert/update/delete操作。
對一般的DDL過程而言,Oracle都會給資料物件一個獨佔表鎖。也就是說,在進行DDL操作的過程中,我們是不能對資料表進行DML(增加、修改和刪除操作)。只有等待DDL結束,才能夠繼續操作。
也就是說,如果一個DDL持續時間很長,比如資料表海量大小,那麼在這個長時間中,系統資料表其實是不能對外提供服務的。
Oracle線上重定義提供瞭解決問題的途徑。我們如果需要對一個資料表進行重定義,需要定義一箇中間目標表Interim。在Interim表中定義好目標結構,比如期望的儲存、分割槽、欄位關係。線上重定義使用的主要是dbms_redefinition包的對應方法。
線上重定義最大的特點是,當進行online操作的時候,我們還可以對資料表進行DML操作。結束定義過程時,期間進行的操作都是可以反饋到目標資料表中的。
目前,Oracle線上重定義支援下列種類的重定義動作:
ü 插入、刪除資料表列和對一個存在的資料表列改名;
ü 修改欄位型別;
ü 消除資料表段中的碎片塊;
ü 索引、約束等物件的重定義;
ü 分割槽錶轉變;
下面,我們透過一個簡單的例子,去看看如何使用dbms_redefinition包進行重定義操作。
2、簡單的重定義例子
我們在Oracle 11gR2中進行測試實驗。
SQL> select * from v$version where rownum<3;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
PL/SQL Release 11.2.0.3.0 – Production
首先我們建立目標資料表。
SQL> create table t as select object_id, object_name, owner from dba_objects;
Table created
Executed in 0.328 seconds
SQL> select count(*) from t;
COUNT(*)
----------
75192
Executed in 0.047 seconds
SQL> alter table t add constraint pk_t_id primary key (object_id);
Table altered
進行線上重定義的第一步,就是判斷目標資料表是否可以進行重定義。此時,可以使用dbms_redefinition包的can_redef_table方法進行判斷。
SQL> exec dbms_redefinition.can_redef_table( 'SCOTT','T',dbms_redefinition.cons_use_pk);
PL/SQL procedure successfully completed
Executed in 0.016 seconds
注意該方法的第三個引數,使用主鍵還是rowid方法。本質上,Online Redefinition是使用物化檢視Materialized View技術。過程定義記錄就是主鍵和rowid兩種策略。通常而言,我們還是推薦資料表有一個明確主鍵,也就是使用cons_use_pk。如果希望使用rowid,就使用dbms_redefinition.cons_use_rowid。
透過了檢查之後,就可以進行下一步,定義目標資料表格式。無論是何種變化,我們需要建立一箇中間表interim,將我們“期望”的資料表定義實現在裡面。其中包括表型別、列定義、分割槽定義和索引等。但是注意,約束(主外來鍵)可以不定義在其中。
SQL> create table t_interim as select * from dba_objects where 1=0;
Table created
Executed in 0.032 seconds
顯然,我們是希望給資料表T增加一些列。
此時,我們就可以開始重定義過程。使用dbms_redefinition的start_redef_table方法。
SQL> exec dbms_redefinition.start_redef_table('SCOTT','T','T_INTERIM',col_mapping => 'object_id object_id, object_name object_name, owner owner',options_flag => dbms_redefinition.cons_use_pk);
PL/SQL procedure successfully completed
Executed in 0.625 seconds
此處注意引數col_mapping,這裡以配對鍵值的方式定義了源資料表和中間表在列關係上的對應關係。每個列關係按照<源列名 目標列名>的格式進行書寫。
對約束的處理,如果有需要轉換的約束物件,我們可以使用copy_table_dependents方法將source資料表的約束複製到目標物件中。
SQL> declare
2 error_count number;
3 begin
4 error_count := 0;
5 dbms_redefinition.copy_table_dependents(uname => 'SCOTT',orig_table => 'T',
6 int_table => 'T_INTERIM',
7 copy_indexes => dbms_redefinition.cons_orig_params,
8 num_errors => error_count);
9 dbms_output.put_line(to_char(error_count));
10 end;
11 /
0
PL/SQL procedure successfully completed
Executed in 4.265 seconds
這個方法的引數很多,定義如下:
-- NAME: copy_table_dependents
--
-- INPUTS: uname - schema name
-- orig_table - name of table to be re-organized
-- int_table - name of interim table
-- copy_indexes - integer value indicating whether to
-- copy indexes
-- 0 - don't copy
-- 1 - copy using storage params/tablespace
-- of original index
-- copy_triggers - TRUE implies copy triggers, FALSE otherwise
-- copy_constraints - TRUE implies copy constraints, FALSE
-- otherwise
-- copy_privileges - TRUE implies copy privileges, FALSE
-- otherwise
-- ignore errors - TRUE implies continue after errors, FALSE
-- otherwise
-- num_errors - number of errors that occurred while
-- cloning ddl
-- copy_statistics - TRUE implies copy table statistics, FALSE
-- otherwise.
-- If copy_indexes is 1, copy index
-- related statistics, 0 otherwise.
-- copy_mvlog - TRUE implies copy table's MV log, FALSE
-- otherwise.
PROCEDURE copy_table_dependents(uname IN VARCHAR2,
orig_table IN VARCHAR2,
int_table IN VARCHAR2,
copy_indexes IN PLS_INTEGER := 1,
copy_triggers IN BOOLEAN := TRUE,
copy_constraints IN BOOLEAN := TRUE,
copy_privileges IN BOOLEAN := TRUE,
ignore_errors IN BOOLEAN := FALSE,
num_errors OUT PLS_INTEGER,
copy_statistics IN BOOLEAN := FALSE,
copy_mvlog IN BOOLEAN := FALSE);
利用各種copy_xxx引數,我們可以精細的定義哪些約束依賴關係會被複製到目標表中。
當結束之後,我們需要使用finish_redef_table方法結束定義過程。
SQL> exec dbms_redefinition.finish_redef_table('SCOTT','T','T_INTERIM');
PL/SQL procedure successfully completed
Executed in 1.406 seconds
最後,我們檢視效果。
SQL> desc t;
Name Type Nullable Default Comments
-------------- ------------- -------- ------- --------
OWNER VARCHAR2(30) Y
OBJECT_NAME VARCHAR2(128) Y
SUBOBJECT_NAME VARCHAR2(30) Y
OBJECT_ID NUMBER Y
DATA_OBJECT_ID NUMBER Y
OBJECT_TYPE VARCHAR2(19) Y
CREATED DATE Y
LAST_DDL_TIME DATE Y
TIMESTAMP VARCHAR2(19) Y
STATUS VARCHAR2(7) Y
TEMPORARY VARCHAR2(1) Y
GENERATED VARCHAR2(1) Y
SECONDARY VARCHAR2(1) Y
NAMESPACE NUMBER Y
EDITION_NAME VARCHAR2(30) Y
SQL> desc t_interim;
Name Type Nullable Default Comments
----------- ------------- -------- ------- --------
OBJECT_ID NUMBER
OBJECT_NAME VARCHAR2(128) Y
OWNER VARCHAR2(30) Y
SQL> select count(*) from t;
COUNT(*)
----------
75192
資料表T的欄位被新增上,而中間表的結構被設定為原來的樣子。約束內容,也就是原來的主鍵也被保留下來。
--在dbms_metadata.getddl輸出片段
"EDITION_NAME" VARCHAR2(30),
CONSTRAINT "PK_T_ID" PRIMARY KEY ("OBJECT_ID")
至此,我們完成了一個最簡單的重定義過程。大致分為五個步驟:
ü 判斷資料表是否可以支援重定義,定義中間表Interim結構;
ü 使用dbms_redefinition的start_redef_table方法開始重定義過程;
ü 複製約束、重定義register約束資訊內容;
ü 同步online過程中的DML操作(Optional,在之後例子演示);
ü 結束過程finish_redef_table操作;
對線上重定義,其中的細節過程,例如實現方式、中間DML操作同步、鎖機制和各種方法的功能原理,我們在下面繼續進行討論。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29067253/viewspace-2141761/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle Online Redefinition線上重定義(中)Oracle
- Oracle Online Redefinition線上重定義(下)Oracle
- Online Redefinition線上重定義(一)
- Online Redefinition線上重定義(三)--多表關聯重定義案例
- Oracle線上重定義之DBMS_REDEFINITIONOracle
- 線上重定義表(Redefine Tables Online) - dbms_redefinition
- 使用DBMS_REDEFINITION包執行線上重定義表(ONLINE TABLE REDEFINITION)
- Online Redefinition線上重定義(二)--單表複雜案例
- dbms_redefinition線上重定義表
- 利用DBMS_REDEFINITION線上重定義表
- 【redefinition】線上重定義概覽與使用
- DBMS_REDEFINITION(線上重定義一個重要bug)
- oracle 線上重定義Oracle
- Oracle線上重定義Oracle
- 分割槽表和dbms_redefinition包線上重定義表
- oracle 表線上重定義Oracle
- oracle表線上重定義Oracle
- 【Oracle】線上重定義表Oracle
- 【REDEFINITION】使用線上重定義dbms_redefinition完成主鍵列型別的調整型別
- Oracle的線上重定義(轉)Oracle
- 使用DBMS_REDEFINITION線上重定義表普通表為分割槽表
- Oracle表的線上重定義(一)Oracle
- oracle線上重定義表步驟Oracle
- Oracle中重建表的線上重定義Oracle
- 線上重定義表ORACLE 11GOracle
- 指令碼:線上重定義,從普通表到分割槽表,redefinition_table.sh指令碼
- 【TABLE】oracle表線上重定義注意事項Oracle
- oracle實驗記錄 (線上重定義表)Oracle
- Online Redefinition
- 在oracle 9i下線上重定義表Oracle
- Oracle 9i中表的線上重定義(轉)Oracle
- ORACLE 線上重新定義表分割槽表重定義為普通表。Oracle
- oracle分割槽表線上重定義欄位not null問題OracleNull
- ORACLE 普通錶轉換成分割槽表(線上重定義)Oracle
- 10g線上重定義新特性——對單獨的分割槽進行線上重定義
- dbms_redefinition利用線上重定義把普通錶轉化為分割槽表的一些測試
- 使用ORACLE線上重定義將普通表改為分割槽表Oracle
- ORACLE 普通錶轉換成分割槽表(線上重定義)(zt)Oracle