Oracle-11g 中当执行 DBMS_STATS 时,因数据泵外部表文件缺失 Alert Log 告警 "ORA-20011、ORA-29913" 以及 "KUP-XXXXX"错误

告警现象:

Alert Log 中 出现类似如下告警信息。
*** 2016-11-24 22:00:05.260
DBMS_STATS: GATHER_STATS_JOB: GATHER_TABLE_STATS('"ADM_ZSZ"','"ET$02D2001B0001"','""', ...)
DBMS_STATS: ORA-20011: Approximate NDV failed: ORA-29913: error in executing ODCIEXTTABLEOPEN callout
KUP-11024: This external table can only be accessed from within a Data Pump job.
 
告警原因:
当尝试读取外部表时,外部函数 "ODCIEXTTABLEOPEN" 报错。
真正原因是关联外部表的文件已不存在,而数据库却仍认为文件仍存在。数据库之所以认为文件仍存在是因为外部表的目录信息并未被改动。
而数据泵外部表文件缺失往往因为数据包作业没有正常结束导致。
 
处理步骤:
1.识别失效的数据泵作业
SQL> SELECT owner_name, job_name, rtrim(operation) "OPERATION", 
       rtrim(job_mode) "JOB_MODE", state, attached_sessions
  FROM dba_datapump_jobs
 WHERE job_name NOT LIKE 'BIN$%'
 AND state='NOT RUNNING'
 ORDER BY 1,2;
根据查询结果,识别出失效的数据泵作业。注意:并非所有"NOT RUNNING"的作业都是失效作业。
2.识别失效数据泵作业关联的数据表
SQL> SELECT o.status, o.object_id, o.object_type, 
       o.owner||'.'||object_name "OWNER.OBJECT" 
  FROM dba_objects o, dba_datapump_jobs j 
 WHERE o.owner=j.owner_name AND o.object_name=j.job_name 
   AND j.state='NOT RUNNING'
   AND j.job_name NOT LIKE 'BIN$%' ORDER BY 4,2; 
3.删除失效数据泵作业关联的数据表
根据步骤 2 "识别失效数据泵作业关联的数据表" 的结果,通过类似如下语句删除数据表。
SQL> DROP TABLE <schema>.<table_name> PURGE;
4.清理顽固的失效数据泵作业
重新执行步骤 1 "识别失效的数据泵作业" ,如果删除数据表后失效作业仍存在,则需要以作业所有用户连接数据库,执行类似如下语句。
例如:清理的失效作业的数据表名为 "SYS_EXPORT_TABLE_01",失效作业由 "SCOTT" 发起。
SQL> SET serveroutput on 
SET lines 100 
DECLARE 
   h1 NUMBER; 
BEGIN 
   h1 := DBMS_DATAPUMP.ATTACH('SYS_EXPORT_TABLE_01','SCOTT'); 
   DBMS_DATAPUMP.STOP_JOB (h1); 
END; 
/
5.识别数据泵作业关联的失效外部表
注意:为了避免潜在的干扰因素,在识别不存在的外部表过程中,请确保没有数据泵作业在运行
通过以下语句确定外部表
SQL> select owner, TABLE_NAME, TYPE_NAME, DEFAULT_DIRECTORY_NAME, ACCESS_TYPE
from dba_external_tables
order by 1,2;
通过以下语句确定数据泵作业的外部表
SQL> select OWNER,OBJECT_NAME,OBJECT_TYPE, status,
to_char(CREATED,'dd-mon-yyyy hh24:mi:ss') created
,to_char(LAST_DDL_TIME , 'dd-mon-yyyy hh24:mi:ss') last_ddl_time
from dba_objects
where object_name like 'ET$%';
6.删除数据泵作业关联的失效外部表
根据步骤 5 "识别数据泵作业关联的失效外部表" 的结果,确保外部表属于数据泵进程,通过类似如下语句删除外部表。
SQL> DROP TABLE <schema>.<table_name> PURGE;
 
参考文档:
(1).《How To Cleanup Orphaned DataPump Jobs In DBA_DATAPUMP_JOBS  (文档 ID 336014.1)》
(2).《ORA-20011 ORA-29913 and ORA-29400 with Associated KUP-XXXXX Errors from DBMS_STATS.GATHER_STATS_JOB (文档 ID 1274653.1)》
原文地址:https://www.cnblogs.com/autopenguin/p/6305754.html