1. 監視表在線重定義進度
可以查詢V$ONLINE_REDEF
視圖以監視聯機表重定義操作的進度。
select * from V$ONLINE_REDEF;
該V$ONLINE_REDEF
視圖爲該PROGRESS
列中的操作提供了百分比完成值。該視圖在該OPERATION
列中顯示完成該操作所需的步驟總數。例如,如果操作中有10個步驟,則此列可能顯示Step 6 out of 10
。該視圖還包括SUBOPERATION
列和DETAILED_MESSAGE
列,用用於提供有關當前操作的更詳細的信息。
2. 失敗後重新啓動表在線重新定義
如果聯機表重新定義失敗,則可以完成以下步驟來重新啓動它:
- 查詢
DBA_REDEFINITION_STATUS
視圖以確定故障原因以及糾正該故障所需的操作。例如,運行以下查詢:SELECT BASE_TABLE_NAME, INTERIM_OBJECT_NAME, OPERATION, STATUS, RESTARTABLE, ACTION FROM DBA_REDEFINITION_STATUS;
如果RESTARTABLE
值爲Y
,則可以重新開始操作。如果RESTARTABLE
值爲N
,則無法重新開始操作,必須從頭開始重新定義。 - 執行上一步查詢結果中指定的操作。
- 使用查詢結果中指定的操作重新啓動聯機重新定義,然後運行所有後續操作以完成表的聯機重新定義。
示例-- SYNC_INTERIM_TABLE過程調用失敗
SYNC_INTERIM_TABLE
過程調用中失敗,並出現以下錯誤:
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE('U1', 'ORIG', 'INT');
END;
/
ORA-42009: error occurred while synchronizing the redefinition
ORA-01653: unable to extend table U1.INT by 8 in tablespace my_tbs
ORA-06512: at "SYS.DBMS_REDEFINITION", line 148
ORA-06512: at "SYS.DBMS_REDEFINITION", line 2807
ORA-06512: at line 2
-
查詢
DBA_REDEFINITION_STATUS
視圖:SELECT BASE_TABLE_NAME, INT_TABLE_NAME, OPERATION, STATUS, RESTARTABLE, ACTION FROM DBA_REDEFINITION_STATUS; BASE_TABLE_NAME INT_OBJ_NAME OPERATION STATUS RESTARTABLE ACTION --------------- ------------ ------------------ ------- ----------- --------- ORIG INT SYNC_INTERIM_TABLE FAILED Y Fix error
因爲查詢結果
RESTARTABLE
是Y,
在線重定義操作可以重新開始。要重新啓動操作,請更正操作失敗時返回的錯誤,然後重新啓動操作。在此示例中,錯誤爲“ ORA-01653: unable to extend table U1.INT by 8 in tablespace my_tbs”。 -
通過向表空間my_tbs添加數據文件來增加表空間的大小:
ALTER TABLESPACE my_tbs ADD DATAFILE '/u02/oracle/data/my_tbs2.dbf' SIZE 100M;
-
重新運行
SYNC_INTERIM_TABLE
過程調用:BEGIN DBMS_REDEFINITION.SYNC_INTERIM_TABLE('U1', 'ORIG', 'INT'); END; /
示例--物化視圖日誌問題
在原始表上開始重新定義之後,物化視圖日誌可能會出現問題。例如,由於某些原因,物化視圖日誌可能被意外刪除或損壞。在這種情況下,將返回類似於以下內容的錯誤:
ERROR at line 1:
ORA-42010: error occurred while synchronizing the redefinition
ORA-12034: materialized view log on "HR"."T1" younger than last refresh
假設正在重新定義使用以下SQL語句創建的表:
CREATE TABLE hr.t1(
c1 NUMBER PRIMARY KEY,
c2 NUMBER)
TABLESPACE example_tbs;
假設使用以下SQL語句創建了一個臨時表,該語句更改了表的表空間:
CREATE TABLE hr.int_t1(
c1 NUMBER PRIMARY KEY,
c2 NUMBER)
TABLESPACE hr_tbs;
-
-
開始重新定義過程。
BEGIN DBMS_REDEFINITION.START_REDEF_TABLE( uname =>'hr', orig_table =>'t1', int_table =>'int_t1'); end; /
-
Drop the materialized view log on the original table。
DROP MATERIALIZED VIEW LOG ON hr.t1;
-
Create a new materialized view log on the original table.
CREATE MATERIALIZED VIEW LOG ON hr.t1 WITH COMMIT SCN PURGE IMMEDIATE ASYNCHRONOUS;
-
Synchronize the interim table
hr.int_t1
.BEGIN DBMS_REDEFINITION.SYNC_INTERIM_TABLE( uname => 'hr', orig_table => 't1', int_table => 'int_t1'); END; / BEGIN * ERROR at line 1: ORA-42010: error occurred while synchronizing the redefinition ORA-12034: materialized view log on "HR"."T1" younger than last refresh
-
由於返回了錯誤,請檢查
DBA_REDEFINITION_STATUS
視圖。COLUMN BASE_OBJECT_NAME FORMAT A11 COLUMN OPERATION FORMAT A10 COLUMN STATUS FORMAT A10 COLUMN RESTARTABLE FORMAT A11 COLUMN ERR_TXT FORMAT A15 COLUMN ACTION FORMAT A18 SELECT BASE_OBJECT_NAME, OPERATION, STATUS, RESTARTABLE, ERR_TXT, ACTION FROM DBA_REDEFINITION_STATUS ORDER BY BASE_TABLE_NAME, BASE_OBJECT_NAME; BASE_OBJECT OPERATION STATUS RESTARTABLE ERR_TXT ACTION ----------- ---------- ---------- ----------- --------------- ------------------ T1 SYNC_REDEF Failure N ORA-12034: mate Abort redefinition _TABLE rialized view l og on "HR"."T1" younger than l ast refresh
由於查詢結果中存在聯機重新定義操作,因此無法重新啓動
RESTARTABLE
它N
,並且該ACTION
列指示必須放棄聯機表重新定義操作。 -
Abort the online table redefinition operation
BEGIN DBMS_REDEFINITION.ABORT_REDEF_TABLE( uname => 'hr', orig_table => 't1', int_table => 'int_t1'); END; /
3. 表在線重定義回滾
1. 關於回滾表在線重定義
在線重定義表之後,可以將表回滾到其在線重定義之前,同時保留對錶所做的所有數據操作語言(DML)更改。
在某些情況下,您可能需要撤消在線重定義表的操作。例如,重定義之後,表上的操作性能可能比重定義之前要差。在這些情況下,你可以將表回滾到其原始定義,同時保留重定義表後對該表所做的所有DML更改。表在線重定義回滾主要用於重定義更改表的存儲特性,並且更改意外導致性能降低的情況。
要啓用表在線重定義的回滾,必須在DBMS_REDEFINITION.START_TABLE_REDEF
過程中將ENABLE_ROLLBACK
參數設置爲TRUE。如果將此參數設置爲true,則Oracle數據庫將在重定義完成後維護在重定義期間創建的臨時表。您可以運行該SYNC_INTERIM_TABLE
過程以定期同步臨時表,以便將對重定義的表所做的DML更改應用於臨時表。內部的物化視圖和物化視圖日誌可以維護臨時表。如果您決定回滾表在線重定義,則會同步臨時表,並且Oracle數據庫將切換回該表,以便該表具有其原始定義。
以下限制適用於表在線重定義回滾:
當原始表的列到臨時表的列沒有一對一映射時,在重定義期間列映射中不能有運算符或函數。
當原始表的列到臨時表的列有一對一的映射時,列映射中可以有運算符和函數。
當爲重定義啓用回滾時,在回滾或中止在表在線重定義之前,不能再次重定義該表。
2. 執行表在線重定義回滾
DBMS_REDEFINITION包中的ROLLBACK過程返回一個在保留DML更改的同時在線重新定義爲其原始定義的表。
要使用此ROLLBACK過程,必須在表在線重定義期間啓用表在線重定義回滾。如果決定保留表在線重定義所做的更改,則可以運行ABORT_ROLLBACK過程。
- 執行表在線重定義,從
START_REDEF_TABLE
過程開始,到FINISH_REDEF_TABLE完成過程結束。
在START_REDEF_TABLE
過程ENABLE_ROLLBACK
參數必須設置爲TRUE
。此參數的默認值爲FALSE
。 - 可選:定期運行該
SYNC_INTERIM_TABLE
過程,以便將對重定義的表進行的DML更改應用於臨時表。如果定期將DML更改應用到臨時表,則可以提高表在線重定義回滾的性能。 - 選擇以下選項之一:
- 如果要回滾表重新定義所做的更改並返回到原始表定義,請在
DBMS_REDEFINITION
包中運行ROLLBACK過程。 - 如果要保留表在線重定義所做的更改,請在
DBMS_REDEFINITION
包運行ABORT_ROLLBACK
程序。中止rollback將停止維護臨時表,並刪除啓用回滾的實例化視圖和實例化日誌。
- 如果要回滾表重新定義所做的更改並返回到原始表定義,請在
示例--回滾表在線重定義
本示例說明了通過更改表的存儲特徵來在線重新定義表。具體而言,此示例在表在線重新定義期間壓縮表的表空間。假設您要在完成在線重新定義後評估表的性能。如果表的性能不及預期,那麼您希望能夠回滾在線重新定義所做的更改。
Assume that the following statements created the original tablespace and table:
CREATE TABLESPACE tst_rollback_tbs
DATAFILE 'tst_rollback_tbs.dbf' SIZE 10M
ONLINE;
CREATE TABLE hr.tst_rollback
(rllbck_id NUMBER(6) PRIMARY KEY,
rllbck_name VARCHAR2(20))
TABLESPACE tst_rollback_tbs
STORAGE (INITIAL 2M);
-
In SQL*Plus, connect as a user with the required privileges for performing online redefinition of a table.
Specifically, the user must have the privileges described in "Privileges Required for the DBMS_REDEFINITION Package".
-
Create a compressed tablespace for the interim table.
CREATE TABLESPACE tst_cmp_rollback_tbs DEFAULT ROW STORE COMPRESS ADVANCED DATAFILE 'tst_cmp_rollback_tbs.dbf' SIZE 10M ONLINE;
-
Create an interim table
hr.int_tst_rollback
.CREATE TABLE hr.int_tst_rollback (rllbck_id NUMBER(6) PRIMARY KEY, rllbck_name VARCHAR2(20)) TABLESPACE tst_cmp_rollback_tbs STORAGE (INITIAL 2M);
Ensure that the interim table uses the compressed tablespace created in the previous step.
-
Start the redefinition process.
BEGIN DBMS_REDEFINITION.START_REDEF_TABLE( uname => 'hr', orig_table => 'tst_rollback', int_table => 'int_tst_rollback', options_flag => DBMS_REDEFINITION.CONS_USE_PK, enable_rollback => TRUE); END; /
Ensure that
enable_rollback
is set toTRUE
so that the changes made by online redefinition can be rolled back. -
Copy dependent objects.
DECLARE num_errors PLS_INTEGER; BEGIN DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS( uname => 'hr', orig_table => 'tst_rollback', int_table => 'int_tst_rollback', copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS, copy_triggers => TRUE, copy_constraints => TRUE, copy_privileges => TRUE, ignore_errors => TRUE, num_errors => num_errors); END; /
-
Query the
DBA_REDEFINITION_ERRORS
view to check for errors.SET LONG 8000 SET PAGES 8000 COLUMN OBJECT_NAME HEADING 'Object Name' FORMAT A20 COLUMN BASE_TABLE_NAME HEADING 'Base Table Name' FORMAT A10 COLUMN DDL_TXT HEADING 'DDL That Caused Error' FORMAT A40 SELECT OBJECT_NAME, BASE_TABLE_NAME, DDL_TXT FROM DBA_REDEFINITION_ERRORS;
You can ignore errors related to the primary key and indexes.
-
Synchronize the interim table
hr.int_tst_rollback
.BEGIN DBMS_REDEFINITION.SYNC_INTERIM_TABLE( uname => 'hr', orig_table => 'tst_rollback', int_table => 'int_tst_rollback'); END; /
-
Complete the redefinition.
BEGIN DBMS_REDEFINITION.FINISH_REDEF_TABLE( uname => 'hr', orig_table => 'tst_rollback', int_table => 'int_tst_rollback'); END; /
The table
hr.tst_rollbck
is locked in the exclusive mode only for a small window toward the end of this step. After this call the tablehr.tst_rollback
is redefined such that it has all the attributes of thehr.int_tst_rollback
table. In this example, the tablespace for thehr.tst_rollbck
table is now compressed. -
During the evaluation period, you can periodically synchronize the interim table
hr.int_tst_rollback
.BEGIN DBMS_REDEFINITION.SYNC_INTERIM_TABLE( uname => 'hr', orig_table => 'tst_rollback', int_table => 'int_tst_rollback'); END; /
Synchronizing the tables updates the original table with the DML changes made to the redefined table. When you synchronize the tables periodically, a rollback operation is more efficient because fewer DML changes must be made to the original table. You can query the
STATUS
column of theDBA_REDEFINITION_STATUS
view to determine the status of the rollback operation. -
Perform one of the following actions:
- Assume that the redefined table did not perform as well as expected, and roll back the changes made by online redefinition.
BEGIN DBMS_REDEFINITION.ROLLBACK( uname => 'hr', orig_table => 'tst_rollback', int_table => 'int_tst_rollback'); END; /
- Assume that the redefined table performed as expected, and abort the rollback to retain the changes made by online table redefinition and clean up the database objects that enable rollback.
BEGIN DBMS_REDEFINITION.ABORT_ROLLBACK( uname => 'hr', orig_table => 'tst_rollback', int_table => 'int_tst_rollback'); END; /
- Assume that the redefined table did not perform as well as expected, and roll back the changes made by online redefinition.