以下实验环境:在win7(32bit)下的oracle 10g进行
修改主机名 hostname 命令
实例只有从关闭到启动(用startup)才会读取参数(文件)命令,退出后再次进入sqlplus工具实例就会重新读取参数文件的想法是错误的,因为sqlplus工具是个客户端的工具,退出sqlplus只是断开了与服务端的连接,而不会影响到位于服务端的实例的状态,它本来是处于启动运行状态的,退出sqlplus后,它还是处于这样的状态。还有,实例只有在启动时才会读取参数文件里的内容。
===========================================================
当读取tnsname文件里的网络服务名(标识)TOO(即sqlplus /@TOO as sysdba)来进行连接时,
若服务端的参数文件里service_names未填写出来时,则服务端的参数文件里参数service_names默认的值为db_name+db_domain两个同样是参数文件里的参数的值的组合。
如下例子,其中服务端的db_name=‘too’,db_domain=‘’,而service_names是两者的组合:
客户端的tnsname.ora文件为
,则客户端输入命令的结果是:
C:\Users\Administrator>sqlplus /@TOO as sysdba
SQL*Plus:Release 10.2.0.1.0 - Production on星期日 7月 7 18:44:412013
Copyright (c)1982, 2005, Oracle. All rights reserved.
连接到:
Oracle Database10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Miningoptions
SQL> show parameters service_names
NAME TYPE VALUE
----------------------------------------------- ------------------------------
service_names string too
SQL> show parameters db_domain
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_domain string
SQL>
若服务端的db_name=‘too’,db_domain=‘dkz.hz’,service_names是两者的组合,而客户端的service_name依然是too时,以sqlplus /@TOO as sysdba连接就会出错,提示的意思是说客户端说的服务名too在服务端不存在,此时服务端的服务名已经是too.dkz.hz了。(静态监听时即使服务端的服务名写着是too,详细如下:SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = too)
(ORACLE_HOME =C:\oracle\product\10.2.0\db_1)
)
)
只要该实例too实际不存在,也会有同样提示的错误。)
C:\Users\Administrator>sqlplus /@TOO as sysdba
SQL*Plus:Release 10.2.0.1.0 - Production on星期日 7月 7 18:44:122013
Copyright (c)1982, 2005, Oracle. All rights reserved.
ERROR:
ORA-12514: TNS:监听程序当前无法识别连接描述符中请求的服务
请输入用户名:
若服务端的db_name=‘too’,db_domain=‘dkz.hz’,service_names是两者的组合,且客户端的service_name也是too.dkz.hz时,以sqlplus/@TOO as sysdba连接,是正常的。
C:\Users\Administrator>sqlplus/@TOO as sysdba
C:\Users\Administrator>sqlplus/@TOO as sysdba
SQL*Plus:Release 10.2.0.1.0 - Production on星期日 7月 7 18:44:412013
Copyright (c)1982, 2005, Oracle. All rights reserved.
连接到:
Oracle Database10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Miningoptions
SQL> showparameters service_name
NAME TYPE VALUE
----------------------------------------------- ------------------------------
service_names string too.dkz.hz
SQL> show parameters db_domain
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_domain string dkz.hz
SQL>
当以不读取tnsname文件里的网络服务名(标识)而用默认的方式(即sqlplus / as sysdba)来进行连接时,
若此时的客户端的tnsname.ora文件里的service_name为too,如下:
则以sqlplus / as sysdba连接还是正常的:
C:\Users\Administrator>sqlplus / as sysdba
SQL*Plus:Release 10.2.0.1.0 - Production on星期日 7月 7 21:53:542013
Copyright (c)1982, 2005, Oracle. All rights reserved.
连接到:
Oracle Database10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Miningoptions
SQL> showparameters instance_name
NAME TYPE VALUE
----------------------------------------------- ------------------------------
instance_name string too
SQL> show parameters db_domain
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_domain string dkz.hz
SQL> show parameters service_name
NAME TYPE VALUE
----------------------------------------------- ------------------------------
service_names string too.dkz.hz
SQL>
这说明sqlplus / as sysdba连接时,是以环境变量oracle_sid来找到对应的参数文件(参数文件名要为initSID或spfileSID的格式),读取参数文件里面的db_name参数,从而确定对应到哪个数据库的。
其实,sqlplus /@TOOas sysdba的连接方式时,根据tnsname文件里的服务名通过监听(程序所有的配置)找到对应的实例名,也就是环境变量oracle_sid,再同样地,是以环境变量oracle_sid来找到对应的参数文件(参数文件名要为initSID或spfileSID的格式),读取参数文件里面的db_name参数,从而确定对应到哪个数据库的。
注释:sqlplus / as sysdba连接只能本地连接,即客户端和服务端在同一个主机上。
上述都是在动态监听下(配对的服务名和实例)进行,如下图:
===========================================================
修改参数文件里的db_name参数并不能起到修改数据库名的目的,这个参数只是告诉(读取该参数文件的)实例要去和叫db_name的数据库关联而已。实际决定数据库的名字的位置是在创建数据库语句create database DBname 中的 DBname。
SQL> showparameters local_listen
NAME TYPE VALUE
----------------------------------------------- ------------------------------
local_listener string
SQL>
说明local_listener为空值时以协议为TCP端口为1521的监听程序(若它已经启动的话)来进行动态监听的。
当listener.ora文件的静态监听列表部分如下时,
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME =C:\oracle\product\10.2.0\db_1)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME=tt)
(ORACLE_HOME =C:\oracle\product\10.2.0\db_1)
)
)
则
说明在静态监听下(SID_NAME=tt)即实例名tt也成了服务名的来源。下图也是:
按理说,当静态监听如下时:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME =PLSExtProc)
(ORACLE_HOME =C:\oracle\product\10.2.0\db_1)
(PROGRAM =extproc)
)
(SID_DESC =
(SID_NAME=too)
(ORACLE_HOME =C:\oracle\product\10.2.0\db_1)
(GLOBAL_NAME=we)
)
)
此时,服务名应该为we,和实例名too关联。但是,监听的状态显示如下:
就是说服务名依然是too,而不是(GLOBAL_NAME=we)里的we,这个很奇怪!
按理说,动态监听时服务名与实例名关联应该是类似于(SID_NAME=too)和(GLOBAL_NAME=we)的关联的。现在不知道解释了。
没有奇怪的,因为listener.ora文件里的有个参数名写错了,(GLOBAL_NAME=we)的GLOBAL_NAME应该正确的写法是GLOBAL_DBNAME,如下所示:
当listener.ora文件如下时,
则监听状态显示如下:
就是说服务名里便有cool了。
此时,若客户端的tnsname.ora文件配置如下:
则可以连接到服务端了,结果如下图:
最后,要说的一点是动态监听可以监听所有已经启动的实例的,如下图所示:
若不是默认配置的监听程序要能动态监听,则要设置local_listener参数,其中的一种方式,如下:
alter system setlocal_listener='ADDRESS = (PROTOCOL=TCP)(HOST=mydb)(PORT=1522))';
附加:服务名的其他来源的探讨。
我们在看下图:
这三个服务名都是A.db_domain的形式,其中“yoy.ting”是db_name.db_domain的形式,即A这里代表参数变量db_name。
那么,其他两个的A是代表什么呢?
打开参数文件,就有可能看到这两个值,如果这两个值对应的参数变量是显式地写在参数文件的话。跟“yoy.ting”里的yoy代表参数变量db_name的值一样,这两个值也是参数文件里某两个参数的值。
同时,这两个值也是合成的,即rouXDB是instance_name+XDB的形式;yoy_XPT是db_name+_XPT的形式.
当然,这两个值对应的参数变量没有显式地写在参数文件的话,不是代表就没有这两个参数了。这两个参数和其他参数一样在Oracle软件本身就存在着的,他们有自己的默认值(初始值)的(默认值就是上面这两个值),参数文件,即配置文件,只是修改这些变量的值而已。
如果你将这两个值对应的参数变量是显式地写在参数文件里,又不想写成上面值的形式,也是可以的,随便你写的。
总结:服务名的来源
1、就是上述的,参数文件里的参数与db_domain的结合
2、全局数据库名分成两类来源:一是参数db_name和参数db_domain结合的形式:db_name.db_domain,一是listener.ora里的global_dbname。
注释:
位于服务端的数据库里的参数global_name不是服务名的来源。验证该参数是否是服务名的来源,只要修改该参数值(ALTER DATABASE RENAME GLOBAL_NAME TO NEW_NAME;)。之后,执行lsnrctl status命令,发现显示的执行结果里‘服务摘要..’这一片段里没有服务名为参数global_name修改后的值,故而确认参数global_name不是服务名的来源。
查看参数global_name值:select * from global_name;
还有,所谓数据库里的参数的默认值,就是oracle数据库软件对应的源码里一个变量声明定义时的初始化值,而用该参数在参数文件里的值覆盖数据库里的参数的默认值,就是程序对应的源码里该变量赋值时的值。
学习笔记:global database name 是用于区分同一个分布式数据库系统(构成一个局域网络)上不同的数据库,而不是用于区分两个分布式数据库系统上不同的数据库
3、service_names的值(也是参数文件里的参数)
注释:
1、当创建好数据库后,查看service_names的原始值就是db_name.db_domain。但是设置service_names值时,若把db_name.db_domain给覆盖了,没有保留的话,则service_names里就没有db_name.db_domain了。
2、例如像status命令显示的结果里提到instance是指instance_name,非oracle_sid。ORACLE_SID用于标示进程(作用于操作系统内部),而instance_name则用来标示实例(作用于操作系统外部,让其他主机上的进程可以识别的),两者可以具有不同的名称。具体参见《修改instance_name的语句(alter system set instance_name)》。
3、global_dbname给具有静态监听的监听程序自己用的。比如,监听A的监听配置里的SID_listener_监听A部分,设置global_dbname为sta,则其他监听(已经启动的)具有动态监听功能时,是不能识别出这个名为sta的服务的。当然,监听A自己无论是否具有动态监听功能都能识别这个名为sta的服务。
另见:《TNS连接和服务名杂记》