您的位置:首页 > 数据库 > Oracle

Oracle global database name与db link的纠缠关系

2016-06-08 11:21 811 查看
ORACLE数据库中GlobalDatabaseName与DBLINKS的关系还真是有点纠缠不清,在说清楚这个关系前,我们先来了解一下GlobalDatabaseName的概念GlobalDataBaseName概念1.Whatisaglobaldatabasename?-------------------------------------------------------------------------------Theglobaldatabasenameistheuniquenameofthedatabase.Inadistributeddatabasesystem(asetofdatabasesstoredonmultiplecomputersthattypicallyappearstoapplicationsasasingledatabase)theglobaldatabasenameensuresthateachdatabaseisdistinctfromallotherdatabasesinthesystem.Oracleformsadatabase'sglobaldatabasenamebyprefixingthedatabase'snetworkdomainwiththeindividualdatabase'sname.Forexample:sales.us.oracle.comandsales.uk.oracle.com.TheglobaldatabasenamedefaultstoDB_NAME.DB_DOMAINandthisvalueismarkedatdatabasecreationtime.IfyouchangetheDB_NAMEorDB_DOMAINafterthedatabasehasbeencreated,thevaluefortheglobaldatabasename(GLOBAL_NAME)willnotchange.说简单一点,globaldatabasename就是用来唯一标识数据库的东东。globaldatabasename由两部分组成,DB_NAME和DB_DOMAIN。在创建dblink的时候,Oracle会自动将db_domain作为后缀添加上去。而且一旦加入就很难变更。所以在进行高级复制、Streams复制等配置时,最好首先将多个节点的global_name规划好。如何查看GlobalDatabaseName

SQL>select*fromglobal_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM
SQL>

如下所示,可以知道global_name为一个视图。

SQL>selectobject_name,object_typefromdba_objectswhereobject_name=upper('global_name');
OBJECT_NAMEOBJECT_TYPE
-----------------------------------------------------------------------
GLOBAL_NAMEVIEW
GLOBAL_NAMESYNONYM

视图global_name的定义可以从DBA_VIEWS里面查看,如下所示,它来源于sys.props$内部表
selectvalue$fromsys.props$wherename='GLOBAL_DB_NAME'
那么参数global_name与GlobalDatabaseName又没有区别呢?其实参数global_name仅仅表示指定数据库的链接是否需要和它所连接的数据库相同的名称。
GLOBAL_NAMESspecifieswhetheradatabaselinkisrequiredtohavethesamenameasthedatabasetowhichitconnects.

SQL>showparameterglobal_name
NAMETYPEVALUE
--------------------------------------------------------------
global_namesbooleanFALSE
SQL>

所以两者完全是两个不同的概念,但是global_name也很重要,因为它的值会影响DBLINK.接下来,我们来创建一个DBLink,如下所示

SQL>select*fromglobal_name;
GLOBAL_NAME
-------------------------------------
KKK.REGRESS.RDBMS.DEV.US.ORACLE.COM
SQL>CREATEPUBLICDATABASELINK"TEST"
CONNECTTO"test"IDENTIFIEDBYtest1111
USING'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=
(PROTOCOL=TCP)(HOST=192.168.27.109)(PORT=1521)))
(CONNECT_DATA=(SERVICE_NAME=QWR)))';
Databaselinkcreated.
SQL>




如上所示,我创建的DBLink名字为TEST,但是你查询DBA_DB_LINKS时,你会发现链接服务器自动加上了域名,变成了TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM,当你查询时,使用TEST或TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM都OK。

SQL>SELECT*FROMDUAL@TEST;
D
-
X
SQL>SELECT*FROMDUAL@TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM;
D
-
X
SQL>




当GlobalDatabaseName只有DB_NAME,但是没有DB_DOMAIN时,此时,如果创建的DBLink是没有db_domain作为后缀添加上去的,你查询时,就必须使用全名TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM,不能像上面那样使用TEST,否则会报ORA-02019:connectiondescriptionforremotedatabasenotfound错误。

SQL>select*fromglobal_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
EPPS
SQL>CREATEPUBLICDATABASELINK"TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM"
2CONNECTTO"test"IDENTIFIEDBYtest1111
3USING'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=
(PROTOCOL=TCP)(HOST=192.168.27.109)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=QWR)))';
Databaselinkcreated.
SQL>SELECT*FROMDUAL@TEST;
SELECT*FROMDUAL@TEST
*
ERRORatline1:
ORA-02019:connectiondescriptionforremotedatabasenotfound
SQL>SELECT*FROMDUAL@TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM;
D
-
X
SQL>




DB_LINK与GLOBAL_NAMES参数的关系
当GLOBAL_NAMES为TURE时,影响的是创建数据库链接的那个库对数据库链接的使用。而不是链接到该数据库的链接服务器的使用。也就是说,如果一个库(实例)的global_names参数设值为TRUE,则该库连接其他库的数据库链接,其名称必须要与被连接的库的global_name相同,是否有点绕口,那么从下面实验看看。
服务器B

SQL>showparameterglobal_names;
NAMETYPEVALUE
-----------------------------------------------------------------------------
global_namesbooleanFALSE
SQL>select*fromglobal_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
KKK.REGRESS.RDBMS.DEV.US.ORACLE.COM

服务器A

SQL>showparameterglobal_name;
NAMETYPEVALUE
-----------------------------------------------------------------------------
global_namesbooleanFALSE
SQL>select*fromglobal_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
SCM2.REGRESS.RDBMS.DEV.US.ORACLE.COM

在服务器B上创建链接服务器,链接到服务器A

SQL>CREATEPUBLICDATABASELINK"LINK1"
2CONNECTTO"test"IDENTIFIEDBYtest1111
3USING'SERVER_A';
Databaselinkcreated.
SQL>SELECT*FROMDUAL@LINK1;
D
-
X

在服务器A上启用参数global_names,设置为TRUE。

SQL>showparameterglobal_names;
NAMETYPEVALUE
-----------------------------------------------------------------------------
global_namesbooleanFALSE
SQL>altersystemsetglobal_names=true;
Systemaltered.
SQL>

然后在服务器B上,再次创建链接服务器LINK2,如下所示

SQL>CREATEPUBLICDATABASELINK"LINK2"
2CONNECTTO"test"IDENTIFIEDBYtest1111
3USING'SERVER_A';
Databaselinkcreated.
SQL>SELECT*FROMDUAL@LINK2;
D
-
X

从上可以看出,服务器B上的global_names设置为TRUE是不影响服务器A上的DBLINK的,那么在服务器A上,将参数global_names设置为TRUE呢?

SQL>altersystemsetglobal_names=true;
Systemaltered.
SQL>SELECT*FROMDUAL@LINK1;
SELECT*FROMDUAL@LINK1
*
ERRORatline1:
ORA-02085:databaselinkLINK1.REGRESS.RDBMS.DEV.US.ORACLE.COMconnectsto
SCM2.REGRESS.RDBMS.DEV.US.ORACLE.COM
SQL>SELECT*FROMDUAL@LINK2;
SELECT*FROMDUAL@LINK2
*
ERRORatline1:
ORA-02085:databaselinkLINK2.REGRESS.RDBMS.DEV.US.ORACLE.COMconnectsto
SCM2.REGRESS.RDBMS.DEV.US.ORACLE.COM




此时我们来创建一个与被链接数据库global_name一致的DBLink,如下所示

SQL>showparameterglobal_names
NAMETYPEVALUE
-----------------------------------------------------------------------------
global_namesbooleanTRUE
SQL>select*fromglobal_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
KKK.REGRESS.RDBMS.DEV.US.ORACLE.COM
SQL>
SQL>
SQL>CREATEPUBLICDATABASELINKSCM2
2CONNECTTO"test"IDENTIFIEDBYtest1111
3USING'SERVER_A';
Databaselinkcreated.
SQL>SELECT*FROMDUAL@SCM2;
D
-
X

另外,我们来看看如何修改GlobalDatabaseName,如下所示

SQL>select*fromglobal_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
KKK.REGRESS.RDBMS.DEV.US.ORACLE.COM
SQL>alterdatabaserenameglobal_nametoTEST;
Databasealtered.
SQL>select*fromglobal_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM
SQL>




如上所示,修改renameglobal_name只能修改DB_NAME部分,不能修改DB_DOMAIN,没有常规的办法去掉"."分隔符后面部分,要去掉只能用update语句

updateglobal_namesetglobal_name='xxxx';

但是网上很多大神的建议都是不要更新global_name.例如AskTom里面HowtochangethevalueinGLOBAL_NAMEtable就提到
youdon'tUPDATEaglobal_namelikethat.YouNEVERupdateanydatadictionarytable--never.
另外在老熊的博客Oracle数据库的global_name里面,提到不要直接用updateglobal_namesetglobal_name=''将global_name设置为空,否则数据库不能启动,会报ORA-00600[18061]或ORA-00600[18062]这样的错误。除非万不得已,不要去更新global_name视图,即使更新,也不要去更新global_name的基表props$,更不要将global_name更新为空。
参考资料:
http://www.laoxiong.net/oracle_global_name.html
http://www.laoxiong.net/database_link_global_names.html
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1392538395678
https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=265322928260367&parent=DOCUMENT&sourceId=742140.1&id=115499.1&_afrWindowMode=0&_adf.ctrl-state=1hwssfmxb_203
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: