DUAL表误删除恢复

DUAL表不存在,被删除,数据库是无法启动的,会报错,必须恢复。

昨天晚上接到同事来电,说dual表不小心被删除了,现在无法创建,于是研究了下dual表的恢复,现在模拟还原如下:
dual表是系统的一个虚表,用来构成select的语法规则。

如果不小心删除了的话,会导致数据库起不来,报错ORA-01092: ORACLE instance terminated. Disconnection forced。

数据库版本10.2.0.4
OS:linux
[oracle@rac1 ~]$ uname -a
Linux rac1 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 athlon i386 GNU/Linux

过程如下:


[oracle@rac1 ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 10.2.0.4.0 - Production on Thu Dec 30 15:10:24 2010

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options

SQL> select * from dual;

D
-
X

SQL>


--删除DUAL表


SQL> drop table dual;

Table dropped.

SQL>
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL> startup
ORACLE instance started.

Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 104860968 bytes
Database Buffers 58720256 bytes
Redo Buffers 2924544 bytes
Database mounted.
ORA-01092: ORACLE instance terminated. Disconnection forced


--报错,已无法启动

SQL>


Alert日志报错:

Thu Dec 30 15:16:58 2010
Errors in file /u02/app/oracle/admin/NOAP/udump/noap1_ora_12164.trc:
ORA-01775: looping chain of synonyms
Error 1775 happened during db open, shutting down database
USER: terminating instance due to error 1775
Thu Dec 30 15:16:58 2010
Errors in file /u02/app/oracle/admin/NOAP/bdump/noap1_lms0_12015.trc:
ORA-01775: looping chain of synonyms
Thu Dec 30 15:16:58 2010
Errors in file /u02/app/oracle/admin/NOAP/bdump/noap1_lmd0_12008.trc:
ORA-01775: looping chain of synonyms
Thu Dec 30 15:16:58 2010
Errors in file /u02/app/oracle/admin/NOAP/bdump/noap1_lmon_12006.trc:
ORA-01775: looping chain of synonyms
Instance terminated by USER, pid = 12164
ORA-1092 signalled during: ALTER DATABASE OPEN...


SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options

在网上搜寻半天,大家都做法都是一样:
1.创建一个pfile,在pfile中加入参数replication_dependency_tracking = FALSE 。
2.使用这个加参数的pfile启动数据库。
3.创建dual表。
4.去掉参数,重启。
即可顺利完成。

于是照做:


[oracle@rac1 ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 10.2.0.4.0 - Production on Thu Dec 30 15:17:36 2010

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to an idle instance.

SQL> startup mount
ORACLE instance started.

Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 104860968 bytes
Database Buffers 58720256 bytes
Redo Buffers 2924544 bytes
Database mounted.
SQL> host pwd
/export/home/oracle

SQL> create pfile='/export/home/oracle/initnoap1.ora' from spfile;

File created.

SQL> shutdown immediate
ORA-01109: database not open


Database dismounted.
ORACLE instance shut down.
SQL>

在init.ora文件中最后加入参数:replication_dependency_tracking = FALSE
这个参数指定数据库在启动的时候是否启用读/写相关性跟踪。

[oracle@rac1 ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 10.2.0.4.0 - Production on Thu Dec 30 15:20:53 2010

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to an idle instance.

SQL> startup pfile='/export/home/oracle/initnoap1.ora'
ORACLE instance started.

Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 104860968 bytes
Database Buffers 58720256 bytes
Redo Buffers 2924544 bytes
Database mounted.
Database opened.

--顺利启动

QL> select * from dual;
select * from dual
*
ERROR at line 1:
ORA-01775: looping chain of synonyms


SQL> select * from sys.dual;
select * from sys.dual
*
ERROR at line 1:
ORA-00942: table or view does not exist


SQL>
SQL> create table SYS.DUAL
2 ( dummy VARCHAR2(1))
3 tablespace SYSTEM
4 pctfree 10
5 pctused 40
6 initrans 1
7 maxtrans 255
8 storage
9 (
10 initial 16K
11 next 1M
12 minextents 1
13 maxextents unlimited
14 );
create table SYS.DUAL
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01775: looping chain of synonyms

--意外发生了,无法创建dual表

SQL>
SQL> drop synonym dual;
drop synonym dual
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01775: looping chain of synonyms


SQL> drop public synonym dual;
drop public synonym dual
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01775: looping chain of synonyms

--也无法删除dual同义词

--折腾了半天,死活就是不行

SQL>
SQL> select owner,object_name,object_type from dba_objects where object_name='DUAL';

OWNER OBJECT_NAME OBJECT_TYPE
---------- ------------------------------ -------------------
PUBLIC DUAL SYNONYM

SQL>
SQL>

--这个时候已经无法创建表

SQL> create table test(a varchar2(10));
create table test(a varchar2(10))
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01775: looping chain of synonyms


SQL>

访问某些字典表也可能出错

SQL> select * from v$log;
select * from v$log
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 2
ORA-01775: looping chain of synonyms


SQL>
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
noap1

SQL> SELECT * FROM DBA_DATA_FILES;
SELECT * FROM DBA_DATA_FILES
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 2
ORA-01775: looping chain of synonyms


SQL>

在网上找了半天,没有任何进展,大家的案例都是很顺利就创建了。唯有我这无法创建,也无法删除,
最后到metalink上搜寻,没有相同的案例,但是有一个文档引起我的注意
'Dual' Synonym was Dropped by Mistake and Cannot Recreate it [ID 973260.1]
其中一段:

It appears a trigger is being fired prior to the create statement.

Solution

======================
-- To implement the solution, please execute the following steps::
It appears a before create trigger is firing before issuing the create synonym statement.

1- Issue:
SQL>ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=FALSE SCOPE=MEMORY;
SQL> create or replace public synonym dual for sys.dual;
SQL>ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=true SCOPE=MEMORY;

2- If that still fails, query dba_triggers to determine if you have a before create trigger enabled. If yes, disable it and then re-issue create synonym statement.


马上想到创建dual表应该也是系统触发器的问题

SQL> ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=FALSE SCOPE=MEMORY;

System altered.

SQL> create table SYS.DUAL
2 ( dummy VARCHAR2(1))
3 tablespace SYSTEM
4 pctfree 10
5 pctused 40
6 initrans 1
7 maxtrans 255
8 storage
9 (
10 initial 16K
11 next 1M
minextents 1
12 13 maxextents unlimited
14 );

Table created.


--终于创建了

SQL> select * from dual;

no rows selected

SQL> insert into dual values('X');

1 row created.

SQL> commit;

Commit complete.

SQL> grant select on DUAL to PUBLIC with grant option;

Grant succeeded.


SQL> ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=true SCOPE=MEMORY;

System altered.

SQL>

SQL> select * from dual;

D
-
X

SQL>
SQL> select owner,object_name,object_type from dba_objects where object_name='DUAL';

OWNER OBJECT_NAME OBJECT_TYPE
---------- ------------------------------ -------------------
SYS DUAL TABLE
PUBLIC DUAL SYNONYM

SQL>

SQL> create table test(a varchar2(10));

Table created.

SQL> select sysdate from dual;

SYSDATE
---------
30-DEC-10

SQL>

终于好了,后面,关闭数据库,把replication_dependency_tracking = FALSE
去掉,重启,就OK了。

原文地址:https://www.cnblogs.com/miracle2020/p/14033300.html