Online Redefinition線上重定義(二)--單表複雜案例
在上一篇博文(Online Redefinition線上重定義(一))中,簡單地介紹了Oracle線上重定義特性進行資料表線上結構變動操作。本篇博文將演示一個較複雜的案例,在案例的複雜變化中進行線上重定義及dbms_redefinition包各個關鍵方法的作用。
普通表改造分割槽表
--建立一張普通表t_wjq1
SEIANG@seiang11g>create table t_wjq1 as select object_id,object_name,created from dba_objects;
Table created.
SEIANG@seiang11g>desc t_wjq1
Name Null? Type
----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
OBJECT_ID NUMBER
OBJECT_NAME VARCHAR2(128)
CREATED DATE
SEIANG@seiang11g>select count(*) from t_wjq1;
COUNT(*)
----------
86997
--在表t_wjq1的object_id列上建立主鍵
SEIANG@seiang11g>alter table t_wjq1 add constraint pk_t_wjq1_id primary key(object_id);
Table altered.
SEIANG@seiang11g>
SEIANG@seiang11g>select index_name,index_type,table_owner,table_name from user_indexes;
INDEX_NAME INDEX_TYPE TABLE_OWNER TABLE_NAME
------------------------------ --------------------------- ------------------------------ ------------------------------
PK_T_WJQ1_ID NORMAL SEIANG T_WJQ1
需求:重定義的內容有以下幾個:
(1)使用object_id進行分割槽
(2)created欄位從date型別變為timestamp型別
(3)object_name欄位改名為object_name_2。
--建立一張中間表t_wjq1_interim
SEIANG@seiang11g>create table t_wjq1_interim(
2 object_id number,
3 object_name_2 varchar2(128),
4 created timestamp
5 )
6 partition by range(object_id)
7 (
8 partition p1 values less than (5000),
9 partition p2 values less than (10000),
10 partition p3 values less than (50000),
11 partition p4 values less than (maxvalue)
12 );
Table created.
--檢視中間表的分割槽情況
SEIANG@seiang11g>select table_name,partition_name from user_tab_partitions;
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
T_WJQ1_INTERIM P4
T_WJQ1_INTERIM P3
T_WJQ1_INTERIM P2
T_WJQ1_INTERIM P1
--首先,檢視t_wjq1表是否支援重定義操作
SEIANG@seiang11g>exec dbms_redefinition.can_redef_table('SEIANG','T_WJQ1',options_flag=>dbms_redefinition.cons_use_pk);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02
--開始重定義操作
SEIANG@seiang11g>exec dbms_redefinition.start_redef_table('SEIANG','T_WJQ1','T_WJQ1_INTERIM',col_mapping => 'object_id object_id, object_name object_name_2, to_timestamp(created) created',options_flag => dbms_redefinition.cons_use_pk);
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.42
注意這個col_mapping對映關係設定,如果存在列名轉換,就在這裡將列關係對映說明出來。如果需要進行欄位型別轉換,要書寫函式關係將對映計算規則定義出來。
Oracle線上重定義的基礎是物化檢視。此時,通過檢視試圖user_mviews,可以看到有一個新的物化檢視生成,並且存在對應的物化檢視日誌。
SEIANG@seiang11g>select mview_name, container_name, query, REFRESH_METHOD from user_mviews;
MVIEW_NAME CONTAINER_NAME QUERY REFRESH_
------------------------------ ------------------------------ -------------------------------------------------------------------------------- --------
T_WJQ1_INTERIM T_WJQ1_INTERIM select object_id object_id, object_name object_name_2, to_timestamp(created) cre FAST
Elapsed: 00:00:00.02
SEIANG@seiang11g>
SEIANG@seiang11g> select master,log_table from user_mview_logs;
MASTER LOG_TABLE
------------------------------ ------------------------------
T_WJQ1 MLOG$_T_WJQ1
Elapsed: 00:00:00.00
線上重定義的Start方法建立了一個Fast重新整理模式的物化檢視物件t_wjq1_interim。物化檢視中最重要的物化檢視日誌,名稱為MLOG$_T_WJQ1
--檢視原始表和中間表的資料量
SEIANG@seiang11g>select count(*) from t_wjq1;
COUNT(*)
----------
86997
Elapsed: 00:00:00.01
SEIANG@seiang11g>
SEIANG@seiang11g>select count(*) from t_wjq1_interim;
COUNT(*)
----------
86997
Elapsed: 00:00:00.01
--沒有DML操作,所以物化檢視日誌尚空
SEIANG@seiang11g>select * from mlog$_t_wjq1;
no rows selected
Elapsed: 00:00:00.00
SEIANG@seiang11g>select count(*) from mlog$_t_wjq1;
COUNT(*)
----------
0
Elapsed: 00:00:00.00
綜合上述內容,說明start_redef_table的作用是下面幾個方面:
(1)以Interim資料表為名稱,建立一個Fast重新整理模式的物化檢視物件;
(2)從源資料表中將資料載入到Interim中;
(3)建立物化檢視日誌;
如果在這個過程中,發生了DML操作,也就是說在start過程或者之後有DML操作,有新資料插入或修改,如下操作所示:
--檢視t_wjq1表的資料量和最大的object_id值
SEIANG@seiang11g>select count(*) from t_wjq1;
COUNT(*)
----------
86997
Elapsed: 00:00:00.00
SEIANG@seiang11g>select max(object_id) from t_wjq1;
MAX(OBJECT_ID)
--------------
89700
Elapsed: 00:00:00.01
--模擬DML操作:在表t_wjq1中插入資料庫
SEIANG@seiang11g>insert into t_wjq1 select object_id+90000,object_name,created from dba_objects;
87006 rows created.
Elapsed: 00:00:05.13
--再次檢視原始表t_wjq1、中間表t_wjq1_interim以及物化檢視日誌試圖的變化
SEIANG@seiang11g>select count(*) from t_wjq1;
COUNT(*)
----------
174003
Elapsed: 00:00:00.01
SEIANG@seiang11g>
SEIANG@seiang11g>select count(*) from t_wjq1_interim;
COUNT(*)
----------
86997
Elapsed: 00:00:00.00
SEIANG@seiang11g>select count(*) from mlog$_t_wjq1;
COUNT(*)
----------
87006
Elapsed: 00:00:00.01
發現:中間表的資料內容保持不變,並且物化檢視日誌積累了需要重新整理的資料條目。此時存在資料的不一致和不統一。Oracle推薦要求使用sysnc_interim_table方法將重定義過程中出現的變化資料重新整理。
--重新整理8萬多條資料,使用了超過四分鐘時間。在這個過程中,我們可以看到重新整理物化檢視過程。
SEIANG@seiang11g>exec dbms_redefinition.sync_interim_table('SEIANG','T_WJQ1','T_WJQ1_INTERIM');
PL/SQL procedure successfully completed.
Elapsed: 00:04:18.33
SEIANG@seiang11g>select * from v$mvrefresh;
SID SERIAL# CURRMVOWNER CURRMVNAME
---------- ---------- ------------------------------- -------------------------------
41 14059 SEIANG T_WJQ1_INTERIM
--重新整理開始和結束過程,我們可以看到物化檢視重新整理過程中的時間變化。
SEIANG@seiang11g>alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';
Session altered.
SEIANG@seiang11g>
SEIANG@seiang11g>select name, LAST_REFRESH from user_mview_refresh_times;
NAME LAST_REFRESH
------------------------------ -------------------
T_WJQ1_INTERIM 2017-09-06 13:59:57
SEIANG@seiang11g>select name, LAST_REFRESH from user_mview_refresh_times;
NAME LAST_REFRESH
------------------------------ -------------------
T_WJQ1_INTERIM 2017-09-06 14:22:20
--重新整理結束後,發現t_wjq1_interim表和mlog$_t_wjq1日誌表資料的變化
SEIANG@seiang11g>select count(*) from t_wjq1_interim;
COUNT(*)
----------
174003
SEIANG@seiang11g>
SEIANG@seiang11g>select count(*) from t_wjq1;
COUNT(*)
----------
174003
SEIANG@seiang11g>
SEIANG@seiang11g>select count(*) from mlog$_t_wjq1;
COUNT(*)
----------
0
說明無變化資料需要重新整理了
綜合上面的實驗,知道方法sync_interim_table的實質是進行一次物化檢視快速重新整理。這個方法持續的時間根據不同資料量和物化檢視重新整理演算法來決定,這個過程中,並不會引起很多鎖定動作。而且,線上重定義過程中,這個方法是可以重複執行多次的。
--下面將原有資料表中的約束關係重新整理到目標結構上
SEIANG@seiang11g>declare
2 error_count number:=0;
3 begin
4 dbms_redefinition.copy_table_dependents(uname => 'SEIANG',orig_table => 'T_WJQ1',int_table => 'T_WJQ1_INTERIM',
5 copy_indexes => dbms_redefinition.cons_orig_params,
6 num_errors => error_count);
7 dbms_output.put_line(to_char(error_count));
8 end;
9 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:05.29
SEIANG@seiang11g>select index_name,index_type,table_owner,table_name from user_indexes;
INDEX_NAME INDEX_TYPE TABLE_OWNER TABLE_NAME
------------------------------ --------------------------- ------------------------------ ------------------------------
TMP$$_PK_T_WJQ1_ID0 NORMAL SEIANG T_WJQ1_INTERIM
PK_T_WJQ1_ID NORMAL SEIANG T_WJQ1
I_MLOG$_T_WJQ1 NORMAL SEIANG MLOG$_T_WJQ1
Elapsed: 00:00:00.04
SEIANG@seiang11g>select master,log_table from user_mview_logs;
MASTER LOG_TABLE
------------------------------ ------------------------------
T_WJQ1 MLOG$_T_WJQ1
Finish過程主要完成六個步驟操作:
(1)執行sysnc_interim_table命令,將中間表資料儘可能靠近源資料表;
(2)鎖定源資料表T,使之後不能有任何變化發生在這個資料表上;
(3)再次執行sysnc_interim_table命令,這個時候執行的時間不會很長;
(4)將源資料表和Interim資料表表名進行置換;
(5)登出unregistered物化檢視,並且刪除掉物化檢視日誌;
(6)釋放開在中間表上的鎖定;
SEIANG@seiang11g> exec dbms_redefinition.finish_redef_table('SEIANG','T_WJQ1','T_WJQ1_INTERIM');
PL/SQL procedure successfully completed.
Elapsed: 00:00:02.11
SEIANG@seiang11g>select master,log_table from user_mview_logs;
no rows selected
Elapsed: 00:00:00.02
SEIANG@seiang11g>
SEIANG@seiang11g>select * from mlog$_t_wjq1;
select * from mlog$_t_wjq1
*
ERROR at line 1:
ORA-00942: table or view does not exist
SEIANG@seiang11g>select index_name,index_type,table_owner,table_name from user_indexes;
INDEX_NAME INDEX_TYPE TABLE_OWNER TABLE_NAME
------------------------------ --------------------------- ------------------------------ ------------------------------
TMP$$_PK_T_WJQ1_ID0 NORMAL SEIANG T_WJQ1_INTERIM
PK_T_WJQ1_ID NORMAL SEIANG T_WJQ1
--檢查重定義的結果
SEIANG@seiang11g>desc t_wjq1
Name Null? Type
----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
OBJECT_ID NUMBER
OBJECT_NAME_2 VARCHAR2(128)
CREATED TIMESTAMP(6)
SEIANG@seiang11g>
SEIANG@seiang11g>desc t_wjq1_interim
Name Null? Type
----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
OBJECT_ID NOT NULL NUMBER
OBJECT_NAME VARCHAR2(128)
CREATED DATE
SEIANG@seiang11g> exec dbms_stats.gather_table_stats(user,'T_WJQ1',cascade => true);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.76
--分割槽和主鍵物件實現成功
SEIANG@seiang11g>select table_name,partition_name from user_tab_partitions;
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
T_WJQ1 P1
T_WJQ1 P2
T_WJQ1 P3
T_WJQ1 P4
SEIANG@seiang11g>select constraint_name,constraint_type,table_name from user_constraints;
CONSTRAINT_NAME C TABLE_NAME
------------------------------ - ------------------------------
TMP$$_PK_T_WJQ1_ID0 P T_WJQ1_INTERIM
PK_T_WJQ1_ID P T_WJQ1
之前的實驗都是在單表情況下進行的線上重定義操作,但是,在實際的生產環境中,通常涉及到多表關係,例如外來鍵關係表下的重定義,那有該如何處理呢?接下來的案例,作者將介紹多表關係下的線上重定義。
作者:SEian.G(苦練七十二變,笑對八十一難)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31015730/viewspace-2144603/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 指令碼:線上重定義,從普通表到分割槽表,redefinition_table.sh指令碼
- 線上重定義與普通表改為分割槽表
- 在oracle 9i下線上重定義表Oracle
- 線上重定義方式將普通表修改為分割槽表
- 壓縮錶轉非壓縮表(線上重定義)
- SharePoint Online 自定義Modern UI表單UI
- 線上重定義的操作步驟__普通錶轉換為分割槽表的實驗案例
- jFinal避免表單重複提交
- PHP 防止表單重複提交PHP
- java 表單避免重複提交?Java
- dolphinscheduler簡單任務定義及複雜的跨節點傳參
- Spring MVC表單防重複提交SpringMVC
- 如何避免表單的重複提交?
- 萬智牌設計雜談:重複利用(上)
- Struts2防止表單重複提交
- 展示BPMN複雜流程的案例
- PHP防止使用者重複提交表單PHP
- XML Schema 複雜元素型別詳解:定義及示例解析XML型別
- MySQL Online DDL導致全域性鎖表案例分析MySql
- oracle表複雜查詢Oracle
- 線性表 & 雜湊表
- Flowable 6.6.0 BPMN使用者指南 -9 表單 - 9.1 表單定義
- Django實踐(二)——使用模型類定義資料表,實現表單頁面跳轉Django模型
- 如何防止使用者重複提交訂單?(上)
- 中國式複雜報表真的有必要存在?如何解決複雜報表
- 十二、雜湊表(二)
- C++ 定義靜態成員 static 關鍵字不能在定義出重複出現C++
- vue+elementUI 複雜表單的驗證、資料提交方案VueUI
- 面向複雜場景的高效能表單解決方案
- MySQL 5.6使用pt-online-schema-change線上修改大表欄位長度MySql
- 10月21日線上研討會 | 軟體定義汽車下的產品線複用管理
- 聯機重定義表在10g的改進
- extern 用法,全域性變數與標頭檔案(重複定義)變數
- C++17 連結 C++11 lib 出現重複定義C++
- 複雜二進位制資料
- 複製錯誤案例分享(二)
- “田由甲” - Kafka重複消費線上問題暴雷Kafka
- 複雜報表設計之動態報表
- 複製貼上Ctrl+C改為自定義單鍵