群友删除了dual表同义词的分析和处理

来源:这里教程网 时间:2026-03-03 21:20:21 作者:

群友删除了dual表同义词的分析和处理

1、背景


1月9日晚,接到群友求助,说有人误删除了dual同义词导致整个业务挂掉。昨天在外面吃饭,没有环境,我手机上给他说了下,让他找个环境先测试。

过一会,他找到我,还是无法解决,他在恢复创建同义词的时候遇到了如下报错,又发给我,我看到了ORA-000001违反唯一约束问题,第一时间想到有唯一约束或者唯一索引导致,让他找一下,然后禁用再创建。

通过他的分析,发现没有该约束。后面我继续吃饭就没管了。后面搞了很久,群友测试帮助下,找到了具体问题,是基表中SYN$重复导致,删除了里面的DUAL记录就好了。和我给他说的思路是一样的。

2、问题测试



##今天刚好有点时间,测试下。

1、破坏环境
select * from dba_objects 
where object_name=
'DUAL';
select * from dba_synonyms 
where synonym_name=
'DUAL';
DROP PUBLIC SYNONYM DUAL;
create public synonym dual 
for sys.dual;

2、按照我昨天给他说的思路做
select * from dba_constraints 
where constraint_name=
'I_SYN1';  --无记录
select * from dba_constraints 
where constraint_name LIKE 
'%I_SYN%'; --无记录
SELECT * FROM DBA_OBJECTS WHERE object_name LIKE 
'%I_SYN%'; --结果如下

select a.owner,a.index_name,a.table_owner,a.table_name,a.uniqueness,a.status,a.constraint_index,
listagg (b.COLUMN_NAME, 
',') WITHIN GROUP (ORDER BY b.COLUMN_POSITION) idx_column
from dba_indexes a,dba_ind_columns b 

where a.table_owner=b.TABLE_OWNER
and a.owner=b.INDEX_OWNER
and a.index_name=b.index_name
and a.table_name=
'SYN$'
--and a.index_name=
'I_SYN1'
group by a.owner,a.index_name,a.table_owner,a.table_name,a.uniqueness,a.status,a.constraint_index;

--通过上面我们可以看到,这个是一个唯一的索引,创建在了SYS.SYN$表中的OBJ
#列。而实际上该表没有约束,这也是为什么前面查询不到的原因。

select * from SYS.SYN$ 
where name like 
'%DUAL%';


##找到问题就很好办了
3、解决办法
方法1
1)删除索引
2)创建同义词
SQL> drop index I_SYN1;
SQL> create public synonym dual 
for sys.dual;
3)重建索引
--找到非唯一的行,也就是说在SYN$中找到重复的行,然后删除,再创建即可。或者取消unique创建成非唯一索引。

SELECT ROWID, a.*, ROW_NUMBER() OVER (PARTITION BY obj
#, name ORDER BY ROWID) AS RN FROM SYS.SYN$ a;
delete from SYS.SYN$ a 
where a.rowid=
'AAAABeAABAAAARZAAA';
commit;

create unique index I_SYN1 on SYN$ (OBJ
#)  tablespace SYSTEM;

方法2
1)找到表中的行,查看是违反了什么唯一键,导致冲突(也就是和dual相关的行)
2)删除多余的行
3)创建同义词

3、总结



##问题就像我给他说的,很简单。

##即便恢复不了,通过特殊手段把system恢复出来,单独起库,把对应的文件再通过修改关键文件头位置关联即可实现移花接木。

##还有就是块的反省3c修改2c,再修改事务槽。

解决问题的思路很重要~

相关推荐