分布式数据库组件——Database Link

来源:互联网 发布:windows凭据 普通凭据 编辑:程序博客网 时间:2024/05/18 13:09

今天我们一起聊聊Database Link。

 

Database Link(下面简称为DBLink)是Oracle分布式数据构建的一个基石技术。通过DBLink,将两个物理上独立的数据库连接了起来,使得客户端有可能透明的访问两个数据库上的数据和对象。而客户端角度看,访问的数据库好像只有一个。

 

 

分布式数据库是现代分布式系统的一个重要组件。传统集中式数据库中,数据库实例可能有多个,但是数据库(文件)只有一份。进行的查询都是在一个数据库中进行,进行的事务都是在一个实例下完成。

 

分布式数据库的一个特性就是实例是多个,同时数据库也是多个,分布在不同的物理服务器上。由于对象和实例的分布特性,所以查询一个数据,访问的实例和数据库可能是多个,进行dml操作的事务也随着上升为分布式事务。

 

 

DB Link简介

 

简单的说,DB Link就是建立在两个数据库服务器上面的单向链接数据通道。从数据库对象的角度看,DB Link是一个对象,结构和定义是保存在数据库服务器上的。当客户端登录到数据库服务器A上后,通过调用在A上定义的DB Link,可以访问到数据库服务器B上的数据对象。但是,这种连接是一种单向链接,登录到服务器B上的客户端是不能借这个链接访问到数据库服务器A上的对象。因为DB Link的定义是保存在服务器A的数据字典中。

 

 

首先我们看一个小例子。我们有两个数据库服务器wilson和orcl。Wilson是一台运行在CentOS上的Oracle11g服务器,而Orcl是在windows环境下。现在要建立一条从orcl访问到wilson数据库的dblink。

 

 

//首先登录orcl

SQL> conn scott/tiger@orcl;

Connected to Oracle Database10g Enterprise Edition Release 10.2.0.1.0

Connected as scott

 

SQL>create database link DB_WILSON

 2   connect to HR identified by HR

 3   using 'WILSON';

 

Database link created

 

 

首先,我们登录orcl,以soctt用户登录系统。使用create database link语句建立一个database link。语句的含义:创建一个dblink,连接到本地命名服务wilson对应的数据库服务器上,连接的时候使用HR/HR作为用户名和密码。

 

注意:create database link语句是需要用户具有create database link的系统权限。如果没有,就不能创建。

 

创建之后,我们发现创建的dblink名称不为db_Wilson,而是加入了wilson的全局网络名称。为:DB_WILSON.REGRESS.RDBMS.DEV.US.ORACLE.COM;使用DB Link的方法,如下:

 

 

SQL> conn scott/tiger@orcl;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as scott

 

SQL> select * fromjobs@DB_WILSON.REGRESS.RDBMS.DEV.US.ORACLE.COM;

 

JOB_ID    JOB_TITLE                          MIN_SALARY MAX_SALARY

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

AD_PRES   President                               20080     40000

(篇幅原因,有省略……

PR_REP    Public Relations Representative          4500     10500

 

19 rows selected

 

 

使用“对象名[调用方法]@db_link_name”,就可以访问到远程对象。jobs数据表是数据库范例表HR Schema下的数据信息。

 

 

在进行下面的内容介绍前,说明两个问题。

 

首先,是访问db link的数据表@后面的名称问题。在设计环境中,可以使用同义词synonym技术将@后面的内容屏蔽掉,让应用层面做到透明化。

 

其次,就是oracle10g与11g进行交互时候的小技巧。在Oracle11g之前,数据库密码是不区分大小写的。内部保存校验密码的时候,都是将其转换为大写字母后进行处理。建立dblink的时候,输入的登录用户名,密码(connect to HR identified by HR),也是用大写字母进行密码保存作为固定用户的登录信息。这种机制在oracle10g以及之前的版本中都没有什么问题。当连接涉及到oracle11g的时候,就会出现一些问题。

 

从Oracle11gR1开始,密码大小写不识别的情况被修正了。如果Oracle11g的用户密码含小写字符,那么我们在Oracle10g端创建dblink的时候,即使输入了正确的密码字符。Oracle10g会自动将其转换为大写字符。连接11g的时候,使用这个大写字符进行验证,自然会报错误。这也算是一个不大不小的陷阱了。

 

为了避免这个陷阱,笔者在实验前,执行了密码变换,将密码转为了大写。

 

//login the oracle 11g

 

SQL> conn sys/sys@wilson as sysdba;

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0

Connected as SYS

 

SQL> alter user HR identified by HR;

 

User altered

 

 

 

下面我们来看看dblink的本质。我们知道,客户端连接到数据库实例之后,在实例上是通过server process进行代理进行操作。一直以来,操作本地数据库(local database)的时候,server process与实例进程进行交互,获取本地数据库数据。那么,在使用dblink的时候,这个过程是怎么样的呢?

 

我们检查一下进程情况。在确保没有其他链接到oracle11g服务器的情况下,我们检查服务器所在Linux的进程情况。

 

 

//查看进程连接

[oracle@oracle11g ~]$ ps -ef | grep ora

(篇幅原因,省略部分后台进程列表……

oracle   5727    1 0 15:12 ?       00:00:00 ora_smco_wilson

oracle   5729    1 0 15:12 ?       00:00:00 ora_w000_wilson

oracle   5749    1 0 15:15 ?       00:00:00 oraclewilson (LOCAL=NO)

oracle   5751    1 3 15:15 ?       00:00:00 ora_j000_wilson

oracle   5753    1 1 15:15 ?       00:00:00 ora_j001_wilson

oracle   5754 5517 0 15:16 pts/0   00:00:00 ps -ef

oracle   5755 5517 0 15:16 pts/0   00:00:00 grep ora

 

 

注意,当我们使用过dblink后,在link的remote数据库上出现了一个server process进程,而且是长期保存。根据我们的之前blog中对server process的实验,server process是一个忠实于client的进程对象。只要client存在,并且保持连接,server process会一直驻留在服务器进程列表中。

 

现在我们看到了有server process驻留在里面,说明存在与dblink相关的一个client,在与其建立通信调用关系。那么,究竟是谁呢???

 

SQL> select saddr,sid,serial#,paddr,user#,username,status,osuser,PROGRAM from v$session where paddr in (select addr from v$process where spid in(5749));

 

SADDR          SID   SERIAL# PADDR        USER# USERNAME       STATUS  OSUSER                        PROGRAM

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

38295E1C        35        11 38BC56E4  85HR  INACTIVE SYSTEMORACLE.EXE

 

 

根据OS上面的SPID编号(5749),我们定位了会话的信息(SID=35)。使用的数据库用户是HR,程序名称为ORACLE.exe。

 

到这里,我们似乎可以猜到dblink的工作原理了。ORACLE.exe是Oracle在Windows下的实例程序进程,其中的Server process和后台进程都被实现为线程模型。但是在使用dblink连接到remote database的时候,却是充当了program客户端的角色。

 

在回顾一下我们建立dblink的参数:一个本地命名服务名、登录用户名/密码。这些信息完全具备了客户端登录服务器的全部要素。那么,一切都可以清楚了。

 

当我们使用dblink,要求访问remote数据对象数据时候。本地实例上的进程(server process)会去充当客户端程序的角色,利用本地命名服务和用户名密码连接远程服务器。之后的过程同一般的客户端连接服务器没有任何差距了。

 

 

当访问数据(如select),实际上是将数据从远程的数据库服务器上,通过dblink对应的连接线路,传递到本地数据库服务器实例上,再进行额外的处理。如果直接返回结果,就将remote实例上的数据,经过local实例,传回到客户端。的确是很漫长的过程……如果需要和local数据库上的数据表进行额外的关联查询或者连接,就在local实例上进行。