1. 程式人生 > >LOB對象在數據泵導出、導入後查詢對象數量發現丟失

LOB對象在數據泵導出、導入後查詢對象數量發現丟失

用戶信息 cascade 發現 有效 字段類型 都是 cycle HERE 去除

問題描述:
問題:源庫的某個Schema使用數據泵Expdp元數據整體導出,在目標庫導入且成功後,邏輯驗證用戶對象,發現缺失。分析查詢後,缺失的對象,都是LOB類型(並不是所有的LOB都無法導入,是大部分LOB類型的對象)

#以下邏輯驗證,SQL執行,對比源庫、目標庫數據
#以下語句特點:測試環境,還原狀況模擬:數據無法完全重現 SQL
> select OBJECT_TYPE,count(*) from dba_objects where owner=SCOTT group by object_type OBJECT_TYPE COUNT(*) ------------------- ---------- SEQUENCE
1 TABLE PARTITION 2 LOB 1 TABLE 14 INDEX 7


#通過上述操作對比:發現LOB對象,少了100多個,但是有的LOB字段卻能導入

疑問? 什麽樣的情況下LOB會缺失?

是EXPDP根本不導出,還是導入報錯,不創建?


診斷思路: 沒有什麽好的方法:直接查詢MOS

LOB EXPORT

LOB OBJECTS APPEAR TO BE LOST AFTER THE Export/import PROCESSES 

ID 
1595391.1

MOS信息截取:

適用於:

Oracle數據庫 - 企業版 - 版本11.2.0.1至12.1.0.1 [版本11.2至12.1] 
本文檔中的信息適用於任何平臺

導出/導入後,許多LOB對象似乎丟失。

select object_type, count(*)
from obj
group by object_type
order by object_type;

OBJECT_TYPE COUNT(*)
-------------------------------
LOB                   676

SQL> select object_type, count(*)
from obj
group by object_type
order by object_type;

OBJECT_TYPE COUNT(*)
------------------- ----------
LOB                     429

在導出/導入過程中,有247個LOB對象丟失,但導入沒有報告任何類型的錯誤。



drop table lob; 


在這種情況下,因為有些對象已被丟棄,但仍處於回收站中。

需要清除recyclebin以從obj中刪除這些條目,或者使用user_lobs而不是執行查詢。

問題解決:

#驗證:使用查詢即可:查詢回收站中,LOB類型的對象數量,驗證是否導入缺失的LOB數量對比
select type,count(*) from dba_recyclebin where owner=SCOTT and type=LOB group by type

TYPE                        COUNT(*)
------------------------- ----------
LOB                                2  

#本次導入後,對象數量對比,通過上述SQL查詢,正好匹配:視圖dba_objects中,object_type=LOB類型的對象缺失數量=   dba_recyclebin中的查詢數量

有什麽好的方式可以減少這種現象:

#查詢回收站
SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
ID               BIN$aO6HsIdlTr3gU4AUqMDssg==$0 TABLE        2018-04-03:17:51:14
ID               BIN$aO6HsIdkTr3gU4AUqMDssg==$0 TABLE       2018-04-03:17:35:05

#清空回收站
SQL> purge recyclebin;
Recyclebin purged.


#小結:   在執行數據泵導出前,清空回收站
SQL> select type,count(*) from dba_recyclebin where owner=SCOTT and type=LOB group by type;

no rows selected

問題總結:其實這不是故障,而是一種特性:

我們通過obj視圖去驗證數量,Oracle數據庫drop table xx(no purge)(no clear recyclebin)( and exists LOB column )時,LOB字段在視圖obj中,status狀態還是vaild, 也就是說:drop table 操作後的LOB對象類型,在視圖中存在,但是Export數據泵不導出,因此統計對比發生誤差;

如果導入數據後,對比對象數量:繼續使用dba_objects中 object_type統計LOB字段對比:可以事先查詢:源庫回收站中的LOB類型數量,統計減去OK; 或者清空源庫回收站,避免回收站內的LOB字段造成,統計幹擾

在user_lobs視圖統計用戶下的LOB數量更為準確

#如下測試:

2流程: 2.1源庫中,SCOTT用戶創建一個LOB字段的表:查詢信息 2.2源庫中,將使用數據泵導出SCOTT整個用戶、導入成功後再次查詢,對比 2.3源庫中,源表drop table xx(不加purge),信息存放在回收站,查詢此特點 2.4源庫中,將源庫中的drop table後的整個schema導出,導入目標庫,查詢對比 2.5 測試,使用drop table xx purge;是否可以將LOB字段的表drop,級聯刪除LOB字段對象 2.6使用一條SQL語句,查詢出回收站內LOB類型的對象數量,用於驗證 2.7反向:知道這個特點,有什麽用 2流程: 2.1源庫中,SCOTT用戶創建一個LOB字段的表:查詢信息 2.2源庫中,將使用數據泵導出SCOTT整個用戶、導入成功後再次查詢,對比 2.3源庫中,源表drop table xx(不加purge),信息存放在回收站,查詢此特點 2.4源庫中,將源庫中的drop table後的整個schema導出,導入目標庫,查詢對比 2.5 測試,使用drop table xx purge;是否可以將LOB字段的表drop,級聯刪除LOB字段對象 2.6使用一條SQL語句,查詢出回收站內LOB類型的對象數量,用於驗證 2.7 有什麽可以避免,或者說更好的準備方法 2.1.0源庫中,SCOTT用戶下,創建一個LOB字段的表
2.1創建測試表(包含LOB字段):

SQL> create table loba(id int,name clob) tablespace users;

 

2.1.2 查詢用戶信息:發現創建一個LOB字段的表:自動創建SYS命名的LOB index and LOB segments

SQL> select object_name,object_type,status from user_objects;

OBJECT_NAME                           OBJECT_TYPE         STATUS

--------------------------------------------------------------------------------

LOBA                                      TABLE               VALID

SYS_IL0000089677C00002$$                  INDEX               VALID

SYS_LOB0000089677C00002$$                 LOB                 VALID

 

2.1.3查詢視圖:用戶下LOB字段的相關信息

SQL> select TABLE_NAME,COLUMN_NAME,SEGMENT_NAME,TABLESPACE_NAME,INDEX_NAME from user_lobs;

TABLE    COLUMN      SEGMENT                  TABLESPACE_NAME    INDEX_NAME

------------------------------ ------------------------------

LOBA    NAME  SYS_LOB0000089677C00002$$   USERS   SYS_IL0000089677C00002$$

 

2.1.4查詢用戶下的對象信息

SQL> select OBJECT_NAME,STATUS,object_id from user_objects;

SYS_IL0000089677C00002$$            VALID        89679

SYS_LOB0000089677C00002$$           VALID        89678

LOBA                                VALID        89677

 

2.2將源庫中數據泵導出SCOTT整個用戶、導入目標庫SONG用戶成功後再次查詢,對比
2.2.1導出:
expdp  \/ as sysdba\‘ DIRECTORY=yang logfile=scott.log DUMPFILE=scott.dmp schemas=scott CONTENT=METADATA_ONLY 

2.2.2dump文件傳輸
$ scp scott* 192.168.20.67:/home/oracle/.

2.2.3導入:
impdp \/ as sysdba\‘ directory=yang dumpfile=scott.dmp remap_schema=scott:song remap_tablespace=users:abc

2.2.4查詢對比:
#對比發現:導入的表是新建的,JOB段也是新建,命名規則中使用了表的OBJECT_ID,因此導入的表,對象除了表明相同,JOB字段、索引都不同
select OBJECT_NAME,STATUS,object_id from user_objects;
OBJECT_NAME                        STATUS   OBJECT_ID
----------------------------------- ------- ----------
LOBA                             VALID        15471
SYS_IL0000015471C00002$$         VALID        15473
SYS_LOB0000015471C00002$$        VALID        15472

2.3源庫中,源表drop table xx(不加purge),信息存放在回收站,查詢此特點
#查詢對象類型,對象數量

SQL> select count(*),status,OBJECT_TYPE from user_objects group by status,object_type;
 COUNT(*) STATUS  OBJECT_TYPE
---------- ------- -------------------
         2 VALID   TABLE PARTITION
        14 VALID   TABLE
         1 VALID   SEQUENCE
         7 VALID   INDEX
         1 VALID   LOB

#源庫drop LOB字段的測試表

SQL> drop table loba;

#從用戶對象角度上,查詢得到:LOB字段的表,drop 刪除後,TABLE AND INDEX都刪除了,LOB段保留且有效

SQL> select count(*),status,OBJECT_TYPE from user_objects group by status,object_type;
  COUNT(*) STATUS  OBJECT_TYPE
---------- ------- -------------------
         2 VALID   TABLE PARTITION
        13 VALID   TABLE
         1 VALID   SEQUENCE
         6 VALID   INDEX
         1 VALID   LOB
 
#查詢用戶下的LOB段
SQL> select object_name,OBJECT_TYPE,status from user_objects where object_type=LOB;
OBJECT_NAME                         OBJECT_TYPE         STATUS
----------------------------------- ------------------- -------
SYS_LOB0000089677C00002$$           LOB                 VALID

 
SQL> select * from cat;
BIN$aO6HsIdjTr3gU4AUqMDssg==$0 TABLE

#查詢用戶下的LOBS相關信息:
select TABLE_NAME,COLUMN_NAME,SEGMENT_NAME,TABLESPACE_NAME,INDEX_NAME from user_lobs;
NULL


2.4查詢數據泵是否導出應用源庫中drop table後,繼續存在的lob段對象
源庫導出:
expdp  \‘/ as sysdba\‘ DIRECTORY=yang logfile=scott02.log DUMPFILE=scott02.dmp schemas=‘scott‘ CONTENT=METADATA_ONLY 

dump文件傳輸
$ scp scott* 192.168.20.67:/home/oracle/.

目標庫:創建測試用戶,授予權限
SQL> drop user song cascade;
SQL> create user song identified by song default tablespace abc;
SQL> grant connect,resource to song;
SQL> grant read,write on directory yang to song;


目標庫導入:
impdp \‘/ as sysdba\‘ directory=yang dumpfile=scott02.dmp remap_schema=scott:song remap_tablespace=users:abc

 
導入成功後:驗證
#源庫:
SQL> select count(*) from user_objects;
----------
        15

 
#源庫查詢:對象類型:
  COUNT(*) STATUS  OBJECT_TYPE
---------- ------- -------------------
         2 VALID   TABLE PARTITION
         9 VALID   TABLE
         1 VALID   SEQUENCE
         2 VALID   INDEX
         1 VALID   LOB

#目標庫
SQL> select count(*) from user_objects;
----------
        14


#目標庫查詢:對象類型:
SQL> select count(*),status,OBJECT_TYPE from user_objects group by status,object_type;
  COUNT(*) STATUS  OBJECT_TYPE
---------- ------- ------------------- 2 VALID TABLE PARTITION 9 VALID TABLE 1 VALID SEQUENCE 2 VALID INDEX #目標庫查詢:當前用戶下LOB字段視圖查詢: SQL> select TABLE_NAME,COLUMN_NAME,SEGMENT_NAME,TABLESPACE_NAME,INDEX_NAME from user_lobs; no rows selected #目標庫查詢:源端回收站的表:不導出 SQL> select object_name,object_type,status from user_objects where object_name=‘LOBA‘; no rows selected
#目標庫查詢: SQL> select index_name,status from user_indexes where table_name=‘LOBA‘; no rows selected

#小結:源庫中包含LOB字段的表,drop刪除操作,LOB對象繼續存在,數據泵對象導出導入後,驗證對象數量,可以去除此幹擾信息: 2.5DROP TABLE xx purge (表中包含LOB字段類型,系統自動創建的段,是否也會被刪除,還是繼續存在)
SQL> create table loba(id int,name clob) tablespace users;

SQL> select TABLE_NAME,COLUMN_NAME,SEGMENT_NAME,TABLESPACE_NAME,INDEX_NAME from user_lobs;
TABLE    COLUMN      SEGMENT                  TABLESPACE_NAME    INDEX_NAME
------------------------------ ------------------------------
LOBA     NAME    SYS_LOB0000015553C00002$$      USERS  SYS_IL0000015553C00002$$

 
#查詢LOB的表,LOB段,索引
SQL> select object_name,object_type,status from user_objects where object_name 
in (LOBA,SYS_LOB0000015553C00002$$,SYS_IL0000015553C00002$$); OBJECT_NAME OBJECT_TYPE STATUS ------------------------------------------------------------- LOBA TABLE VALID SYS_IL0000015553C00002$$ INDEX VALID SYS_LOB0000015553C00002$$ LOB VALID #DROP SQL> drop table loba purge; #再次查詢:記錄清除 SQL> select object_name,object_type,status from user_objects where object_name
in (LOBA,SYS_LOB0000015553C00002$$,SYS_IL0000015553C00002$$); no rows selected #查詢用戶下的LOB信息,也被刪除 SQL> select * from user_lobs; no rows selected

小結:drop table xx purge;後,會級聯刪除LOB對象信息 2.6:測試:刪除的LOB段,在視圖recyclebin中有什麽明確記錄
SQL>  select type,count(*) from dba_recyclebin where owner=‘SCOTT‘ and type=‘LOB‘ group by type;
no rows selected

SQL> create table scott.id(i int,name blob,last clob);
SQL> drop table scott.id;


#驗證:使用查詢即可:查詢回收站中,LOB類型的對象數量,驗證是否導入缺失的LOB數量對比
select type,count(*) from dba_recyclebin where owner=‘SCOTT‘ and type=‘LOB‘ group by type
TYPE                        COUNT(*)
------------------------- ----------
LOB                                2

 
#驗證:使用如下查詢,可以查詢出,在回收站中記錄的對象: lob對象名稱
SQL> select OWNER,OBJECT_NAME,OBJECT_TYPE,STATUS from dba_objects where owner=‘SCOTT‘ and object_type=‘LOB‘;
OWNER      OBJECT_NAME                         OBJECT_TYP STATUS
---------- ----------------------------------- ---------- -------
SCOTT      SYS_LOB0000089722C00003$$           LOB        VALID
SCOTT      SYS_LOB0000089722C00002$$           LOB        VALID


2.7:對於出現的問題:有什麽方法可以避免:例如purge 回收站,是否會刪除不該繼續存在的LOB對象
#查詢回收站

SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
ID               BIN$aO6HsIdlTr3gU4AUqMDssg==$0 TABLE        2018-04-03:17:51:14
ID               BIN$aO6HsIdkTr3gU4AUqMDssg==$0 TABLE       2018-04-03:17:35:05


#清空回收站
SQL> purge recyclebin;
Recyclebin purged.

 
#小結:   在執行數據泵導出前,清空回收站,可以避免此場景
SQL> select type,count(*) from dba_recyclebin where owner=‘SCOTT‘ and type=‘LOB‘ group by type;
no rows selected
#或者計算對象時:減去回收站內的LOB對象數量

LOB對象在數據泵導出、導入後查詢對象數量發現丟失