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分类
创建dblink所需的权限
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 时,需要如果采用数据字典验证,则需要两边数据库的用户名密码一致。
创建 database link 选项说明
共享链接更多资料
共享数据库链接是指该链接的多个用户可以共享同一个底层网络连接。例如,在有四位用户的MTS(多线程服务器)环境下,每一个共享服务器进程都将与远程服务器有一个物理链接,这四位用户共享这两个链接。
表面上,共享链接乍一听起来像是一件好事。在某些环境下的确如此,但是,当你考虑使用共享链接时,应当意识到这有许多局限性和警告:
如果你使用一个专用的服务器连接来连接到你的本地数据库,链接只能在你从那些连接中创建的多重会话间共享 。在MTS环境里,每一个共享服务器进程潜在地打开一个链接。所有的会话被同一共享服务器进程提供并且分享被那个进程打开的任意共享链接。因为在MTS环境里的一个共享服务器进程能够服务于许多用户连接,共享链接的使用可能导致打开的链接远多于所必须的链接。用SHARED关键字建立共享数据库链接。还必须使用AUTHENTICATED BY 子句在远程系统上指定一有效的用户名和口令。如下命令建立一个共享的、公用的、连接用户数据库链接:
CREATE SHARED PUBLIC database link GNIS
AUTHENTICATED BY DUMMY_USER IDENTIFIED BY SECRET
USING ‘GNIS’;
要获得创建链接和管理分布式系统的更多资料,请查阅 Oracle Technology Network (http://otn.oracle.com/)。
使用 AUTHENTICATED BY 子句稍微有些困扰,但是由于实现共享链接的方式安全性决定它是必须的。这个例子中的用户名和口令 DUMMY_USER/SECRET 必须在远程系统上有效。然而,远程系统上使用的帐户仍就是连接用户的帐户。如果我以 JEFF/SECRET 登陆到我的本地数据库并使用我刚建好的共享链接,将会发生以下一系列事件:
为了打开链接,Oracle 使用 DUMMY_USER/SECRET 向远程数据库授权。然后,Oracle 试图使用HMAD/SECRET 使我登陆到远程数据库。共享链接的主要目的是减少两个数据库服务器之间的底层网络连接数量。它们最适合于MTS环境,在那你拥有大量的通过这一链接访问远程数据库的用户。观念上,你想让用户数量超过共享服务器进程的数量。那么你可以通过为每一共享服务器进程打开一个链接而不是每位用户打开一个链接的方法,节省资源。
database link使用方式
取值 | 说明 |
---|---|
不指定 | 默认值建立一个private的database link |
PUBLIC | 公共连接,这样的连接可以被数据的所有的用户访问 |
不使用 TNS Name 一例:
CREATE database link link_name
CONNECT TO user IDENTIFIED BY screct
USING '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = sales.company.com)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = sales)
)
)';
database link的使用
-- 最简单的用法
SELECT * FROM table_name@database link;
-- 不想让使用的人知道 database link 的名字的时候
-- 建一个别名包装一下
CREATE SYNONYM table_name FOR table_name@database link;
SELECT * FROM table_name;
-- 或者,也可以建立一个视图来封装
CREATE VIEW table_name AS SELECT * FROM table_name@database link;
database link删除
-- 删除 public 类型的 database link
DROP PUBLIC database link link_name;
-- 删除非 public 类型的 database link
-- 注意:只有 owner 自己能删除自己的非 public 类型 database link
DROP database link link_name;
查看 database link 的信息
查看系统 database link 的基本信息
DBA_DB_LINKS (ALL_DB_LINKS/USER_DB_LINKS)
DBA_DB_LINKS 视图为每一定义的链接返回一行。OWNER 列和 DB_LINK 列分别显示了这一链接的所有者及名称。对公用数据库链接,OWNER 列将包含'PUBLIC'。如果你建立固定用户链接,用户名应在DBA_DB_LINKS 视图的 USERNAME 列里。ALL_DB_LINKS 视图和 USER_DB_LINKS 视图与 DBA_DB_LINKS 视图相类似-它们分别显示了你能够访问的所有链接及你所拥有的全部链接。
COL OWNER FOR A15
COL DB_LINK FOR A25
COL HOST FOR A25
COL USERNAME FOR A15
SELECT * FROM DBA_DB_LINKS;
DBA_OBJECTS (ALL_OBJECTS/USER_OBJECTS)
在这个视图里面只能查询到系统有那些database link以及他们的owner,创建时间等信息。
COL OWNER FOR A15
COL OBJECT_NAME FOR A25
COL OBJECT_TYPE FOR A25
SELECT OWNER,OBJECT_NAME,OBJECT_TYPE FROM DBA_OBJECTS WHERE OBJECT_TYPE LIKE 'database link';
查看保存的Fixed user database link所保存的用户密码,该密码是经过加密的。
这是比较危险的一件事,有必要对表sys.link$的权限进行限制。
col host for a15
col userid for a15
col passwordx for a40
col name for a20
select name, host, userid, passwordx from sys.link$;
通过database link去SELECT远程数据库的一个表也是一个事务吗?
select * from v$transaction;
-- 没有记录,说明没有事务
-- 通过database link连接远程数据库,select 其中一个表
select * from bbs_news@mylink
select * from v$transaction;
-- 发现有一条记录。
解释
因为本地数据库只是将对应的sql发送给远程数据库执行,接受remote db返回的结果,但他并不知道是否该sql修改了数据; 所以需要为select 语句也标示一个事务。
具体可以参考 otn 分布式数据库手册,所以在用database link远程访问时,要加上set transaction read only;
close database link
ALTER SESSION CLOSE database link sales;
其实,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
当然直接操作数据字典是危险的,最好做好备份,然后再进行操作。
利用dblink执行ddl
我们知道任何ddl语句都无法在dblink中直接执行,示例如下
SQL> desc db_test;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(38)
SQL> drop table db_test@DBLINK_CONNECTED_HR;
drop table db_test@DBLINK_CONNECTED_HR
*
ERROR at line 1:
ORA-02021: DDL operations are not allowed on a remote database
通过创建存储过程,使得能在dblink中执行ddl语句。 注意需在目标数据库的相应用户下创建存储过程 ,具体如下
SQL> create or replace procedure p_execute_ddl(p_ddl in varchar2)
2 as
3 begin
4 execute immediate p_ddl;
5 end;
6 /
删除目标数据库的表
SQL> exec p_execute_ddl@DBLINK_CONNECTED_HR('drop table db_test');
PL/SQL procedure successfully completed.
SQL> desc db_test;
ERROR:
ORA-04043: object db_test does not exist
dblink的限制
You cannot perform the following operations using database links:
Grant privileges on remote objects
Execute DESCRIBE operations on some remote objects. The following remote objects, however, do support DESCRIBE operations:
Tables
Views
Procedures
Functions
Analyze remote objects
Define or enforce referential integrity
Grant roles to users in a remote database
Obtain nondefault roles on a remote database. For example, if jane connects to the local database and executes a stored procedure that uses a fixed user link connecting as scott, jane receives scott's default roles on the remote database. Jane cannot issue SET ROLE to obtain a nondefault role.
Execute hash query joins that use shared server connections
Use a current user link without authentication through SSL, password, or NT native authentication