ORACLE 中极易混淆的几个 NAME 的分析和总结

我们知道,Oracle中的各种NAME会在我们的各个配置文件中经常出现,大致有以下这些:

在init.ora中有DB_NAME,INSTANCE_NAME,SERVICE_NAME

配置DG的时候,为了区分主备库,还要使用DB_UNIQUE_NAME

在操作系统中需要配置环境变量,ORACLE_SID

在listener.ora中有SID_NAMEGLOBAL_DBNAME

在tnsname.ora中有SERVICE_NAMESIDNET SERVICE NAME

那么这么多名字到底有哪些区别呢?我们在使用过程中,又要注意些什么问题呢?下面我来总结一下:

这么多名字中,有些是初始化参数,如DB_NAME,DB_QUNIQUE_NAME,DB_DOMAIN,GLOBAL_NAME

有些则只是一种叫法或者说是概念(并没有一个地方可以去设置它),如NET SERVICE NAME

有些则是某些表/视图中的字段名,如V$INSTANCE视图的INSTANCE_NAME

有些则是环境变量中的叫法,如ORACLE_SID

亦或是监听或客户端配置文件中设置的参数,如SID,SID_NAME,SERVICE_NAME,GLOBAL_DBNAME

DB_NAME:

对一个数据库(Oracle database)的唯一标识。这种表示对于单个数据库是足够的,但是随着由多个数据库构成的分布式数据库的普及,这种命令数据库的方法给数据库的管理造成一定的负担,因为各个数据库的名字可能一样,造成管理上的混乱。为了解决这种情况,引入了Db_domain参数,这样在数据库的标识是由Db_name和Db_domain两个参数共同决定的,避免了因为数据库重名而造成管理上的混乱。这类似于互连网上的机器名的管理。我们将Db_name和Db_domain两个参数用’.’连接起来,表示一个数据库,并将该数据库的名称称为Global_name,即它扩展了Db_name。Db_name参数只能由字母、数字、’_’、’#’、’$’组成,而且最多8个字符。特别要注意这个限制,有的时候会掉坑里,我就掉过一次T_T

DB_DOMAIN:

定义一个数据库所在的域,该域的命名同互联网的’域’没有任何关系,只是数据库管理员为了更好的管理分布式数据库而根据实际情况决定的。当然为了管理方便,可以将其等于互联网的域。

GLOBAL_NAME:

对一个数据库(Oracle database)的唯一标识,oracle建议用此种方法命令数据库。该值是在创建数据库是决定的,缺省值为Db_name.Db_domain。在以后对参数文件中Db_name与Db_domain参数的任何修改不影响Global_name的值,如果要修改Global_name,只能用ALTER
DATABASE RENAME GLOBAL_NAME TO <db_name.db_domain>命令进行修改,然后修改相应参数。

SERVICE_NAME:

该参数是oracle8i新引进的。在8i以前,我们用SID来表示标识数据库的一个实例,但是在Oracle的并行环境中,一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了Service_name参数,该参数对应一个数据库,而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为Db_name.
Db_domain,即等于Global_name。一个数据库可以对应多个Service_name,以便实现更灵活的配置。该参数与SID没有直接关系,即Service name不必与SID一样。

比方说我可以在设置环境变量的时候,设置ORACLE_SID=zlm,那么这个时候SID就是zlm,而在tnsnames.ora中,我可以把SERVICE_NAME改成zlm_SN

##tnsnames.ora

ZLM10G =  ##ZLM10G为NET SERVICE NAME

(DESCRIPTION =

(ADDRESS_LIST =

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

)

(CONNECT_DATA =

(SERVICE_NAME = zlm_SN)
##SERVICE_NAME为zlm_SN,与SID为zlm不同

)

)

可以看到,SERVICE_NAME用了刚才在netca中配置的zlm_SN,SID用了ORACLE_SID设置的zlm,并且把tnsnames.ora里系统自动添加的NET SERVICE NAME相关的内容删除了(即由pmon进程自动注册的2个动态监听),只留下自己配置的部分

注意,这里我还使用了netmgr配置了静态监听(从status UNKNOWN其实便可知),静态监听的目的,除了简化配置外,还可以提供在数据库未启动前仍能连接的功能,而不再是等数据库实例启动后,由pmon进程负责动态向监听注册服务,动态监听会通常比较滞后,启动监听后,要等若干分钟,才能看到服务被监听。

##listener.ora

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

(SID_NAME = PLSExtProc)

(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)

(PROGRAM = extproc)

)

(SID_DESC =

(GLOBAL_DBNAME = zlm_SN)

(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)

(SID_NAME = zlm)

)

)

经过上面的tnsnames.ora和linstener.ora的配置,当我们查看监听状态的时候,就会发现不同:

$lsnrctl status

......

Services Summary...

Service "PLSExtProc" has 1 instance(s).

Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...

Service "zlm_SN" has 1 instance(s).## 表示对应的SERVICE_NAME为zlm_SN

Instance "zlm", status
UNKNOWN, has 1 handler(s) for this service...  ##表示对应的INSTANCE_NAME为zlm,也即SID和ORACLE_SID

The command completed successfully

而通常情况下,我们会设置SERVICE_NAME和INSTANCE_NAME一致。这里还要注意的是,SERVICE_NAME虽然可以脱离INSTANCE_NAME搞别名,但是必须对应listener.ora里配置的GLOBAL_DBNAME,否则就算配好了静态监听,也是注册不了服务的

注意,数据库数据文件存放的路径,是根据DB_NAME来确定的,而对于单实例数据库而言,默认与SID和INSTANCE_NAME是一致的,当然,也可以不一致(有DB_DOMAIN的情况下),DBCA的时候可以选择,通常这3个参数在DBCA的时候确认下来后,就基本不再去修改了,那么数据文件路径也就确定下来了,如我的环境中:

数据文件就放在/u01/app/oracle/oradata/zlm下面

而跟踪日志就放在/u01/app/oracle/admin/zlm/bdump下面

过了片刻以后,再查看监听状态,发现自动还是会去动态注册一个和INSTANCE_NAME(SID)一致的SERVICE_NAME

Listening Endpoints Summary...

(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.91)(PORT=1521)))

(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC0)))

Services Summary...

Service "PLSExtProc" has 1 instance(s).

Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...

Service "zlm" has 1 instance(s).

Instance "zlm", status
READY, has 1 handler(s) for this service...

Service "zlmXDB" has 1 instance(s).

Instance "zlm", status READY, has 1 handler(s) for this service...

Service "zlm_SN" has 1 instance(s).

Instance "zlm", status UNKNOWN, has 1 handler(s) for this service...

Service "zlm_XPT" has 1 instance(s).

Instance "zlm", status READY, has 1 handler(s) for this service...

The command completed successfully

这样的话,我个人判断,如果不配置静态监听的话,pmon进程始终会去监听那里注册一个名字和INSTANCE_NAME(SID)一致的SERVICE_NAME,即便是已经在tnsnames.ora中修改了SERVICE_NAME=zlm_SN,而只有通过静态监听强制注册一个与INSTANCE_NAME(SID)不一致的SERVICE_NAME,才会被监听到

NET SERVICE NAME:

网络服务名,又可以称为数据库别名(database alias)。是客户端程序访问数据库时所需,屏蔽了客户端如何连接到服务器端的细节,实现了数据库的位置透明的特性。通常当我们用DBLINK连接数据库时,使用的就是这个名字,由USING关键字指定,USING
‘connect_string‘这里connect_string其实就是NET SERVICE NAME。

说到DBLINK还要提一点,就是当源数据库GLOBAL_NAME=TRUE时,link_name必须与远程数据库的全局数据库名global_name)相同;否则,可以任意命名。同样地,当我们用sqlplus system/[email protected]xxx来连接DB SERVER时,这个xxx就是NET
SERVICE NAME,我的环境中是ZLM10G,如:

ZLM10G =

(DESCRIPTION =

(ADDRESS_LIST =

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

)

(CONNECT_DATA =

(SERVICE_NAME = zlm_SN)

)

)

那么根据tnsnames.ora的配置,这里ZLM10G就是zlm_SN这个SERVICE_NAME所对应的NET SERVICE NAME

如果用sqlplus system/[email protected]是连不上DB SERVER的,只有用sqlplus system/[email protected]才行

[[email protected] ~]$ sqlplus system/[email protected]zlm

SQL*Plus: Release 10.2.0.5.0 - Production on Tue Jul 29 14:48:39 2014

Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

ERROR:

ORA-12560: TNS:protocol adapter error

Enter user-name:

[[email protected] ~]$ sqlplus system/[email protected]zlm10g

SQL*Plus: Release 10.2.0.5.0 - Production on Tue Jul 29 14:48:50 2014

Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

Connected to:

Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

注意,用@NET SERVICE NAME方式登录,必须保证数据库是open的,否则即便是用对了名字,也会出现这种情况:

[[email protected] ~]$ sqlplus system/[email protected]

SQL*Plus: Release 10.2.0.5.0 - Production on Tue Jul 29 14:46:16 2014

Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

ERROR:

ORA-01034: ORACLE not available

ORA-27101: shared memory realm does not exist

Linux-x86_64 Error: 2: No such file or directory

Enter user-name:

[[email protected] ~]$

实例(对应INSTANCE_NAME),就是管理相关库的内存结构的名字(由SGA、PGA、服务器进程、用户进程、后台进程等组成)

数据库(对应DB_NAME或GLOBAL_NAME),就是实际的磁盘上的文件(数据文件、日志文件、控制文件等),负责保存数据,但由对应的实例来操作它的数据

服务名(对应SERVICE_NAME),就是对外公布的名称,为网络监听服务

其实,在我们传统的概念里,数据库是一个统称,在Oracle中,你可以把“数据库”理解成一个大概念,也要把它理解成一个小概念

1、一个Oracle数据库系统中可以同时安装多个数据库,每一个数据库对应一个唯一的实例(1:1),但是OPS系统除外,可以多个实例同时对一个数据库操作,称为并行服务器(1:N),还有RAC架构,也是多个实例为一个数据库实例服务(1:N),另外还有ASM磁盘组实例,用于管理ASM这种OMF存储结构而诞生的实例,这些都是很容易混淆的概念。

2、SID即是INSTANCE_NAME,SERVICE_NAMES主要用在监听器中。

在listener.ora中有SID_NAME,GLOBAL_DBNAME,这里SID_NAME指数据库的运行的实例名,应该是和instance_name一致

而对于GLOBAL_DBNAME是listener配置的对外网络连接名称,在配置tnsname.ora时会考虑这个参数。这个参数可以任意的设置。注意:与GLOBAL_NAME的感念是不同的,GLOBAL_NAME=DB_NAME.DB_DOMAIN

另外有一点需要注意,一般我们会在listener.ora手工配置数据库实例的监听配置。但oracle可以通过pmon进程支持自动注册,这时自动注册的对外网络连接名称就会用到init.ora文件中SERVICE_NAME,有多个值的话就会注册多个监听服务,如zlm_SN,zlm_SN2。如果你还手工配置了一个GLOBAL_DBNAME=zlm_SN3的监听服务的话,那么对于实例INSTANCE_NAME=zlm就会有三个监听服务。这也就是之前提到过,通常GLOBAL_DBANME可以设置成和SERVICE_NAME一致,但不强求

在tnsname.ora中有SERVICE_NAME,SID

配置客户端的tnsname.ora时,要给出连接的数据库的IP及其连接的实例或服务

在监听配置中提到了对外网络连接名称,如果用SERVICE_NAME的话,就需要SERVICE_NAME=(GLOBAL_DBNAME或者SERVICE_NAME=(zlm_SN),zlm_SN可以替换成zlm_SN2,zlm_SN3,这里要求oracle已经自动注册到了监听器中,或者不写SERVICE_NAME=....
,而是写成SID=(zlm),都是可以的

ORACLE_SID参数,这个参数是操作系统中用到的,它是描述我们要默认连接的数据库实例.

instance_name是oracle数据库参数。而ORACLE_SID是操作系统的环境变量,ORACLE_SID必须与instance_name的值一致.对于一个机器上有多个实例的情况下,要修改后才能通过
conn / as sysdba连接,如,SET ORACLE_SID=XXX,因为这里用到了默认的实例名。

1.ORACLE_SID:(ORACLE SYSTEM IDENTIFIER)

以环境变量的形式出现的。Oracle实例是由SGA和一组后台进程组成的,实例的创建和启动需要一个参数文件,而参数文件的名称就是由ORACLE_SID决定的。对于init文件,缺省的文件名称是init<ORACLE_SID>.ora,对于spfile文件,缺省的文件名称是spfile<ORACLE_SID>.ora

设置不同的ORACLE_SID值,就可以默认使用不同的参数文件启动不同的数据库实例。另外,ORACLE_SID的作用远远不是作为一个实例入口这么简单的,在实例启动后,实例名称INSTANCE_NAME也是从ORACLE_SID得到的。

2.INSTANCE_NAME:

实例名称,这是Oracle实例的名字,用来区分不通的实例。在Oracle9i之前,该名字存储在两个地方:参数文件和数据库的内部试图(V$INSTANCE),而在Oracle10g之后的版本中,该名字不再出现在参数文件中,而是动态从系统中获得,默认是取自ORACLE_SID。INSTANCE_NAME的作用除了区别不同实例之外,在监听器动态注册时,还会用于向监听器注册。比如instance_name=zlm,监听中将动态注册Instance
"zlm",status READY信息。

3.DB_NAME:

DB_NAME概念相比于INSTANCE_NAME要重要的多,它决定实例将挂在的数据文件。它出现在数据文件,控制文件,日志文件中。在参数文件中也出现,且必须出现。这个参数涉及到系统的物理文件。

4.SERVICE_NAME和GLOBAL_DBNAME:

这两个参数之所以放在一起讲,是因为他们往往是成对出现的。SERVICE_NAME出现在tnsnames.ora文件中,是客户端要请求的服务名。

GLOBAL_DBNAME出现在listener.ora文件中,是服务器提供的服务名,可以通过show paramererservice_names查看,并可以通过alter systemset service_name=‘servicename‘
scope=both来修改。

二者对应,实现了listerner.ora/tnsnames.ora的重要功能——监听、请求与验证。

一条startup命令,究竟是如何启动庞大的oracle数据库的呢?下面我们来贯穿起来整个启动流程,一探究竟:

首先,nomount状态,系统接收到startup命令,立刻采取行动,取得环境变量ORACLE_SID的值,开始分配SGA内存,启动第一阶段--实例创建。系统根据找到的参数文件启动ORACLE数据库实例,实例启动后,一切由实例接管:注册INSTANCE_NAME,往往INSTANCE_NAME就是来自ORACLE_SID,接着向监听器动态注册实例自己,并将INSTANCE_NAME写入系统数据字典表。

接下来,mount状态,实例进一步读取参数文件,取得DB_NAME、控制文件、检查点等信息,进入第二阶段--挂载数据库。实例从控制文件中取得DB_NAME,并取得数据文件、日志文件等信息,进行DB_NAME的一致性检验、文件的存在性判断等工作之后,实例将挂载数据库,挂载的数据库就是DB_NAME指定的数据库。

最后,open状态,实例进入第三阶段--启动数据库。这一阶段,实例进行了两项检查:检查点和更改点检查,之后启动数据库。

总结:现在,了解了那么多oracle中出现的各种NAME以后,我们发现,名称确实很多,概念也很容易混淆,如,SERVICE_NAME设置错误,就会造成服务无法正确注册到监听,客户端连接不到数据库服务器等等,为了方便不出错,建议能设置的成一样的名字,尽量都用同一个,如:SID,ORACLE_SID,SID_NAME,INSTANCE_NAME,SERVICE_NAME,NET
SERVICE NAME,DB_NAME,GLOBAL_DBNAME这些名字,都可以设置成zlm,DB_DOMAIN能不用就尽量不设置,除非生产环境中有很多库,为了惟一标识,如果设置了,那么GLOBAL_NAME就不再是DB_NAME了,而是DB_NAME.DB_DOMAIN,而当使用DBLINK的时候,LINK的名字也必须使用DB_NAME.DB_DOMAIN了,会带来不小麻烦。

ORACLE 中极易混淆的几个 NAME 的分析和总结

时间: 2024-10-05 08:15:42

ORACLE 中极易混淆的几个 NAME 的分析和总结的相关文章

转载:ORACLE中极易混淆的几个NAME

前言 我们知道,Oracle中的各种NAME会在我们的各个配置文件中经常出现,大致有以下这些: 在init.ora中有DB_NAME,INSTANCE_NAME,SERVICE_NAME配置DG的时候,为了区分主备库,还要使用DB_UNIQUE_NAME在操作系统中需要配置环境变量,ORACLE_SID在listener.ora中有SID_NAME,GLOBAL_DBNAME在tnsname.ora中有SERVICE_NAME,SID,NET SERVICE NAME    那么这么多名字到底有

C++之易混淆知识点一

1.const.mutable与volatile的区别:const表明内存被初始化以后,程序将不能对它进行修改.volatile则表明,即使程序代码没有对内存单元进行修改,但是里面的值也可能会发生变化.例如:将一个指针指向某个硬件位置,其中包含了来自串行端口的时间和信息,在某些情况下,硬件而不是程序可能会修改其中的内容,或者两个程序可能相互影响,共享数据.该关键字的作用就是为了改善编译器的优化能力.假设编译器发现程序在几条语句中两次使用某个变量的值,则编译器可能不是让程序查找这个编码的值两次,而

易混淆名词辨析

以前学习总是懒得查,懒得问,很多名词都不知道是干嘛的,学的越来越多,混得越来越厉害.这次在学习Asp.net和Javascript中又接触到一些,借此机会,把这些学过的都对比和归纳一下. ADO与ADO.NET ADO: 这是第一年做那五个实例的时候用到过的吧,当时对于连接数据库并不太懂.其实ADO就是应用程序和数据源打交道时中间借助的那么一种东东,通过它我们就可以取出数据库中的数据,当然还可以对数据进行操作然后再保存到数据库. ActiveX DataObjects,一种程序对象,用于表示用户

a链接易混淆用法详解

链接可以说遍布互联网,比如你想提供一个可以跳转到百度首页的链接给网友,那么代码如下: <a href="http://www.baidu.com">百度一下,你就知道</a> 而如果这个链接指向的网址你想在浏览器中的新窗口中打开,那么代码如下: <a href="http://www.baidu.com" target="_blank">百度一下,你就知道</a> 那如果我页面中有一堆的a链接都想在

微软BI 之SSIS 系列 - 对于平面文件中 NULL 值处理过程中容易极易混淆的几个细节

最近有人问我 OLE DB Destination 中的 Keep Nulls 如何控制 NULL 值的显示,为什么选中了 Keep Nulls 但是数据库中没有 NULL 值? 为什么在 Flat File Source 中勾选上了 Retain null values from the source as null values in the data flow 但是为什么目标表上显示的是一个当前日期,而不是 NULL 值等等,单开此文来解释这些非常容易混淆的概念. 在比较纯粹的 ETL 项

常问易混淆知识点(嵌入式)

b 一.知识点1 a) 关键字volatile在编译时有什么含义?并给出三个不同使用场景的例子(可以伪代码或者文字描述).b) C语言中static关键字的具体作用有哪些 ?c) 请问下面三种变量声明有何区别?请给出具体含义int const *p;int* const p;int const* const p; a) 用volatile关键字定义变量,相当于告诉编译器,这个变量的值会随时发生变化,每次使用时都需要去内存里 重新读取它的值,并不要随意针对它作优化. 建议使用volatile变量的

C++之易混淆知识点四---虚函数与虚继承

C++面向对象中,虚函数与虚继承是两个完全不同的概念. 一.虚函数 C++程序中只要类中含有虚拟函数,编译程序都会为此类生成一个对应的虚拟函数跳转表(vtbl),该虚拟函数跳转表是一个又若干个虚拟函数体入口地址组成的一个线性表.派生类的虚拟函数跳转表的前半部分由父类的vtbl得出,但是里面的内容不一定相同,后半部分则对应着自己新定义的虚拟函数. class Employee { protected: char *Name; int Age; public: void changeAge(int

PHP易混淆函数的区别及用法汇总

本文实例分析了PHP易混淆函数的区别及用法.分享给大家供大家参考.具体分析如下: 1.echo和print的区别PHP中echo和print的功能基本相同(输出),但是两者之间还是有细微差别的.echo输出后没有返回值,但print有返回值,当其执行失败时返回flase.因此可以作为一个普通函数来使用,例如执行下面的代码后变量$r的值将为1. PHP代码: 复制代码代码如下: $r = print "Hello World"; 这意味着print可用在一些复杂的表达式中,而echo则不

软考网络工程师易混淆的知识点汇总

网络工程师考试是全国计算机技术与软件水平考试的一项中级资格考试,通过考试的合格人员能根据应用部门的要求进行网络系统的规划.设计和网络设备的软硬件安装调试工作,能进行网络系统的运行.维护和管理,能高效.可靠.安全地管理网络资源,作为网络专业人员对系统开发进行技术支持和指导,具有工程师的实际工作能力和业务水平,能指导网络管理员从事网络系统的构建和管理工作.网络工程师考试是软考的一大热门,怎样才能顺利通过考试是广大考生都想知道的,下面希赛软考学院为您带来网络工程师备考锦囊之应战篇,专业老师整理的网络工