刪除 Dblink 報錯 ORA-02024: database link not found

hurp_oracle發表於2014-08-18

database link概述 
database link是定義一個資料庫到另一個資料庫的路徑的物件,database link允許你查詢遠端表及執行遠端程式。在任何分散式環境裡,database都是必要的。另外要注意的是database link是單向的連線。
在建立database link的時候,Oracle再資料字典中儲存相關的database link的資訊,在使用database link的時候,Oracle透過Oracle Net用使用者預先定義好的連線資訊訪問相應的遠端資料庫以完成相應的工作。
建立database link之前需要確認的事項:
確認從local database到remote database的網路連線是正常的,tnsping要能成功。
確認在remote database上面有相應的訪問許可權。
database link分類

型別 Owner 描述
Private 建立database link的user擁有該database link 在本地資料庫的特定的schema下建立的database link。只有建立該database link的schema的session能使用這個database link來訪問遠端的資料庫。同時也只有Owner能刪除它自己的private database link。
Public Owner是PUBLIC. Public的database link是資料庫級的,本地資料庫中所有的擁有資料庫訪問許可權的使用者或pl/sql程式都能使用此database link來訪問相應的遠端資料庫。
Global Owner是PUBLIC. Global的database link是網路級的,When an Oracle network uses a directory server, the directory server automatically create and manages global database links (as net service names) for every Oracle Database in the network. Users and PL/SQL subprograms in any database can use a global link to access objects in the corresponding remote database.
Note: In earlier releases of Oracle Database, a global database link referred to a database link that was registered with an Oracle Names server. The use of an Oracle Names server has been deprecated. In this document, global database links refer to the use of net service names from the directory server.

建立dblink所需的許可權

Privilege Database Required For
CREATE DATABASE LINK Local Creation of a private database link.
CREATE PUBLIC DATABASE LINK Local Creation of a public database link.
CREATE SESSION Remote Creation of any type of database link.

database link的使用 
基本語法
CREATE [SHARED][PUBLIC] database link link_name

      [CONNECT TO [user][current_user] IDENTIFIED BY password]
      [AUTHENTICATED BY user IDENTIFIED BY password]
      [USING 'connect_string']
說明:
1) 許可權:建立資料庫連結的帳號必須有CREATE DATABASE LINK或CREATE PUBLIC DATABASE LINK的系統許可權,用來登入到遠端資料庫的帳號必須有CREATE SESSION許可權。這兩種許可權都包含在CONNECT角色中(CREATE PUBLIC DATABASE LINK許可權在DBA中)。一個公用資料庫連結對於資料庫中的所有使用者都是可用的,而一個私有連結僅對建立它的使用者可用。由一個使用者給另外一個使用者授權私 有資料庫連結是不可能的,一個資料庫連結要麼是公用的,要麼是私有的。
2)link :  當source端的資料庫GLOBAL_NAME=TRUE時,link名必須與遠端資料庫的全域性資料庫名global_name)相同;否則,可以任意命名。

3)current_user使用該選項是為了建立global型別的dblink。在分散式體系中存在多個資料庫的話。如果想要在每一個資料庫中都可以使用同樣的名字來訪問資料庫a,那在每個資料庫中都要建立一個到資料庫a的db_link,太麻煩了。所以現在有這個選項。你只要建立一次。所有的資料庫都可以使用這個db_link來訪問了。要使用這個特性,必須有oracle nameserver或者ORACLE目錄伺服器。並且資料庫a的引數global_names=true.具體我也沒有建立過,沒有這個環境。
4)connectstring:連線字串,tnsnames.ora中定義遠端資料庫的連線串,也可以在建立dblink的時候直接指定。
5)username、password:遠端資料庫的使用者名稱,口令。如果不指定,則使用當前的使用者名稱和口令登入到遠端資料庫,當建立connected user型別的dblink時,需要如果採用資料字典驗證,則需要兩邊資料庫的使用者名稱密碼一致。

刪除 Dblink 報錯 ORA-02024: database link not found 的解決方法  ------導致這種錯誤共有兩種情況具體見metalink文件

Cannot drop a database link after changing the global_name ORA-02024 [ID 382994.1]

ORA-02024: Database Link Not Found [ID 1058949.1]

一 .  DBLINK所有者不一致造成

我們來演示一下這種情況。

 

--建立dblink

SQL> conn system/admin;

已連線。

SQL>  create database link hurp connect to system identified by hurp using '

      (DESCRIPTION =

      (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.125)(PORT = 1521))

       )

      (CONNECT_DATA =

      (SERVICE_NAME = newccs)

       )

       ) ';

 

資料庫連結已建立。

SQL> select name from v$database@hurp;

 

NAME

---------

hurp

 

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

會話已更改。

 

SQL> select * from all_db_links;

OWNER      DB_LINK    USERNAME   HOST       CREATED

---------- ---------- ---------- ---------- -------------------

SYSTEM     HURP       SYSTEM                2013-02-23 09:12:45

 

----用public刪除

SQL> drop public database link hurp;

drop public database link hurp

                          

第 1 行出現錯誤:

ORA-02024: 未找到資料庫連結

--用本地使用者刪

SQL> drop database link hurp;

資料庫連結已刪除。

二、Global_name 造成

       If the value of the GLOBAL_NAMES initialization parameter is TRUE, then the database link must have the same name as the database to which it connects. If the value of GLOBAL_NAMES is FALSE, and if you have changed the global name of the database, then you can specify the global name.

       The maximum number of database links that can be open in one session or one instance of an Oracle RAC configuration depends on the value of the OPEN_LINKS and OPEN_LINKS_PER_INSTANCE initialization parameters.

       Global_names 是一個布林值,global_names的作用是建立db link時是否強制使用遠端資料庫的global_name,如果global_names=true,則db link name必須要求是remote database的global_name,否則建立之後db link 不能連同,預設值是false。 當global_name 為False時,如果我們修改了global_name,那麼在dblink中也要相應的指定global_name. 並且當我們修改了global_name後,之前存在的我們dblink也無法刪除。

       注:Global_name 是由db_name.db_domain構成。
           在上面提到,當global_names為False的情況下,如果我們修改了global_name,之前建立的dblink 在刪除的時候也會包ORA-02024的錯誤。 甚至我們把global_name 改變成原來的值,也無法刪除。 因為這種改變沒有生效。 除非我們更新props$ 表。

先來驗證global_name 修改後生效問題。

SQL> select * from global_name;

GLOBAL_NAME

----------------------------------------------------------------------------

HURP


SQL> alter database rename global_name to newccs.tianlesoftware.com;

資料庫已更改。

 

SQL> select * from global_name;

GLOBAL_NAME

----------------------------------------------------------------------------

NEWCCS.TIANLESOFTWARE.COM

 

SQL> alter database rename global_name to newccs;

資料庫已更改。

 

SQL> select * from global_name;

GLOBAL_NAME

----------------------------------------------------------------------------

NEWCCS.TIANLESOFTWARE.COM

--這裡並沒有生效。

 

SQL> drop database link hurp;

drop database link hurp

                   *

第 1 行出現錯誤:

ORA-02024: 未找到資料庫連結

       從上面的操作,驗證瞭如果僅透過alter 命令,是無法讓global_name 還原成原來的值的。並且當global_name 發生改變後,已經存在的dblink也無法刪除。

       解決這個問題的方法,就是用sys使用者來修改props$表:

       SQL> update props$ set value$ = '' where name ='GLOBAL_DB_NAME';

 

 

示例:

SQL> conn / as sysdba;

已連線。

SQL> update props$ set value$ = 'NEWCCS' where name ='GLOBAL_DB_NAME';

 

已更新 1 行。

SQL> commit;

提交完成。

 

然後切換到dblink 的使用者,刪除dblink:

SQL> conn system/hurp;

已連線。

SQL> drop database link hurp;

資料庫連結已刪除。

如果還報這種錯誤,可以重新整理三次shared pool, 在執行drop命令:

alter system flush SHARED_POOL;

alter system flush SHARED_POOL;

alter system flush SHARED_POOL;

如果重新整理shared pool後還無法drop,那麼就需要重啟DB,在刪除了。



刪除DBLINK

dblink的相應屬性對應了Oracle的資料字典link$,任何針對dblink的操作都是操作該資料字典。在9i的時候,如果Oracle的global_name僅包括db_name,也就是說DB_DOMAIN的值為空。那麼這個時候建立的資料庫鏈,在資料庫修改全域性名GLOBAL_NAME之後(修改為db_name.db_domain格式),會無法刪除。
如果要產生資料庫鏈,必須將GLOBAL_NAME改回DB_NAME格式,即去掉後面的DOMAIN,但是這個時候,RENAME操作會自動新增域名,使得Oracle全域性名無法恢復到初始狀態。因此在這情況下,如果需要刪除dblink,只能直接操作link$資料字典

delete from link$ where owner#=user_id and name=dblink_name

當然直接運算元據字典是危險的,最好做好備份,然後再進行操作。




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29446986/viewspace-1253281/,如需轉載,請註明出處,否則將追究法律責任。

相關文章