分类: Oracle
2010-09-09 00:12:32
oracle中*_name*知多少!
1、db_name 数据库名
SQL> connect xys/manager
as sysdba
已连接。
SQL> show user
USER 为 "SYS"
SQL> show parameter
db_name
NAME TYPE VALUE
------------------------------------
----------- ------------------------------
db_name string
test1
db_name是数据库的名字,oracle本身可能是比较有用的,对我们而言没有什么太多的用处,db_name记录在controlfile,datafile_header,redo中,要想修改db_name是比较麻烦的有两种办法:1、重建controlfile,之后要求必须以reseglogs方式打开数据库;2、通过nid。另外在建库时db_name被限制为最长8个字符,尽管10g在创建时没有错误提示了,但是看看库里最多能存下几个字符就明白了,为什么即使输入超过8个字符不会报错,但是最终还是被截断了,之前我就为一个企业处理过截断db_name而引起的一些问题。
SQL>
desc v$database;
名称 是否为空?
类型
----------------------------------------- --------
------------------------
DBID
NUMBER
NAME
VARCHAR2(9)
SQL>
因此在建库时指定恰当的db_name还是非常重要的。db_name还有一个非常重要的作用就是动态注册监听,不管是否指定了service_name,或者说service_name的值是什么,pmon都会使用db_name动态注册监听的。
SQL>
host lsnrctl status
LSNRCTL for 32-bit Windows: Version 10.2.0.1.0 -
Production on 03-12月-2007 10:1
9:36
Copyright (c) 1991, 2005,
Oracle. All rights reserved.
正在连接到
(ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
LISTENER 的
STATUS
------------------------
别名 LISTENER
版本
TNSLSNR for 32-bit Windows: Version 10.2.0.1.0 -
Produ
ction
启动日期 03-12月-2007 09:29:47
正常运行时间
0 天 0 小时 49 分 50 秒
跟踪级别 off
安全性 ON:
Local OS Authentication
SNMP OFF
监听程序日志文件
e:\oracle\product\10.2.0\db_1\network\log\listener.log
监听端点概要...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=xys)(PORT=1521)))
服务摘要..
服务
"TEST2.COM" 包含 1 个例程。
例程 "inst_test", 状态 READY, 包含此服务的 1 个处理程序...
服务
"TEST3.COM" 包含 1 个例程。
例程 "inst_test", 状态 READY, 包含此服务的 1 个处理程序...
服务
"test1.COM" 包含 1 个例程。
例程 "inst_test", 状态 READY, 包含此服务的 1 个处理程序...
服务
"test1_XPT.COM" 包含 1 个例程。
例程 "inst_test", 状态 READY, 包含此服务的 1
个处理程序...
命令执行成功
SQL> show parameter service_names
NAME
TYPE
VALUE
------------------------------------ -----------
------------------------------
service_names string
TEST2, TEST3
我们发现service_names的值是TEST2, TEST3,但是lsnrctl
status显示的结果中包含了“
服务 "test1.COM" 包含 1 个例程。
例程 "inst_test", 状态 READY,
包含此服务的 1 个处理程序...”
2、instnace_name 实例名
SQL> show parameter
instance_name
NAME TYPE VALUE
------------------------------------
----------- ------------------------------
instance_name string
inst_test
instance_name除了动态注册监听用到之外,到目前为止我没有发现其他用处,也许oracle用它来区分各个实例?不过相信仅仅通过instance_name也不能完全区分,至少也的用到sid吧,看看上面显示出来的动态注册监听中的信息,其中inst_test就是instance_name
3、SID:System
Identifier
The SID identifies the instance's shared memory on a host,
but may not uniquely distinguish this instance
from other
instances
doc上把sid解释为在host上用sid来标示实例的共享内存的,可见sid主要是和os打交道的。
sid可以通过如下语句在库中查询:
SQL>
select instance_name from
v$instance;
INSTANCE_NAME
----------------
tsid
尽管v$instance中字段
instance_name
看起来是实例名,但是实际上存储的是sid,在win下sid不能重复,不管oracle_home是否相同,相同当然不行,主要是不同也不行,这里的不同是针对unix/linux而言的,在unix/linux下只要不同版本的oracle安装在不同的oracle_home下就可以创建相同sid的实例,但是win下不可以,这不是由oracle决定的,主要是受到windows服务的限制,在服务中不能存在服务名相同的oracle服务,服务名是由如下格式组成的:OracleServiceSID,因为服务名中包括了sid,所以sid如果相同了,服务名就相同了,这是windows所不允许的。因此在win下无法创建相同sid的不同实例。
4、service_names
服务名
服务名是复数,大家看好了,意味着service_names
可以是多个值,这里的服务名除了在动态注册的监听中被用到之外,没有发现其它用处,还有其它用处大家可以补充,dataguard中建议大家在primary,standby上使用相同的service_names,这样可能便于尽可能的实现透明切换,前提是如果没有配置静态静听的话,当然如果配置了静态注册的监听在primary,standby上也务必保持在listener中要求输入的服务名相同,还是那句话,尽可能的实现透明切换。下面查询可以显示service_names:
SQL>
show parameter service_names
NAME TYPE
VALUE
------------------------------------ -----------
------------------------------
service_names string TEST2,
TEST3
这里我指定了2个值test2,test3,再来看看动态注册的监听是如何使用服务名的,监听的部分状态信息如下:
服务
"TEST2.COM" 包含 1 个例程。
例程 "inst_test", 状态 READY, 包含此服务的 1 个处理程序...
服务
"TEST3.COM" 包含 1 个例程。
例程 "inst_test", 状态 READY, 包含此服务的 1
个处理程序...
这里我们看到显示出来的服务名有后缀com,是因为我设置了db_domain
5、db_domain
数据库域名
SQL> show parameter db_domain
NAME TYPE
VALUE
------------------------------------ -----------
------------------------------
db_domain string
COM
doc上说它被"."分割,包括句点最多128个字符,没改过这么长的,不知道,没有验证过,谁想验证就验证一下,db_domain
的作用主要是用在分布式数据库中,分布式事务的各个数据库应该有db_domain
,但是要求他们是否相同,doc上没说,我也不知道,之前单位开发有分布式环境,但是当时没有注意过,不过高级复制中要同步的对象所在的数据库是无论如何也要设置db_domain
的,是否要求相同也不得而知了,我在配置复制的时候把db_domain 设置为相同的了。介绍db_domain
的另一个用途就是在同一个os域中如果要创建同名db_name的数据库时建议最好让具有相同db_name的数据库具有不同的db_domain,以保证在同一个域中global_name是唯一的。doc上也是这样建议的:Oracle
recommends that you specify DB_DOMAIN as a unique string for all databases in a
domain
当指定了db_domain的时候,在创建db
link时会自动在db_link的后面加上db_domain(doc:
If you omit the domains from the name
of a database link, Oracle expands the name by qualifying the database with the
domain of your local database as it currently exists in the data dictionary, and
then stores the link name in the data dictionary. The characters valid in a
database domain name are: alphanumeric characters, underscore (_), and number
sign (#).
),9i好像记得是这样的,但是10g我验证了一下不是:
SQL> create database link
dbl_test using 'orcl';
数据库链接已创建。
SQL> select db_link from
dba_db_links;
DB_LINK
----------------------------------------------------------------------------
DBL
DBL_TEST
ORCL
还有一点需要主要的是:You
must set this parameter for every instance, and multiple instances must have the
same value in Real Application Clusters
6、global_name
全局数据库名
global_name 是由db_name.db_domain构成的,doc如下:
Understanding How
Global Database Names Are Formed
A global database name is formed from two
components: a database name and a domain. The database name and the domain name
are determined by the following initialization parameters at database
creation:
Component Parameter Requirements Example
Database name DB_NAME
Must be eight characters or less. sales
Domain containing the database
DB_DOMAIN Must follow standard Internet conventions. Levels in domain names must
be separated by dots and the order of domain names is from leaf to root, left to
right. us.acme.com
但是通过验证发现oracle并没有把db_name.db_domain和global_name
同步起来,不知道为什么?global_name
oracle是通过提供了一个view,sys.global_name,该试图是源于props$的,可以查看创建view的脚本,最终我们访问的是一个public
synonym global_name:
SQL> select * from
global_name;
GLOBAL_NAME
--------------------------------------------
test1
按照doc的意思,我上面看到的查询结果应该是test1.com才对,这是我的疑问,好久了?
不过我们也可以修改global_name:
SQL>
alter database rename global_name to test1.com;
数据库已更改。
SQL>
select * from
global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
TEST1.COM
SQL>
alter database rename global_name to test123.com;
数据库已更改。
SQL>
select * from
global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
TEST123.COM
SQL>
需要注意的是一旦加上了域就不能通过上面的命令去掉了,如:
SQL>
alter database rename global_name to test123.com;
数据库已更改。
SQL>
select * from
global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
TEST123.COM
SQL>
alter database rename global_name to test1;
数据库已更改。
SQL> select
* from
global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
TEST1.COM
SQL>
alter database rename global_name to test123;
数据库已更改。
SQL>
select * from
global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
TEST123.COM
SQL>
不过可以直接update
global_name 或者props$来去掉后缀:
SQL> update global_name set
global_name='test1';
已更新 1 行。
SQL>
commit;
提交完成。
SQL> select * from
global_name;
GLOBAL_NAME
---------------------------------------------------------------
test1
SQL>
global_name
的作用主要也是用在Distributed
Database中,我只在高级复制中用过global_name
详细的内容也可以参考下面的连接:
[url=]
... dmin.htm#sthref4096[/url]
7、global_names
是一个布尔值,为什么要提它,是应为global_names和global_name看起来很相似,global_names的作用是创建db
link时是否强制使用远程数据库的global_name,如果global_names=true,则db link name必须要求是remote
database的global_name,否则创建之后db link 不能连同,测试如下,缺省值是false
SQL> show parameter
global_names
NAME TYPE VALUE
------------------------------------
----------- ------------------------------
global_names boolean
TRUE
SQL> select count(*) from t_emp@dbl;
select count(*) from
t_emp@dbl
*
第 1 行出现错误:
ORA-02085: 数据库链接 DBL 连接到 ORCL
SQL> col
db_link format a10
SQL> col host format a10
SQL> col owner format
a10
SQL> col username format a10
SQL> select * from
dba_db_links;
OWNER DB_LINK USERNAME HOST CREATED
----------
---------- ---------- ---------- --------------
SYS DBL TEST orcl
01-12月-07
SYS ORCL TEST orcl 01-12月-07
SQL> select count(*) from
t_emp@orcl;
COUNT(*)
----------
4
SQL>
8、在通过netmanager配置静态监听注册时,需要输入的全局数据库名(GLOBAL_DBNAME
)到底应该输入什么?而通过netmanager配置网络服务命名(tns)是需要输入的服务名(SERVICE_NAME
)又是什么?
listener.ora内容如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = test)
(ORACLE_HOME =
E:\oracle\product\10.2.0\db_1)
(SID_NAME = tsid)
)
)
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL =
TCP)(HOST = xys)(PORT =
1521))
)
--================================
tnsnames.ora内容如下:
TEST
=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL =
TCP)(HOST = xys)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test)
)
)
--================================
这里明确的告诉大家,配置静态监听注册时,需要输入的全局数据库名(GLOBAL_DBNAME
)输入什么都可以,只要保证listerner.ora中的GLOBAL_DBNAME和tnsnames.ora中的SERVICE_NAME保持一致就可以,下面通过试验看看效果:
值得主要的是GLOBAL_DBNAME
= test,而此时数据库的db_name和global_name以及service_names分别如下显示:
SQL> show
parameter db_name
NAME TYPE
VALUE
------------------------------------ -----------
------------------------------
db_name string
test1
SQL> select *from
global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
test1
SQL>
alter database rename global_name to abcd.yu;
数据库已更改。
SQL>
select *from
global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
ABCD.YU
SQL>
SQL>
show parameter service_names
NAME TYPE
VALUE
------------------------------------ -----------
------------------------------
service_names string
TEST2,
TEST3
SQL>
而我在配置listener和tnsnames时提供的test和db_name,globla_name,service_name没有任何关系,然后看看tnsping的效果:
C:\>tnsping
test
已使用 TNSNAMES 适配器来解析别名
Attempting to contact (DESCRIPTION =
(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = xys)(PORT = 1521)))
(CONNECT_DATA = (SERVICE_NAME = test)))
OK (30
毫秒)
C:\>
9、db_unique_name
DB_UNIQUE_NAME是10g的参数,在配置dataguard环境时必须为处于dg环境中每个db设置一个唯一值,在没有DB_UNIQUE_NAME参数之前,在同一台机器上搭建dg时必须使用参数LOCK_NAME_SPACE在standby参数文件中,10g
有了参数db_unique_name,LOCK_NAME_SPACE已经被废弃!
下面是摘自三思的文章:
Db_name:对一个数据库(Oracle
database)的唯一标识。这种表示对于单个数据库是足够的,但是随着由多个数据库构成的分布式数据库的普及,这种命令数据库的方法给数据库的管理造成一定的负担,因为各个数据库的名字可能一样,造成管理上的混乱。为了解决这种情况,引入了Db_domain参数,这样在数据库的标识是由Db_name和Db_domain两个参数共同决定的,避免了因为数据库重名而造成管理上的混乱。这类似于互连网上的机器名的管理。我们将Db_name和Db_domain两个参数用’.’连接起来,表示一个数据库,并将该数据库的名称称为Global_name,即它扩展了Db_name。Db_name参数只能由字母、数字、’_’、’#’、’$’组成,而且最多8个字符。
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
Service_name:该参数是oracle8i新引进的。在8i以前,我们用SID来表示标识数据库的一个实例,但是在Oracle的并行环境中,一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了Service_name参数,该参数对应一个数据库,而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为Db_name.
Db_domain,即等于Global_name。一个数据库可以对应多个Service_name,以便实现更灵活的配置。该参数与SID没有直接关系,即不必Service
name 必须与SID一样。
Instance_name:数据库实例名。用于和操作系统之间的联系,用于对外部连接时使用。在操作系统中要取得与数据库之间的交互,必须使用数据库实例名。例如,要和某一个数据库server连接,就必须知道其数据库实例名,只知道数据库名是没有用的,与数据库名不同,在数据安装或创建数据库之后,实例名可以被修改。数据库名与实例名之间的关系一般是一一对应关系,有一个数据库名就有一个实例名,如果在一个服务器中创建两个数据库,则有两个数据库名,两个数据库实例名,用两个标识确定一个数据库,用户和实例相连接。
但在8i、9i的并行服务器结构中,数据库与实例之间不存在一一对应关系,而是一对多关系,(一个数据库对应多个实例,同一时间内用户只一个实例相联系,当某一实例出现故障,其它实例自动服务,以保证数据库安全运行。)
Oracle_SID:操作系统环境变量。在实际中,对于数据库实例名的描述有时使用实例名(instance_name)参数,有时使用ORACLE_SID参数。这两个都是数据库实例名,它们有什么区别呢?(经常弄混)
(ORACLE_SID)
OS<---------------->; ORACLE 数据库
<--------(Instance_name(实例名))
上例表示实例名instance_name、ORACLE_SID与数据库及操作系统之间的关系,虽然这里列出的两个参数都是数据库实例名,但instance_name参数是ORACLE数据库的参数,此参数可以在参数文件中查询到,而ORACLE_SID参数则是操作系统环境变量。
操作系统环境变量ORACLE_SID用于和操作系统交互。也就是说,在操作系统中要想得到实例名,就必须使用ORACLE_SID。此参数与ORACLE_BASE、ORACLE_HOME等用法相同。在数据库安装之后,ORACLE_SID被用于定义数据库参数文件的名称。如:
$ORACLE_BASE/admin/DB_NAME/pfile/init$ORACLE_SID.ora。