eygle.com   eygle.com
eygle.com eygle
eygle.com  
 

« 《循序渐进Oracle》第一章连载-之四 | Blog首页 | 《循序渐进Oracle》第一章连载-之六 »

《循序渐进Oracle》第一章连载-之五

1.2.5 INSTANCE_NAME的含义及作用

作为Oracle数据库的重要组成部分INSTANCE也存在一个参数标示:INSTANCE_NAME。
INSTANCE_NAME是Oracle数据库的一个参数,在参数文件中定义,用于标示数据库实例的名称,其缺省值通常就是ORACLE_SID,但是不同的实例可以有相同的实例名。通过简单的参数文件复制,我们就可以在同一台服务器上创建多个具有相同instance_name的实例。

首先确认当前的参数文件:

bash-2.03$ cd $ORACLE_HOME/dbs
bash-2.03$ ls initeygle.ora
initeygle.ora

复制参数文件,更改名称:

bash-2.03$ cp initeygle.ora initjulia.ora

接下来通过导入新的ORACLE_SID我们就可以启动新的实例:

bash-2.03$ export ORACLE_SID=julia
bash-2.03$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Fri Feb 16 10:34:00 2007
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to an idle instance.

SQL> startup nomount;
ORACLE instance started.

Total System Global Area 303532408 bytes
Fixed Size 731512 bytes
Variable Size 184549376 bytes
Database Buffers 117440512 bytes
Redo Buffers 811008 bytes

现在ORACLE_SID为julia的实例已经启动,操作系统上的进程以julia名称标记:

bash-2.03$ ps -ef|grep pmon
oracle 12396 1 0 16:30 ? 00:00:00 ora_pmon_julia
oracle 16201 1 0 18:13 ? 00:00:00 ora_pmon_eygle
oracle 16256 16219 0 18:14 pts/1 00:00:00 grep pmon

但是新实例的instance_name仍然是eygle:

SQL> show parameter instance_name
NAME TYPE VALUE
------------------------------------ ---------------------- -----------------------
instance_name string eygle

总结一下,ORACLE_SID在这里用于标示进程,而instance_name则用来标示实例,两者可以具有不同的名称

此外Oracle的监听器(listener)配置文件中的SID_NAME就是来自instance_name参数,监听器通过instance_name才能确定需要将连接请求注册到哪一个实例上。通常listener.ora文件中SID_NAME相关设置类似如下示例:

SID_LIST_LISTENER =
(SID_DESC =
(GLOBAL_DBNAME = eygle)
(ORACLE_HOME = /opt/oracle/product/9.2.0)
(SID_NAME = eygle)
)

1.2.6 Oracle的口令文件

继续前面的脚本,在创建和启动了实例之后,Oracle开始调用eygle.sql脚本,我们将这个脚本分开来介绍。
这个脚本的最初部分是要求定义用户口令,然后使用定义的sys用户口令创建口令文件:

C:\Oracle\admin\eygle\scripts>type eygle.sql
set verify off
PROMPT specify a password for sys as parameter 1;
DEFINE sysPassword = &1
PROMPT specify a password for system as parameter 2;
DEFINE systemPassword = &2
PROMPT specify a password for sysman as parameter 3;
DEFINE sysmanPassword = &3
PROMPT specify a password for dbsnmp as parameter 4;
DEFINE dbsnmpPassword = &4
host C:\oracle\10.2.0\bin\orapwd.exe file=C:\oracle\10.2.0\database\PWDeygle.ora
password=&&sysPassword force=y

这里又引入了另外一个工具orapwd,这个工具在Linux/UNIX上同样存在,当口令文件丢失或损坏之后,可以通过这个工具重建口令文件,这个工具的语法为:

C:\>orapwd
Usage: orapwd file= password= entries= force=
where
file - name of password file (mand),
password - password for SYS (mand),
entries - maximum number of distinct DBA and force - whether to overwrite existing file (opt),
OPERs (opt),
There are no spaces around the equal-to (=) character.

注意:force参数是Oracle 10g中新增加的。
Oracle在启动过程中,会在$ORACLE_HOME/dbs(Windows下相应的目录则是$ORACLE_HOME\database)目录下查找口令文件,查找的顺序是首先检查orapw<ORACLE_SID>文件,如果不存在则查找orapwd文件,如果orapwd文件也不存在,就会报出如下错误:

SQL> startup force;
ORACLE instance started.

Total System Global Area 131142648 bytes
Fixed Size 451576 bytes
Variable Size 104857600 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes
ORA-01990: error opening password file '/opt/oracle/product/9.2.0/dbs/orapw'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
Additional information: 3

口令文件丢失或损坏后,通常可以通过如下命令重建口令文件:

[oracle@jumper dbs]$ orapwd file=orapwhsjf password=oracle entries=5

在数据库没有启动之前,数据库内建用户是无法通过数据库来验证身份的,此时口令文件的作用就体现了出来。口令文件中存放了具有sysdba / sysoper身份用户的用户名及口令,Oracle允许用户通过口令文件验证,在数据库未启动之前登录,从而启动实例进而加载并打开数据库;而如果没有口令文件,在数据库未启动之前就只能通过操作系统认证方式来启动实例。

Oracle通过一个初始化参数remote_login_passwordfile来限制口令文件的使用,通过这个参数可以设置用户登录时是否检查口令文件,以及有多少个数据库可以使用口令文件。这个参数有3个选项:EXCLUSIVE、SHARED和NONE。

当remote_login_passwordfile设置为NONE时,远程用户将不能通过sysdba/sysoper身份登录数据库:

SQL> show parameter pass
NAME TYPE VALUE
------------------------- ----------- ------------------------------
remote_login_passwordfile string NONE

此时通过远程连接会收到如下错误:

E:\Oracle\ora92\bin>sqlplus /nolog
SQL*Plus: Release 9.2.0.4.0 -
Production on 星期四 4月 15 09:39:22 2004
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
SQL> connect sys/oracle@hsjf as sysdba
ERROR:ORA-01017: invalid username/password; logon denied

此处实际上是无法通过口令文件验证。
缺省的remote_login_passwordfile参数设置为exclusive,支持远程sysdba的登录操作:

SQL> alter system set remote_login_passwordfile=exclusive scope=spfile;

System altered

这个参数是静态参数,修改后重起数据库才能生效。
当remote_login_passwordfile参数设置为exclusive时可以通过远程以sysdba身份登录数据库:

E:\Oracle\ora92\bin>sqlplus /nolog
SQL*Plus: Release 9.2.0.4.0 -
Production on 星期四 4月 15 09:47:11 2004
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
SQL> connect sys/oracle@hsjf as sysdba
已连接。
SQL> show user
USER 为"SYS"


当remote_login_passwordfile参数设置为shared时,则多个数据库可以共享一个口令文件,但是此时口令文件中只能存储SYS用户的口令,此时其他用户不能被授予sysdba身份:
SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
--------- ----- -----
SYS TRUE TRUE
SQL> grant sysdba to eygle;
grant sysdba to eygle
*
ERROR at line 1:
ORA-01994: GRANT failed: cannot add users to public password file
SQL> show parameter password
NAME TYPE VALUE
---------------------------- ------ ------------------------------
remote_login_passwordfile string SHARED

此时的口令文件中是不能添加用户的。
很多朋友的疑问在于:口令文件的缺省名称是orapw,怎么能够共享?
前面已经提到,Oracle数据库在启动时,首先查找的是orapw的口令文件,如果该文件不存在,则开始查找orapw的口令文件;如果同一主机上的多个数据库同时使用orapw文件,则口令文件就可以共享(当然通过其他方式,如符号链接等也可以实现共享)。
来看一下测试,首先移动缺省的口令文件:

[oracle@jumper dbs]$ mv orapweygle orapweygle.b

此时启动数据库会出现如下错误:

SQL> startup force;
ORACLE instance started.

<...ignore SGA info here...>
ORA-01990: error opening password file '/opt/oracle/product/9.2.0/dbs/orapw'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
Additional information: 3

拷贝一个orapw口令文件,这时候再启动数据库就不会出现这个错误:

SQL> ! cp orapweygle.b orapw
SQL> startup force;
ORACLE instance started.
<...ignore SGA info here...>

Database mounted.
Database opened.
SQL> show parameter password
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_login_passwordfile string SHARED

那么你可能会有这样的疑问:多个Exclusive的数据库是否可以共享一个口令文件(orapw)呢?
继续这个测试:

[oracle@jumper dbs]$ strings orapw
]\[Z
ORACLE Remote Password file
INTERNAL
AB27B53EDC5FEF41
8A8F025737A9097A

注意这里仅记录着INTERNAL/SYS的口令。
当REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE时:

SQL> alter system set remote_login_passwordfile=exclusive scope=spfile;
System altered.
SQL> startup force;
ORACLE instance started.
<...ignore SGA info here...>

Database mounted.
Database opened.
SQL> ! strings orapw
]\[Z
ORACLE Remote Password file
EYGLE
INTERNAL
AB27B53EDC5FEF41
8A8F025737A9097A

注意,这里以EXCLUSIVE方式启动以后,实例名称信息被写入口令文件。
此时如果有其他实例以Exclusive模式启动,仍然可以使用这个口令文件,口令文件中的实例名称同时被改写,也就是说,数据库只在启动过程中才读取口令文件,数据库运行过程中并不锁定该文件,类似于pfile/spfile文件。
进一步地,如果对其他用户授予SYSDBA的身份:

SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
----------------- -------- --------
SYS TRUE TRUE
SQL> grant sysdba to eygle;
Grant succeeded.
SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
------------------------------ ----- -----
SYS TRUE TRUE
EYGLE TRUE FALSE

SQL> ! strings orapw
]\[Z
ORACLE Remote Password file
EYGLE
INTERNAL
AB27B53EDC5FEF41
8A8F025737A9097A
>EYGLE
B726E09FE21F8E83

注意此时增加的SYSDBA用户,其相关信息可以被写入到口令文件,一旦口令文件中增加了其他SYSDBA用户,此文件就不再能够被其他Exclusive的实例共享。


1.2.7 脚本的执行
继续来看eygle.sql的内容,接下来的脚本才是创建数据库中最关键的:

@C:\oracle\admin\eygle\scripts\CreateDB.sql
@C:\oracle\admin\eygle\scripts\CreateDBFiles.sql
@C:\oracle\admin\eygle\scripts\CreateDBCatalog.sql
@C:\oracle\admin\eygle\scripts\emRepository.sql
@C:\oracle\admin\eygle\scripts\postDBCreation.sql

第一个脚本是CreateDB.sql,其主要内容如下:

connect "SYS"/"&&sysPassword" as SYSDBA
set echo on
spool C:\oracle\admin\eygle\scripts\CreateDB.log
startup nomount pfile="C:\oracle\admin\eygle\scripts\init.ora";
CREATE DATABASE "eygle"
MAXINSTANCES 8
MAXLOGHISTORY 1
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
DATAFILE SIZE 300M AUTOEXTEND ON NEXT 10240K MAXSIZE UNLIMITED
EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE SIZE 120M AUTOEXTEND ON NEXT 10240K MAXSIZE UNLIMITED
SMALLFILE DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE SIZE 20M AUTOEXTEND ON NEXT 640K MAXSIZE UNLIMITED
SMALLFILE UNDO TABLESPACE "UNDOTBS1" DATAFILE SIZE 200M AUTOEXTEND ON NEXT 5120K MAXSIZE UNLIMITED
CHARACTER SET ZHS16GBK
NATIONAL CHARACTER SET AL16UTF16
LOGFILE GROUP 1 SIZE 51200K,
GROUP 2 SIZE 51200K,
GROUP 3 SIZE 51200K
USER SYS IDENTIFIED BY "&&sysPassword" USER SYSTEM IDENTIFIED BY "&&systemPassword";
set linesize 2048;
column ctl_files NEW_VALUE ctl_files;
select concat('control_files=''', concat(replace(value, ', ', ''','''), '''')) ctl_files from v$parameter where name ='c
ontrol_files';
host "echo &ctl_files >>C:\oracle\admin\eygle\scripts\init.ora";
spool off

可以看到,这个文件的主要操作步骤如下:
(1) 通过SYS连接;
(2) 通过配置的参数文件init.ora启动实例;
(3) 开始数据库创建;
(4) 将数据库生成的控制文件名称追加到参数文件。
注意:由于选择了OMF管理文件,控制文件的名称在创建数据库之前是未知的,所以创建数据库之后才能得到名称加入参数文件中。



历史上的今天...
    >> 2009-08-04文章:
           20090804 - 简报这一天
    >> 2008-08-04文章:
           墨墨恢复健康 - 病好了

无觅

By eygle on 2007-08-04 15:01 | Comments (4) | Books | 1532 |

4 Comments

“此外Oracle的监听器(listener)配置文件中的SID_NAME就是来自instance_name参数,监听器通过instance_name才能确定需要将连接请求注册到哪一个实例上。”

请问大师,如果按照您文中用两个不同的 ORACLE_SID,启动两个 instance_name 相同的实例,监听器如何确定连接应该注册到哪个实例上呢?

我的orapw文件删除后重新启动的时候没什么反应
仅仅是远程无法用sysdba登陆
没有出现ORA-01990错误
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

>create pfile from spfile;
之后生成的这个initorcl.ora文件中并没有包含instance_name这个参数值。
在starup nomount以后,发现instance总是默认的跟sid一样的。

您的意思是不是我们可以在initorcl.ora中手动地写入instance_name=一个与SID不一样的值?

手工写入当然是可以的。

但是初始化参数文件中,是从10g开始才不包含instance_name的,从而消除了歧义,这是正确的改变。


CopyRight © 2004~2020 云和恩墨,成就未来!, All rights reserved.
数据恢复·紧急救援·性能优化 云和恩墨 24x7 热线电话:400-600-8755 业务咨询:010-59007017-7040 or 7037 业务合作: marketing@enmotech.com