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

群友删除了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,再修改事务槽。

解决问题的思路很重要~


请使用浏览器的分享功能分享到微信等