yangtingkun
===========================================================
PUBLIC数据库链无法删除的问题(一)
===========================================================

今天在一个二线数据库中发现了一个奇怪的问题。有几个已经存在的PUBLIC数据库链无法正常删除。


这个数据库建立很早,且一直不是我在维护,所以数据库一直没有打PATCH,数据库版本仍然是9201

SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 -
Production PL/SQL Release 9.2.0.1.0 - Production
CORE 9.2.0.1.0 Production
TNS for Linux: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production

检查数据库链,并尝试删除:

SQL> SELECT * FROM DBA_DB_LINKS;

OWNER DB_LINK USERNAME HOST CREATED
-------- --------------------- ------------ ------------ ----------------------
PUBLIC DATA NDMAIN DATADB 2004-5
-14 18:44:07
PUBLIC DATA.EMEDCHINA.NET SELE datadb 2007-2
-01 10:39:10
PUBLIC DATADB DNMAIN DATADB 2004-5
-14 18:41:35
PUBLIC MAINDB LOG MAINDB 2004-2
-19 18:27:30
PUBLIC MAINDB.EMEDCHINA.NET LOG MAINDB 2004-6
-04 14:03:37
LAS REPDB02.EMEDCHINA.NET REPORT report2_90 2006-2
-28 14:46:29
LAS_NEW GPODB.EMEDCHINA.NET SELE_LAS_NEW gpodb 2007-1
-19 09:52:01
LAS_NEW SSISS.EMEDCHINA.NET USERTSP ssiss 2007-1
-22 10:03:29

已选择8行。

SQL> DROP PUBLIC DATABASE LINK DATADB;
DROP PUBLIC DATABASE LINK DATADB
*
ERROR
位于第 1 :
ORA-02024:
未找到数据库链接


SQL> ALTER SYSTEM SET GLOBAL_NAMES = TRUE;

系统已更改。

SQL> DROP PUBLIC DATABASE LINK DATADB;
DROP PUBLIC DATABASE LINK DATADB
*
ERROR
位于第 1 :
ORA-02024:
未找到数据库链接


SQL> ALTER SYSTEM SET GLOBAL_NAMES = FALSE;

系统已更改。

看来常规的办法已经行不通了。由于数据库链已经创建了很长的时间,产生问题的原因可能已经无法找到,不过现在可以做的是至少找到无法产生的原因。

SQL> ALTER SESSION SET SQL_TRACE = TRUE;

会话已更改。

SQL> DROP PUBLIC DATABASE LINK DATADB;
DROP PUBLIC DATABASE LINK DATADB
*
ERROR
位于第 1 :
ORA-02024:
未找到数据库链接


SQL> ALTER SESSION SET SQL_TRACE = FALSE;

会话已更改。

TRACE文件中没有找到具体的错误原因,于是新建立一个数据库链,并对删除操作进行trace

SQL> CREATE PUBLIC DATABASE LINK TEST;

数据库链接已创建。

SQL> ALTER SESSION SET SQL_TRACE = TRUE;

会话已更改。

SQL> DROP PUBLIC DATABASE LINK TEST;

数据库链接已丢弃。

SQL> ALTER SESSION SET SQL_TRACE = FALSE;

会话已更改。

进行了简单的对比后,仍然找不到导致删除失败的原因。不过到是找到了一个解决问题的方法。

DROP PUBLIC DATABASE LINKtrace文件看,Oracle在删除数据库链时,对数据字典进行的修改只有一个,就是从link$表中将对应的记录删除。那么只要将需要删除的数据库链对应的记录从表中清除掉就可以了。当然,即使从TRACE文件上看,只包含了这一个操作,仍然不建议采用这样的方法去操作,毕竟,对数据字典进行操作是危险的。

于是查看了一下Metalink,检查是否存在类似的问题,结果很快就查到了问题的真正原因:

如果Oracleglobal_name仅包括db_name,也就是说DB_DOMAIN的值为空。那么这个时候建立的数据库链,在数据库修改全局名GLOBAL_NAME之后(修改为db_name.db_domain格式),会无法删除。

如果要产生数据库链,必须将GLOBAL_NAME改回DB_NAME格式,即去掉后面的DOMAIN,但是这个时候,RENAME操作会自动添加域名,使得Oracle全局名无法恢复到初始状态。

SQL> SELECT * FROM GLOBAL_NAME;

GLOBAL_NAME
-----------------------------------------
ORCL.EMEDCHINA.NET

SQL> ALTER DATABASE RENAME GLOBAL_NAME TO ORCL;

数据库已更改。

SQL> SELECT * FROM GLOBAL_NAME;

GLOBAL_NAME
-----------------------------------------
ORCL.EMEDCHINA.NET

这个错误本来是8i上的,不知道为什么9201又重现了这个问题。

Oracle给出的解决问题的方法居然是UPDATE PROPS$。通过修改PROPS$将数据库的GLOBAL_NAME修改回原来的值。删除数据库链后将GLOBAL_NAME恢复,并重建目前所有的数据库链。

Oracle在给出这个方法的时候强调了这是一种不支持的方法。说实话,我认为Oracle提供的方法还没有直接从LINK$中删除记录方便呢,反正同样都是修改数据字典,更新PROPS$表还需要重新RENAME并重建索引。

如果没有必要,其实最好的方法是不去处理,如果一定要删除的话,最好先做好备份。

yangtingkun 发表于:2007.02.01 17:38 ::分类: ( ORACLE ) ::阅读:(764次) :: 评论 (4)
re: PUBLIC数据库链无法删除的问题(一) [回复]

我以前也遇到类似的问题:
http://space6212.itpub.net/post/12157/259607

解决后,后来无法重现这现象

space6212 评论于: 2007.02.02 10:06
re: PUBLIC数据库链无法删除的问题(一) [回复]

嗯,你的global_name无法rename到仅包含db_name,所以你无法重现这个错误。

yangtingkun 评论于: 2007.02.02 10:29
re: PUBLIC数据库链无法删除的问题(一) [回复]

laughing
原来不用这么麻烦的你写的Database link 名字是不全的
所以有这样的错误ORA-02024: 未找到数据库链接
select OBJECT_NAME from dba_objects where object_type='DATABASE LINK';
drop public database link object_name
我遇到的问题就是这样解决的

洁 评论于: 2007.11.09 13:58
re: PUBLIC数据库链无法删除的问题(一) [回复]

呵呵,还不至于犯这么低级的错误
这个问题是由于GLOBAL_NAME修改名称造成的,不是名字没有写全那么简单。

yangtingkun 评论于: 2007.11.09 16:41

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...