EXP导出aud$报错EXP-00008,ORA-00904 解决

本文介绍了解决Oracle环境下使用EXP导出sys用户下的aud$表时出现的EXP-00008及ORA-00904错误的方法。通过oradebug进行故障跟踪,并最终通过授予DBMS_JAVA包执行权限给DBA角色解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主题:EXP导出aud$报错EXP-00008,ORA-00904 解决
环境:Oracle 11.2.0.4
问题:在自己的测试环境,导出sys用户下的aud$表报错。

1.故障现场

导出sys用户下的表,依据经验使用system用户导出:

按照这个方法,exp导出时报错,具体报错信息如下:

[oracle@jyrac1 ~]$ exp system/oracle file=audit.dmp log=audit.log tables=sys.aud$

Export: Release 11.2.0.4.0 - Production on Wed Jan 17 17:16:30 2018

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.


Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Tes
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

About to export specified tables via Conventional Path ...
Current user changed to SYS
. . exporting table                           AUD$
EXP-00008: ORACLE error 904 encountered
ORA-00904: : invalid identifier
Export terminated successfully with warnings.

2.跟踪处理

使用oradebug跟踪对应的exp进程:

2.1 exp 交互式

[oracle@jyrac1 ~]$ exp system/oracle

Export: Release 11.2.0.4.0 - Production on Wed Jan 17 17:20:17 2018

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.


Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Tes
Enter array fetch buffer size: 4096 > 

2.2 定位exp进程的SPID:

SELECT p.spid,
       p.addr,
       p.pid,
       s.sid,
       SUBSTR(s.username, 1, 15) "USERNAME",
       SUBSTR(s.program, 1, 15) "PROGRAM"
  FROM v$process p, v$session s
 WHERE s.paddr = p.addr
   AND addr =
       (SELECT paddr FROM v$session WHERE UPPER(program) LIKE 'EXP%');

结果如下:

SYS@jyzhao1 >SELECT p.spid,
  2         p.addr,
  3         p.pid,
  4         s.sid,
  5         SUBSTR(s.username, 1, 15) "USERNAME",
  6         SUBSTR(s.program, 1, 15) "PROGRAM"
  7    FROM v$process p, v$session s
  8   WHERE s.paddr = p.addr
  9     AND addr =
 10         (SELECT paddr FROM v$session WHERE UPPER(program) LIKE 'EXP%');

SPID                     ADDR                    PID        SID USERNAME                       PROGRAM
------------------------ ---------------- ---------- ---------- ------------------------------ ------------------------------
15552                    000000007F4CA268         33        141 SYSTEM                         exp@jyrac1 (TNS

2.3 oradebug跟踪spid:

SQL> oradebug setospid 15552
SQL> oradebug unlimit
SQL> oradebug tracefile_name
SQL> oradebug Event 10046 trace name context forever, level 12

实际过程记录:

SYS@jyzhao1 >oradebug setospid 15552
Oracle pid: 33, Unix process pid: 15552, image: oracle@jyrac1 (TNS V1-V3)
SYS@jyzhao1 >oradebug unlimit
Statement processed.
SYS@jyzhao1 >oradebug tracefile_name
/opt/app/oracle/diag/rdbms/jyzhao/jyzhao1/trace/jyzhao1_ora_15552.trc
SYS@jyzhao1 >oradebug Event 10046 trace name context forever, level 12
Statement processed.

2.4 查看10046的跟踪文件:
我搜索904这个错误,可以匹配到err=904的部分

=====================
PARSE ERROR #139705015595160:len=301 dep=0 uid=5 oct=3 lid=5 tim=1516181414835913 err=904
SELECT SYNNAM, DBMS_JAVA.LONGNAME(SYNNAM), DBMS_JAVA.LONGNAME(SYNTAB),             TABOWN, TABNODE, PUBLIC$, SYNOWN, SYNOWNID, TABOWNID, SYNOBJNO      FROM   SYS.EXU9PTS      WHERE  SYNOBJNO IN (          SELECT SYNOBJNO          FROM SYS.EXU9TYPT          WHERE TABOBJNO = :1 )      ORDER  BY SYNTIME
WAIT #139705015595160: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=18 tim=1516181414836191
WAIT #139705015595160: nam='SQL*Net message from client' ela= 127 driver id=1650815232 #bytes=1 p3=0 obj#=18 tim=1516181414836355
WAIT #0: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=18 tim=1516181414836399

*** 2018-01-17 17:30:19.545
WAIT #0: nam='SQL*Net message from client' ela= 4709518 driver id=1650815232 #bytes=1 p3=0 obj#=18 tim=1516181419545928
WAIT #0: nam='SQL*Net message to client' ela= 2 driver id=1650815232 #bytes=1 p3=0 obj#=18 tim=1516181419546119
WAIT #0: nam='SQL*Net message from client' ela= 65 driver id=1650815232 #bytes=1 p3=0 obj#=18 tim=1516181419546230
PARSE #139705014733696:c=0,e=17,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=3684871272,tim=1516181419547202
BINDS #139705014733696:
 Bind#0
  oacdty=11 mxl=16(16) mxlc=00 mal=00 scl=00 pre=00
  oacflg=18 fl2=0001 frm=00 csi=00 siz=16 off=0
  kxsbbbfp=7f0f9bca8510  bln=16  avl=16  flg=05
  value=00002451.0000.0001
EXEC #139705014733696:c=0,e=98,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=3684871272,tim=1516181419547371
FETCH #139705014733696:c=0,e=59,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,plh=3684871272,tim=1516181419547468
CLOSE #139705014733696:c=0,e=29,dep=1,type=3,tim=1516181419547548
PARSE #139705014733696:c=0,e=26,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=3684871272,tim=1516181419548823
BINDS #139705014733696:
 Bind#0
  oacdty=11 mxl=16(16) mxlc=00 mal=00 scl=00 pre=00
  oacflg=18 fl2=0001 frm=00 csi=00 siz=16 off=0
  kxsbbbfp=7f0f9bca8510  bln=16  avl=16  flg=05
  value=0000243C.0007.0001
EXEC #139705014733696:c=0,e=112,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=3684871272,tim=1516181419549015
FETCH #139705014733696:c=1000,e=116,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,plh=3684871272,tim=1516181419549155
CLOSE #139705014733696:c=0,e=9,dep=1,type=3,tim=1516181419549188
=====================

也可以选择tkprof美化trc文件:

[root@jyrac1 ~]# tkprof /opt/app/oracle/diag/rdbms/jyzhao/jyzhao1/trace/jyzhao1_ora_15552.trc /tmp/jyzhao1_ora_15552.out waits=y sort=exeela

TKPROF: Release 11.2.0.4.0 - Development on Wed Jan 17 17:33:44 2018

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

美化后的文档可以更清晰的看到904错误的原因:

********************************************************************************

The following statement encountered a error during parse:

SELECT SYNNAM, DBMS_JAVA.LONGNAME(SYNNAM), DBMS_JAVA.LONGNAME(SYNTAB),             TABOWN, TABNODE, PUBLIC$, SYNOWN, SYNOWNID, TABOWNID, SYNOBJNO      FROM   SYS.EXU9PTS      WHERE  SYNOBJNO IN (          SELECT SYNOBJNO          FROM SYS.EXU9TYPT          WHERE TABOBJNO = :1 )      ORDER  BY SYNTIME

Error encountered: ORA-00904
********************************************************************************

3.匹配MOS文章

根据报错和trc文件的内容,匹配到MOS文档:Errors EXP-8 ORA-904 During Export (文档 ID 1091927.1)

APPLIES TO:
Oracle Database - Enterprise Edition - Version 10.2.0.4 and later
Information in this document applies to any platform.
Checked for relevance on 16-Dec-2014
SYMPTOMS
You are attempting to perform an export as the SYSTEM user or a DBA. During export, the following errors occurred:

EXP-00008: ORACLE error 904 encountered
ORA-00904: : invalid identifier

When performing a trace on the export, we see that the ORA-904 error is caused by the following statement:

PARSE ERROR #9:len=302 dep=0 uid=5 oct=3 lid=5 tim=778463694169 err=904
SELECT SYNNAM, DBMS_JAVA.LONGNAME(SYNNAM), DBMS_JAVA.LONGNAME(SYNTAB), TABOWN, TABNODE, PUBLIC$, SYNOWN, SYNOWNID, TABOWNID, SYNOBJNO FROM SYS.EXU9PTS WHERE SYNOBJNO IN ( SELECT SYNOBJNO FROM SYS.EXU9TYPT WHERE TABOBJNO = :1 ) ORDER BY SYNTIME
CAUSE
The PUBLIC privilege has been revoked from the DBMS_JAVA package.

Privileges to the DBMS_JAVA package are needed for the export to succeed. However, as there is concern about security issues due to privileges on the DBMS_JAVA many have revoked the execute privilege to this package to keep the database secure.

SOLUTION
Explicitly grant EXECUTE on the DBMS_JAVA package to the DBA role:

SQL> grant execute on DBMS_JAVA to dba;

This will give members of the DBA role the rights to perform the export while keeping the DBMS_JAVA package out of the PUBLIC role.

4.使用MOS解决方案

MOS解决方案赋权DBMS_JAVA给DBA角色:

SYS@jyzhao1 >grant execute on DBMS_JAVA to dba;

Grant succeeded.

再次尝试exp导出成功。

[oracle@jyrac1 ~]$ exp system/oracle file=audit.dmp log=audit.log tables=sys.aud$

Export: Release 11.2.0.4.0 - Production on Wed Jan 17 17:39:07 2018

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.


Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Tes
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

About to export specified tables via Conventional Path ...
Current user changed to SYS
. . exporting table                           AUD$         25 rows exported
Export terminated successfully without warnings.

至此,问题完美解决,该案例的定位,主要用到了oradebug的跟踪技能。

<think>我们正在解决用户创建表AUD_BACKUP时遇到的ORA-00955错误。这个错误表示表名已被现有对象使用。 根据用户描述,用户意图创建AUD_BACKUP表来备份SYS.AUD$表的数据。 解决方案: 1. 检查当前用户下是否已经存在名为AUD_BACKUP的表(或其他同名对象)。 2. 如果存在,我们可以选择删除现有对象(如果不再需要)或者重命名新表。 3. 为了避免删除可能重要的对象,建议先确认该对象是否可删除,或者使用不同的表名。 步骤: 步骤1:查询当前用户下是否存在名为AUD_BACKUP的表 步骤2:如果存在,确认是否可以删除或重命名 步骤3:如果不存在,可能是其他类型的同名对象(如索引、视图等),需要一并检查 另外,注意用户可能是在不同的模式下创建表(比如在SYS下创建,但通常不建议在SYS下创建用户表),所以还要考虑模式问题。 但是,用户创建表AUD_BACKUP,很可能是要在自己的模式下创建,所以检查当前用户下的对象。 查询当前用户下所有名为AUD_BACKUP的对象: 我们可以使用以下SQL查询: SELECT object_name, object_type FROM user_objects WHERE object_name = 'AUD_BACKUP'; 如果查询有结果,说明存在同名对象。 处理方式: 方式一:删除已存在的同名对象(如果确定不再需要) DROP TABLE AUD_BACKUP; -- 如果是表 DROP VIEW AUD_BACKUP; -- 如果是视图 等等,根据实际类型删除。 方式二:修改新表名,例如改为AUD_BACKUP_NEW等。 考虑到用户需要备份SYS.AUD$表,这个表可能很大,所以创建备份表是合理的。 另外,注意:在Oracle中,表名、视图名等对象名称不区分大小写,但是Oracle默认会将名称转换为大写(除非创建时用双引号括起来并指定小写)。所以,我们查询时用大写。 根据引用[1]中E选项:创建一个表返回ORA-00955:名字已备现有对象使用。说明确实存在同名对象。 因此,我们给出以下步骤: 1. 检查是否存在同名对象: ```sql SELECT object_name, object_type FROM user_objects WHERE object_name = 'AUD_BACKUP'; ``` 2. 如果存在,并且可以删除,则删除: ```sql -- 根据对象类型执行删除 BEGIN FOR obj IN (SELECT object_name, object_type FROM user_objects WHERE object_name = 'AUD_BACKUP') LOOP EXECUTE IMMEDIATE 'DROP ' || obj.object_type || ' ' || obj.object_name; END LOOP; END; / ``` 或者,如果只有表,可以直接: ```sql DROP TABLE AUD_BACKUP PURGE; ``` 3. 如果不想删除,则选择另一个表名,例如: ```sql CREATE TABLE AUD_BACKUP_NEW AS SELECT * FROM SYS.AUD$; ``` 4. 重新执行创建备份表的语句: ```sql CREATE TABLE AUD_BACKUP AS SELECT * FROM SYS.AUD$; ``` 注意:直接备份SYS.AUD$表需要具有相应的权限。通常需要DBA权限。 另外,由于SYS.AUD$可能很大,创建备份表可能需要较长时间,并产生大量undo和redo。 补充:如果用户是在SYS用户下操作,则要特别注意,因为SYS用户下的对象都是系统重要的,不建议在SYS下创建用户表。所以,建议在另一个用户下创建备份表,并赋予该用户SELECT ON SYS.AUD$的权限。 因此,更安全的做法是: 1. 创建一个专门用于备份的用户(如果不存在)并授予权限。 2. 用该用户登录,然后创建备份表。 例如: CREATE USER backup_user IDENTIFIED BY password; GRANT CONNECT, RESOURCE TO backup_user; GRANT SELECT ON SYS.AUD$ TO backup_user; 然后以backup_user登录: CREATE TABLE AUD_BACKUP AS SELECT * FROM SYS.AUD$; 如果这样操作,就不会和SYS用户下的对象冲突。 所以,用户遇到这个错误,可能是因为在同一个用户下已经有一个同名的表。 综上所述,我们提供两种方案: 方案一:删除已有同名对象,然后重新创建(适用于确认该对象无用) 方案二:使用其他用户创建备份表(更安全,避免与系统对象冲突) 根据引用[4]中我们看到有CON_ID,说明可能是多租户环境。如果是在PDB中操作,则需要注意当前容器。 但创建表操作通常是在当前PDB中,所以不影响。 我们按照方案一给出具体步骤: 步骤1:查询当前用户下的同名对象 步骤2:删除同名对象(如果存在且允许删除) 步骤3:创建备份表 如果用户没有权限删除,或者不想删除,则采用新表名。 另外,如果用户希望保留原有同名表中的数据,那么应该先重命名原有表,然后再创建新表,最后将重命名表的数据导入新表(如果需要的话)。但这里用户是要备份AUD$,所以原有表如果是之前备份的,可能已经过时,可以删除。 因此,我们给出以下示例代码: 示例: 1. 检查并删除(在SQL*Plus中执行): ```sql -- 查询是否存在 SELECT object_name, object_type FROM user_objects WHERE object_name = 'AUD_BACKUP'; -- 如果存在,删除(注意:这会永久删除该对象) DROP TABLE AUD_BACKUP PURGE; -- 如果是表 -- 如果是其他对象,如视图 -- DROP VIEW AUD_BACKUP; ``` 或者使用动态删除(如果不知道具体类型): ```sql DECLARE v_count NUMBER; BEGIN FOR rec IN (SELECT object_name, object_type FROM user_objects WHERE object_name = 'AUD_BACKUP') LOOP EXECUTE IMMEDIATE 'DROP ' || rec.object_type || ' ' || rec.object_name; DBMS_OUTPUT.PUT_LINE('Dropped ' || rec.object_type || ' ' || rec.object_name); END LOOP; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM); END; / ``` 2. 创建备份表: ```sql CREATE TABLE AUD_BACKUP AS SELECT * FROM SYS.AUD$; ``` 注意:如果SYS.AUD$表非常大,这个操作可能会很慢,并且需要足够的表空间。 如果用户遇到表空间不足的问题,需要提前分配足够的表空间,或者在创建表时指定表空间。 例如: ```sql CREATE TABLE AUD_BACKUP TABLESPACE users AS SELECT * FROM SYS.AUD$; ``` 另外,如果用户希望只备份最近一段时间的数据,可以添加WHERE条件。 最后,考虑到用户可能是在生产环境操作,建议在低峰期进行。 相关问题: 1. 如何查看当前用户下的所有表? 2. 删除表时出现ORA-00942(表或视图不存在)是什么原因? 3. 如何估算SYS.AUD$表的大小? 4. 如何将备份表创建到其他表空间? 5. 如何备份审计记录到另一个数据库? 注意:在引用中,我们并没有直接相关的引用,但引用[1]提到了ORA-00955错误,引用[4]展示了数据文件的状态和恢复,与表空间有关,所以备份表时要注意表空间状态。 因此,我们在回答中引用[1]说明这个错误是名称已被现有对象使用。</think>### 解决 ORA-00955 错误:创建 AUD_BACKUP 表失败 #### 错误原因分析 ORA-00955 错误表示**数据库对象名称已被现有对象使用**。在您尝试创建 `AUD_BACKUP` 表时,可能因为以下原因导致冲突: 1. 当前用户下已存在同名表或视图 2. 其他用户拥有同名对象且您有访问权限 3. 存在同名但不同类型的对象(如索引、序列等) 4. 对象在回收站中未完全删除[^1] --- ### 解决方案步骤 #### 步骤 1:检查同名对象 ```sql -- 检查当前用户下的同名对象 SELECT object_name, object_type FROM user_objects WHERE object_name = 'AUD_BACKUP'; -- 检查所有用户下的同名对象(需DBA权限) SELECT owner, object_name, object_type FROM dba_objects WHERE object_name = 'AUD_BACKUP'; ``` #### 步骤 2:处理现有对象 根据查询结果选择合适操作: ```sql -- 情况1:存在同名表(推荐删除) DROP TABLE AUD_BACKUP PURGE; -- PURGE绕过回收站直接删除 -- 情况2:存在同名视图 DROP VIEW AUD_BACKUP; -- 情况3:对象在回收站(Oracle 10g+) PURGE RECYCLEBIN; -- 清空当前用户回收站 -- 情况4:保留原有对象(改用新表名) CREATE TABLE AUD_BACKUP_NEW AS SELECT * FROM SYS.AUD$; ``` #### 步骤 3:创建备份表 ```sql -- 标准创建方式 CREATE TABLE AUD_BACKUP AS SELECT * FROM SYS.AUD$ WHERE 1=0; -- 仅复制结构不复制数据 -- 包含存储参数(推荐) CREATE TABLE AUD_BACKUP STORAGE (INITIAL 64M NEXT 32M) -- 初始64MB,每次扩展32MB TABLESPACE users -- 指定非SYSTEM表空间 AS SELECT * FROM SYS.AUD$; ``` #### 步骤 4:验证和备份数据 ```sql -- 验证表结构 DESC AUD_BACKUP; -- 插入数据(约1小时审计量) INSERT INTO AUD_BACKUP SELECT * FROM SYS.AUD$ WHERE NTIMESTAMP# > SYSTIMESTAMP - INTERVAL '1' HOUR; COMMIT; ``` --- ### 关键注意事项 1. **权限要求** ```sql GRANT SELECT ON SYS.AUD$ TO your_user; -- 需DBA执行 GRANT UNLIMITED TABLESPACE TO your_user; ``` 2. **存储规划** ```sql -- 查询AUD$表大小 SELECT ROUND(SUM(bytes)/1024/1024) AS size_mb FROM dba_segments WHERE segment_name = 'AUD$'; ``` | 审计数据量 | 建议表空间大小 | 备份策略 | |------------|----------------|----------| | <1GB | 2GB | 全量备份 | | 1-10GB | 20GB | 按周备份 | | >10GB | 50GB+ | 分区备份 | 3. **多租户环境** 在CDB/PDB环境中需指定容器[^3]: ```sql ALTER SESSION SET CONTAINER = your_pdb; CREATE TABLE AUD_BACKUP ... ``` --- ### 自动备份脚本示例 ```sql BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'AUD_BACKUP_JOB', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN EXECUTE IMMEDIATE ''TRUNCATE TABLE AUD_BACKUP''; INSERT INTO AUD_BACKUP SELECT * FROM SYS.AUD$; END;', start_date => SYSTIMESTAMP, repeat_interval => 'FREQ=DAILY; BYHOUR=2', enabled => TRUE ); END; / ``` --- ### 相关问题 1. 如何将审计表迁移到专用表空间? 2. Oracle 19c中如何配置自动审计清理? 3. 多租户环境下如何集中管理PDB审计记录? 4. 审计表过大导致SYSAUX表空间不足如何处理[^4]? 5. 如何恢复已删除的审计记录? > 通过合理规划备份策略[^2],可有效管理审计数据增长,避免系统表空间溢出风险[^4]。定期验证备份完整性是DBA关键任务之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值