已索引
如果你一次运行的任务数据超过了99个,则不要使用默认的 JOB_NAME,可以通过 JOB_NAME=xxx 来指定一个名字。
注意,如果自己定义 JOB_NAME,备份任务是每天定期自动做的话,需要通过 shell 每次生成不同的 JOB_NAME。
之所以默认的 JOB_NAME 不能超过 99个,是因为默认的 JOB_NAME 格式为:SYS_EXPORT_<mode>_NN。
如果不是一次运行了太多任务,则按照下面的方法清理 DBA_DATAPUMP_JOBS 中的 Orphaned DataPump Jobs。
查询数据库中存在的 Data Pump jobs
SET pages 800
SET lines 200
COL owner_name FORMAT a10;
COL job_name FORMAT a20
COL state FORMAT a12
COL operation LIKE state
COL job_mode LIKE state
COL owner.object for a50
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$%'
ORDER BY 1,2;
OWNER_NAME JOB_NAME OPERATION JOB_MODE STATE ATTACHED_SESSIONS
---------- -------------------- ------------ ------------ ------------ -----------------
SYS SYS_EXPORT_SCHEMA_01 EXPORT SCHEMA NOT RUNNING 0
…………
SYS SYS_EXPORT_SCHEMA_99 EXPORT SCHEMA NOT RUNNING 0
99 rows selected.
确认上面 NOT RUNNING 的作业的 OWNER_NAME,确认作业不是人工暂停的。
检查孤立 Datapump 外部表
Identify orphan DataPump external tables.
set linesize 200 trimspool on
set pagesize 2000
col owner form a30
col created form a25
col last_ddl_time form a25
col object_name form a30
col object_type form a25
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$%';
no rows selected
select owner, TABLE_NAME, DEFAULT_DIRECTORY_NAME, ACCESS_TYPE
from dba_external_tables
order by 1,2;
no rows selected
如果有输出,根据上面的输出,找出孤立 Datapump 作业的外部表,然后删除:
SQL> drop table system.&1 purge;
Enter value for 1: ET$00654E1E0001
old 1: drop table system.&1 purge
new 1: drop table system.ET$00654E1E0001 purge
找出 Datapump 作业的 master tables
COL owner.object FORMAT a50
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.job_name NOT LIKE 'BIN$%' ORDER BY 4,2;
STATUS OBJECT_ID OBJECT_TYPE OWNER.OBJECT
------- ---------- ------------------------- --------------------------------------------------
VALID 3920167 TABLE SYS.SYS_EXPORT_SCHEMA_01
…………
VALID 5389966 TABLE SYS.SYS_EXPORT_SCHEMA_99
99 rows selected.
SQL> select table_name, owner from dba_external_tables;
no rows selected
删除外部表
对于过去已经停止且不会再运行的作业,删除 master 表。
SELECT 'DROP TABLE '||o.owner||'.'||object_name||' PURGE;' as "D_STATEMENT"
FROM dba_objects o, dba_datapump_jobs j
WHERE o.owner=j.owner_name AND o.object_name=j.job_name
AND j.job_name NOT LIKE 'BIN$%';
D_STATEMENT
----------------------------------------------------------------------
DROP TABLE SYS.SYS_EXPORT_SCHEMA_95 PURGE;
…………
DROP TABLE SYS.SYS_EXPORT_SCHEMA_07 PURGE;
99 rows selected.
如果表名有大小写,将表名用双引号引起来。
检查确认
从头检查。If there are still jobs listed in dba_datapump_jobs, and these jobs do not have a master table anymore, cleanup the job while connected as the job owner.
CONNECT <USER>/<PASSWORD>
SET serveroutput on
SET lines 100
DECLARE
h1 NUMBER;
BEGIN
h1 := DBMS_DATAPUMP.ATTACH('SYS_EXPORT_TABLE_01','<SCHEMA>');
DBMS_DATAPUMP.STOP_JOB (h1);
END;
/
Note that after the call to the STOP_JOB procedure, it may take some time for the job to be removed.
执行后再次检查。
原因分析
为什么核心数据库有这个问题,而其它数据库没有这个问题呢?
正常情况下,逻辑备份完成后都会自动清理历史信息。
其他数据库每天的逻辑备份都是正常的,但是核心数据库第一节点每天的备份因为 bug 因为会失败。
当备份脚本检测到失败后会切换到第二节点成功执行备份。
第一节点未正常结束,导致历史信息不能自动清理,时间一长,就达到了默认名名的最大编号 99,后期再备份就会报如下错误:
ORA-31634: job already exists
ORA-31664: unable to construct unique job name when defaulted