12CR2 “alter table move”命令導致資料損壞?
在對具有以下特徵的表發出“alter table move”命令時,會發生資料損壞的情況:
1、該表包含使用者定義的型別,該型別宣告為NOT INSTANTIABLE和NOT FINAL。
2、至少有三個類繼承自此使用者定義的型別。
示例如下:
1.建立type
首先建立基本的type。必須是NOT INSTANTIABLE NOT FINAL型別的.
CREATE OR REPLACE TYPE ty_parent AS OBJECT( n1_parent NUMBER ) NOT INSTANTIABLE NOT FINAL ;
2.三個類繼承自此使用者定義的型別。
CREATE OR REPLACE TYPE ty_child_1 UNDER ty_parent( VALUE varchar2(300) ) FINAL ; CREATE OR REPLACE TYPE ty_child_2 UNDER ty_parent( VALUE TIMESTAMP ) FINAL ; CREATE OR REPLACE TYPE ty_child_3 UNDER ty_parent( VALUE number ) FINAL ;
3.建立表,宣告為ty_parent型別
create table t1 (ty1 ty_parent , n1 number) ;
4.插入資料
insert into t1 values ( ty_child_1( 1, 'AAAAAAAAAAAAAAAA' ) , 1 ) ; commit;
5.DUMP定義類中的資料,這裡可以看到因為插入的是字元型別,儲存在ty_child_1當中
SQL> select 2 dump(TREAT(ty1 AS ty_child_1).VALUE,16), 3 dump(TREAT(ty1 AS ty_child_2).VALUE,16), 4 dump(TREAT(ty1 AS ty_child_3).VALUE,16) 5 from t1 ; DUMP(TREAT(TY1ASTY_CHILD_1).VALUE,16) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- DUMP(TREAT(TY1ASTY_CHILD_2).VALUE,16) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- DUMP(TREAT(TY1ASTY_CHILD_3).VALUE,16) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Typ=1 Len=16: 41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41 NULL NULL
6.使用alter table move移動表
SQL> alter table t1 move; Table altered.
7.再次DUMP定義類中的資料,這裡可以看到資料移動到了ty_child_2當中。即使兩列都有不同的資料型別。ty_child_1是字元型,ty_child_2是時間型別。
SQL> select 2 dump(TREAT(ty1 AS ty_child_1).VALUE,16), 3 dump(TREAT(ty1 AS ty_child_2).VALUE,16), 4 dump(TREAT(ty1 AS ty_child_3).VALUE,16) 5 from t1 ; DUMP(TREAT(TY1ASTY_CHILD_1).VALUE,16) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- DUMP(TREAT(TY1ASTY_CHILD_2).VALUE,16) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- DUMP(TREAT(TY1ASTY_CHILD_3).VALUE,16) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- NULL Typ=180 Len=16: 41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41 NULL
8.在此之後,執行雜湊連線時出現以下ORA-00600錯誤:
create table t2 (n1 number) ; insert into t2 values (1) ; commit ; SQL> select t1.* from t1,t2 where t1.n1 = t2.n1 ; select t1.* from t1,t2 where t1.n1 = t2.n1 * ERROR at line 1: ORA-00600: internal error code, arguments: [rworupo.1], [16], [11], [], [], [], [], [], [], [], [], []
9.執行ctas重建表,報ORA-12899錯誤
SQL> create table t3 as select * from t1; create table t3 as select * from t1 * ERROR at line 1: ORA-12899: value too large for column ??? (actual: 16, maximum: 11)
建議:
12cR2在執行alter table move操作之前,執行下列sql語句檢查,以下查詢出來的表是不能進行move操作的。
SQL> select c.owner, c.table_name, 2 substr(qualified_col_name,1,instr(qualified_col_name,'"',1,2)) parent_type 3 from dba_tab_cols c, dba_tables t 4 where hidden_column = 'YES' and virtual_column='NO' 5 and t.owner = c.owner and t.table_name = c.table_name 6 and tablespace_name is not null 7 and qualified_col_name like 'TREAT(%' 8 group by c.owner,c.table_name, 9 substr(qualified_col_name,1,instr(qualified_col_name,'"',1,2)) 10 having count(*) > 2 ; OWNER TABLE_NAME PARENT_TYPE ------------------------------ ------------------------------ ------------------------------ SYS AQ$_KUPC$DATAPUMP_QUETAB_1_P TREAT("USER_DATA" SYS KUPC$DATAPUMP_QUETAB_1 TREAT("USER_DATA" SYS T1 TREAT("TY1" SYS KUPC$DATAPUMP_QUETAB TREAT("USER_DATA"
經過測試資料使用expdp和exp是可以把資料匯出來的
[oracle@ol6 ~]$ expdp system/oracle dumpfile=a.dmp DIRECTORY=ORACLE_HOME tables=t1; Export: Release 12.2.0.1.0 - Production on Wed Sep 26 17:27:11 2018 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production Warning: Oracle Data Pump operations are not typically needed when connected to the root or seed of a container database. Starting "SYSTEM"."SYS_EXPORT_TABLE_01": system/******** dumpfile=a.dmp DIRECTORY=ORACLE_HOME tables=t1 Processing object type TABLE_EXPORT/TABLE/TABLE_DATA Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER Processing object type TABLE_EXPORT/TABLE/TABLE . . exported "SYSTEM"."T1" 9.445 KB 1 rows Master table "SYSTEM"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded ****************************************************************************** Dump file set for SYSTEM.SYS_EXPORT_TABLE_01 is: /u01/app/oracle/product/12.2.0.1/db_1/a.dmp Job "SYSTEM"."SYS_EXPORT_TABLE_01" successfully completed at Wed Sep 26 17:27:41 2018 elapsed 0 00:00:30 [oracle@ol6 ~]$ exp system/oracle tables=t1; Export: Release 12.2.0.1.0 - Production on Wed Sep 26 17:24:30 2018 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. EXP-00056: ORACLE error 28002 encountered ORA-28002: the password will expire within 7 days Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production Export done in US7ASCII character set and AL16UTF16 NCHAR character set server uses AL32UTF8 character set (possible charset conversion) About to export specified tables via Conventional Path ... . . exporting table T1 1 rows exported Export terminated successfully without warnings.
目前在MOS上查不到該問題相關的Bug。建議做move前先執行SQL檢查。
參考文件:https://nenadnoveljic.com/blog/corruption-alter-table-move-oracle-12-2/