August 4, 2007
《循序渐进Oracle》代码及服务
作者:eygle
出处:http://blog.eygle.com
《循序渐进Oracle》一书 已经出版,可能很多朋友很快就可以买到了本书.
为了方便大家学习阅读,我整理了一下,将书中的部分代码放在本站提供下载:
http://www.eygle.com/orabk/step.by.step.oracle.script.zip
为了更好的为本书服务,我新开设了一个邮箱,用于接收关于本书的问题,纠错和其他咨询.
购买本书的朋友,可以向 oracle [@] eygle.com 邮箱发送邮件,请在邮件中给出你的常用邮件地址,这样我就可以建立一个读者列表,定期给大家推荐一些有益的文章,或是发布一些关于本书勘误信息等.
本书的其他相关信息请参考:《循序渐进Oracle》一书相关信息
有意者请发邮件,请信任我邮件地址不会被滥用:)
-The End-
Posted by eygle at 4:51 PM | Comments (10)
一则杭州DBA招聘需求
作者:eygle
出处:http://blog.eygle.com
要求:
1、三年以上ORACLE DBA/技术支持相关工作经验,可以独立承担安装部署、备份恢复、性能优化和故障分析工作,熟悉UNIX/RAC/PARTITION/DATA GUARD优先
2、对OCP知识有深刻理解,有OCP证书优先
3、主要服务通讯行业客户,出差较少,熟悉通讯行业优先
4、有良好的人际关系和沟通能力,有项目管理或大型项目经验优先
5、请在简历注明待遇要求,如果附件发送简历,请在附件名称注明个人姓名
工作地点:杭州,基本不出差.
待遇:
1:100k-150k/年
2:每月提供交通和通信补贴
3:外地来杭者,提供黄龙商住区附近三室二厅中的房间一间
4:在职期间,通过OCM考试,报销所有费用
有意者,请简历给我 guoyue@gmail.com
Posted by eygle at 4:39 PM | Comments (22)
《循序渐进Oracle》第一章连载-之六
作者:eygle
出处:http://blog.eygle.com
1.2.8 db_name参数和instance_name参数
在启动实例后执行的创建数据库中,第一个语句就是
CREATE DATABASE "eygle"
这是数据库最重要的开始,其中"eygle"也就是 图1-4 中定义的数据库名称。
对于Oracle数据库来说,db_name代表数据库的名称而instance_name代表实例的名称,instance_name通过参数文件即可修改,而db_name则不然,我们看一下Oracle对于数据库名称的定义:
DB_NAME必须是一个不超过8个字符的文本串.在数据库创建过程中,db_name被记录在数据文件,日志文件和控制文件中。如果数据库实例启动过程中参数文件中的db_name和控制文件中的数据库名称不一致,则数据库不能启动。
通过以上定义可以看到,db_name是最具有稳定意义的参数,在数据文件、日志文件和控制文件中都会记录数据库的名称,这个名称完全可以不同于instance_name。
以下的测试数据库拥有相同的db_name和instance_name:
[oracle@jumper oracle]$ cd $ORACLE_HOME/dbs
[oracle@jumper dbs]$ grep name initeygle.ora
*.db_name='eygle'
*.instance_name='eygle'
我们创建一个新的pfile为julia这个新的实例使用:
[oracle@jumper oracle]$ cd $ORACLE_HOME/dbs
[oracle@jumper dbs]$ cp initeygle.ora initjulia.ora
修改这个文件更改instance_name参数:
[oracle@jumper dbs]$ grep name initjulia.ora
*.db_name='eygle'
*.instance_name='julia'
然后我们启动实例名称为julia的instance:
>[oracle@jumper dbs]$ export ORACLE_SID=julia
[oracle@jumper dbs]$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Tue Jul 25 14:04:15 2006
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to an idle instance.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 139531744 bytes
Fixed Size 452064 bytes
Variable Size 121634816 bytes
Database Buffers 16777216 bytes
Redo Buffers 667648 bytes
ORA-01102: cannot mount database in EXCLUSIVE mode
注意,此时试图加载数据库时出现错误,因为当前数据库被另外一个实例(instance)加载。在非并行模式(OPS/RAC)下,一个数据库同时只能被一个实例加载。
此时已经启动了两个数据库实例,从后台进程可以看出:
[oracle@jumper dbs]$ ps -ef|grep ora_pmon
oracle 27321 1 0 Jul14 ? 00:00:00 ora_pmon_eygle
oracle 15445 1 0 14:04 ? 00:00:00 ora_pmon_julia
oracle 15459 15391 0 14:04 pts/2 00:00:00 ps -ef
oracle 15460 15391 0 14:04 pts/2 00:00:00 grep ora_pmon
关闭eygle这个数据库实例后,就可以通过实例julia加载并打开db_name=eygle的数据库了:
[oracle@jumper dbs]$ export ORACLE_SID=julia
[oracle@jumper dbs]$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Tue Jul 25 14:05:06 2006
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
......
SQL> alter database mount;
alter database mount
*
ERROR at line 1:
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: 3SQL> alter database open;
Database altered.
SQL> select name from v$datafile;
NAME
----------------------------------------------------------------------------
/opt/oracle/oradata/eygle/system01.dbf
/opt/oracle/oradata/eygle/undotbs01.dbf
/opt/oracle/oradata/eygle/users01.dbf
/opt/oracle/oradata/eygle/eygle01.dbf
新的实例具有独立的instance_name和db_name参数设置:
SQL> ! ps -ef|grep ora_pmon
oracle 15445 1 0 14:04 ? 00:00:00 ora_pmon_julia
oracle 15515 15513 0 14:05 pts/2 00:00:00 /bin/bash -c ps -ef|grep ora
oracle 15516 15515 0 14:05 pts/2 00:00:00 ps -ef
SQL> show parameter instance_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
instance_name string julia
SQL> show parameter db_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name string eygle
我们再看看如果参数文件中的db_name和控制文件中的db_name不一致会出现什么错误。
修改参数文件中的db_name参数:
[oracle@jumper dbs]$ grep name initjulia.ora
*.db_name='julia'
*.instance_name='julia'
在启动过程中,我们看到,在mount阶段,数据库会对参数文件和控制文件进行比较,如果两者记录的db_name不一致,则数据库无法启动:
SQL> startup nomount;
ORACLE instance started.
<...ignore SGA info here...>SQL> alter database mount;
alter database mount
*
ERROR at line 1:
ORA-01103: database name 'EYGLE' in controlfile is not 'JULIA'
最后总结一下:
一个实例(instance_name)可以mount并打开任何数据库(db_name),但是同一时间一个实例只能打开一个数据库;一个数据库(db_name)同一时间可以为任一实例(instance_name)所打开,但是在非OPS/RAC情况下,同时只能被同一个实例所打开。
1.2.9 sql.bsq文件与数据库创建
在CREATE DATABASE的过程中,Oracle会调用$ORACLE_HOME/rdbms/admin/sql.bsq脚本,用于创建数据字典,这是非常重要的一个脚本,其中存储了数据字典的创建语句及注释说明,当我们对某些数据字典存在兴趣时,可以通过检查这个文件得到更为详细的信息,例如对于控制数据库启动的bootstrap$表,其创建语句就可以从这个文件中找到:
create table bootstrap$
( line# number not null, /* statement order id */
obj# number not null, /* object number */
sql_text varchar2("M_VCSZ") not null) /* statement */
storage (initial 50K) /* to avoid space management during IOR I */
// /* "//" required for bootstrap */
sql.bsq文件的位置受到一个隐含的初始化参数(_init_sql_file)的控制:
SQL> @GetParDescrb.sql
Enter value for par: init_sql
old 6: AND x.ksppinm LIKE '%&par%'
new 6: AND x.ksppinm LIKE '%init_sql%'NAME VALUE DESCRIB
--------------- --------------------- ----------------------------------------------------
_init_sql_file ?/rdbms/admin/sql.bsq File containing SQL statements to execute upon database creation
如果在创建过程中,Oracle无法找到sql.bsq文件,则数据库创建将会出错。可以测试一下移除sql.bsq文件,看一下数据库创建过程:
[oracle@jumper scripts]$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Fri Aug 18 15:45:26 2006
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.Connected to an idle instance.
SQL> startup nomount;
ORACLE instance started.
<...ignore SGA info here...>SQL> @CreateDB.sql
CREATE DATABASE eygle
*
ERROR at line 1:
ORA-01092: ORACLE instance terminated. Disconnection forcedDisconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production
此时警告日志(alert_
Fri Aug 18 15:45:49 2006
Errors in file /opt/oracle/admin/eygle/udump/eygle_ora_3632.trc:
ORA-01501: CREATE DATABASE failed
ORA-01526: error in opening file '?/rdbms/admin/sql.bsq'
ORA-07391: sftopn: fopen error, unable to open text file.
Error 1526 happened during db open, shutting down database
USER: terminating instance due to error 1526
Fri Aug 18 15:45:49 2006
Errors in file /opt/oracle/admin/eygle/bdump/eygle_ckpt_3623.trc:
ORA-01526: error in opening file ''
Instance terminated by USER, pid = 3632
ORA-1092 signalled during: CREATE DATABASE eygle
MAXINSTANCES 1
MAXLOGHISTORY...
这就是sql.bsq文件在数据库创建过程中的作用。知道了这个内容之后,我们可以通过手工修改sql.bsq文件来更改数据库字典对象参数,从而实现特殊要求数据库的创建或测试自定义库,也可以通过修改_init_sql_file参数来重定位sql.bsq文件的位置(但是通常这些是不建议变更的)。
1.2.10 数据文件及字典的创建
再来看CreateDBFiles.sql文件:
C:\Oracle\admin\eygle\scripts>type CreateDBFiles.sql
connect "SYS"/"&&sysPassword" as SYSDBA
set echo on
spool C:\oracle\admin\eygle\scripts\CreateDBFiles.log
CREATE SMALLFILE TABLESPACE "USERS" LOGGING DATAFILE SIZE 5M AUTOEXTEND ON NEXT 1280K MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
ALTER DATABASE DEFAULT TABLESPACE "USERS";
spool off
这个文件向数据库中追加了USERS表空间,并将该表空间设置为系统缺省的数据表空间,注意最后一句:
ALTER DATABASE DEFAULT TABLESPACE "USERS";
这是Oracle 10g增加的新特性,在Oracle 10g之前,如果创建用户不指定缺省的数据表空间,那么用户的缺省表空间会被指向系统表空间,增加了数据库缺省数据表空间后,如果不指定,那么创建用户的缺省数据表空间会被指向这里:
SQL> create user julia identified by eygle;
用户已创建。SQL> select username,default_tablespace from dba_users
2 where username='JULIA';
USERNAME DEFAULT_TABLESPACE
------------------------------ ------------------------------
JULIA USERS
作为一个数据库属性,这个信息也可以从字典表props$中查询得到:
SQL> select name,value$ from props$
2 where name='DEFAULT_PERMANENT_TABLESPACE';
NAME VALUE$
------------------------------ ------------------
DEFAULT_PERMANENT_TABLESPACE USERS
继续前面的讨论,接下来Oracle通过CreateDBCatalog.sql创建数据字典:
C:\Oracle\admin\eygle\scripts>cat CreateDBCatalog.sql
connect "SYS"/"&&sysPassword" as SYSDBA
set echo on
spool C:\oracle\admin\eygle\scripts\CreateDBCatalog.log
@C:\oracle\10.2.0\rdbms\admin\catalog.sql;
@C:\oracle\10.2.0\rdbms\admin\catblock.sql;
@C:\oracle\10.2.0\rdbms\admin\catproc.sql;
@C:\oracle\10.2.0\rdbms\admin\catoctk.sql;
@C:\oracle\10.2.0\rdbms\admin\owminst.plb;
connect "SYSTEM"/"&&systemPassword"
@C:\oracle\10.2.0\sqlplus\admin\pupbld.sql;
connect "SYSTEM"/"&&systemPassword"
set echo on
spool C:\oracle\admin\eygle\scripts\sqlPlusHelp.log
@C:\oracle\10.2.0\sqlplus\admin\help\hlpbld.sql helpus.sql;
spool off
spool off
这个文件依次调用Oracle的字典创建文件等。
emRepository.sql文件是用于创建EM档案库的:
C:\Oracle\admin\eygle\scripts>type emRepository.sql
connect "SYS"/"&&sysPassword" as SYSDBA
set echo off
spool C:\oracle\admin\eygle\scripts\emRepository.log
@C:\oracle\10.2.0\sysman\admin\emdrep\sql\emreposcre C:\oracle\10.2.0 SYSMAN &&sysmanPassword TEMP ON;
WHENEVER SQLERROR CONTINUE;
spool off
最后一个执行的文件是postDBCreation.sql:
C:\Oracle\admin\eygle\scripts>cat postDBCreation.sql
connect "SYS"/"&&sysPassword" as SYSDBA
set echo on
spool C:\oracle\admin\eygle\scripts\postDBCreation.log
connect "SYS"/"&&sysPassword" as SYSDBA
set echo on
create spfile='C:\oracle\10.2.0\database\spfileeygle.ora'
FROM pfile='C:\oracle\admin\eygle\scripts\init.ora';
shutdown immediate;
connect "SYS"/"&&sysPassword" as SYSDBA
startup ;
alter user SYSMAN identified by "&&sysmanPassword" account unlock;
alter user DBSNMP identified by "&&dbsnmpPassword" account unlock;
select 'utl_recomp_begin: ' || to_char(sysdate, 'HH:MI:SS') from dual;
execute utl_recomp.recomp_serial();
select 'utl_recomp_end: ' || to_char(sysdate, 'HH:MI:SS') from dual;
host C:\oracle\10.2.0\bin\emca.bat -config dbcontrol db -silent -DB_UNIQUE_NAME eygle
-PORT 1521 -EM_HOME C:\oracle\10.2.0 -LISTENER LISTENER -SERVICE_NAME eygle
-SYS_PWD &&sysPassword -SID eygle -ORACLE_HOME C:\oracle\10.2.0
-DBSNMP_PWD &&dbsnmpPassword -HOST gqgai -LISTENER_OH C:\oracle\10.2.0
-LOG_FILE C:\oracle\admin\eygle\scripts\emConfig.log -SYSMAN_PWD &&sysmanPassword;
spool C:\oracle\admin\eygle\scripts\postDBCreation.log
exit;
在创建过程中,需要经历以下几个步骤后,数据库的创建才算正式完成:
(1) Oracle首先通过参数文件创建了spfile文件;
(2) 解锁两个帐号;
(3) 编译;
(4) 配置EM。
Posted by eygle at 3:14 PM | Comments (5)
《循序渐进Oracle》第一章连载-之五
作者:eygle
出处:http://blog.eygle.com
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
来看一下测试,首先移动缺省的口令文件:
[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 FALSESQL> ! 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管理文件,控制文件的名称在创建数据库之前是未知的,所以创建数据库之后才能得到名称加入参数文件中。
Posted by eygle at 3:01 PM | Comments (4)
《循序渐进Oracle》第一章连载-之四
作者:eygle
出处:http://blog.eygle.com
1.2.4 ORACLE_SID的含义
注意到在ORADIM创建服务之前,首先设置了ORACLE_SID:
set ORACLE_SID=eygle
在Linux/UNIX系统的创建中,同样要设置ORACLE_SID,不过Linux/UNIX上不存在服务这项内容,实例是可以通过参数文件直接启动的。
看一下Linux上正常情况下启动到nomount状态的过程:
[oracle@jumper oracle]$ cd $ORACLE_HOME/dbs
[oracle@jumper dbs]$ ls
initconner.ora init.ora lkCONNER orapwconner spfileconner.ora spfile.ora
[oracle@jumper dbs]$ export ORACLE_SID=conner
[oracle@jumper dbs]$ sqlplus "/ as sysdba"SQL*Plus: Release 9.2.0.4.0 - Production on Wed Nov 3 14:57:22 2004
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to an idle instance.SQL> startup nomount
ORACLE instance started.Total System Global Area 80811208 bytes
Fixed Size 451784 bytes
Variable Size 37748736 bytes
Database Buffers 41943040 bytes
Redo Buffers 667648 bytes
注意这里,Oracle根据参数文件的内容,创建了instance,分配了相应的内存区域,启动了相应的后台进程。
回顾一下前面的内容,注意到SID和ORACLE_SID已经多次出现,那么SID是什么?在数据库启动过程中又起到什么作用呢?
SID是System IDentifier的缩写,而ORACLE_SID就是Oracle System Identifier的缩写,在Oracle系统中,ORACLE_SID以环境变量的形式出现,在特定版本的Oracle软件安装(也就是ORACLE_HOME)下,当Oracle实例启动时,操作系统上fork的进程必须通过这个SID将实例与其他实例区分开来,这就是SID的作用。
我们知道Oracle的实例(instance)是由一块共享内存区域(SGA)和一组后台进程(background processes)共同组成;而后台进程正是数据库和操作系统进行交互的通道,这些进程的名称就是通过ORACLE_SID决定的。
实例的启动仅需要一个参数文件,而这个参数文件的名称就是由ORACLE_SID决定的。对于init文件,缺省的文件名称是init
spfile从Oracle 9i开始引入并成为了缺省使用的参数文件,Oracle启动实例时按照以下顺序从缺省目录查找参数文件:
spfile<ORACLE_SID>.ora→spfile.ora →init<ORACLE_SID>.ora。
如果这3个文件都不存在,则Oracle实例将无法启动。
通过这些信息可以知道,在同一个ORACLE_HOME下,Oracle能够根据ORACLE_SID将实例区分开来;但是如果在不同的ORACLE_HOME下,Oracle将无法屏蔽相同名称的ORACLE_SID,也就是说即使在同一台主机上,Oracle也是能够创建相同ORACLE_SID的实例的。
以下一个测试,首先启动一个Oracle8i下ORACLE_SID为eygle的实例:
$ export ORACLE_SID=eygle
$ sqlplus "/ as sysdba"
SQL*Plus: Release 8.1.7.0.0 - Production on Fri Feb 16 10:23:58 2007
(c) Copyright 2000 Oracle Corporation. All rights reserved.
Connected to an idle instance.SQL> startup nomount;
ORACLE instance started.
<...ignore SGA info here...>SQL> ! ps -ef|grep eygle
oracle8 11106 1 0 10:24:02 ? 0:00 ora_d000_eygle
oracle8 11090 1 0 10:24:02 ? 0:00 ora_ckpt_eygle
oracle8 11086 1 0 10:24:02 ? 0:00 ora_dbw0_eygle
oracle8 11084 1 0 10:24:02 ? 0:00 ora_pmon_eygle
oracle8 11092 1 0 10:24:02 ? 0:00 ora_smon_eygle
oracle8 11088 1 0 10:24:02 ? 0:00 ora_lgwr_eygle
......
接下来又可以启动另外ORACLE_HOME下ORACLE_SID为eygle的实例:
$ export ORACLE_SID=eygle
$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Fri Feb 16 10:24:43 2007
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to an idle instance.SQL> startup nomount;
ORACLE instance started.
<...ignore SGA info here...>SQL> ! ps -ef|grep pmon_eygle
oracle9 11214 11172 0 10:24:58 pts/1 0:00 grep pmon_eygle
oracle9 11180 1 0 10:24:48 ? 0:00 ora_pmon_eygle
oracle8 11084 1 0 10:24:02 ? 0:00 ora_pmon_eygle
现在这同一台主机上就启动了两个相同名称的实例,在操作系统上,Oracle能够通过ID标识将共享内存或信号量区分开来:
$ ipcs -i
IPC status from <running system> as of Fri Feb 16 10:30:02 CST 2007
T ID KEY MODE OWNER GROUP
Message Queues:
q 0 0x2e781d5 --rw-r--r-- root root
T ID KEY MODE OWNER GROUP ISMATTCH
Shared Memory:
m 4096 0xabdc9b64 --rw-r----- oracle8 dba 12
m 1025 0x79552064 --rw-r----- oracle9 dba 11
Semaphores:
s 1245184 0x79978bac --ra-r----- oracle8 dba
s 458753 0xa0e9f594 --ra-r----- oracle9 dba
通过Oracle提供的一个小工具sysresv,我们可以找到对应于不同的ORACLE_SID,操作系统上创建的共享内存段ID(Shared Memory)和信号量ID(Semaphores)等信息。
$ sysresv -l eygle julia
IPC Resources for ORACLE_SID "eygle" :
Shared Memory:
ID KEY
2560 0x79552064
Semaphores:
ID KEY
720896 0xa0e9f594
Oracle Instance alive for sid "eygle"
IPC Resources for ORACLE_SID "julia" :
Shared Memory:
ID KEY
514 0xab281214
Semaphores:
ID KEY
196610 0xa7645a54
Oracle Instance alive for sid "julia"
在Linux/UNIX上,ORACLE_SID还和一个名为oratab的文件有关,在Solaris环境中,这个文件一般位于/var/opt/oracle目录下,在Linux及其他UNIX平台,这个文件一般位于/etc目录下。
该文件的主要内容如下:
# This file is used by ORACLE utilities. It is created by root.sh
# and updated by the Database Configuration Assistant when creating a database.# A colon, ':', is used as the field terminator. A new line terminates
# the entry. Lines beginning with a pound sign, '#', are comments.
#
# Entries are of the form:
# $ORACLE_SID:$ORACLE_HOME::
#
# The first and second fields are the system identifier and home
# directory of the database respectively. The third filed indicates
# to the dbstart utility that the database should , "Y", or should not,
# "N", be brought up at system boot time.
#
# Multiple entries with the same $ORACLE_SID are not allowed.
#
*:/opt/oracle/product/9.2.0:N
当执行dbstart脚本时,Oracle会根据这里记录的ORACLE_SID的
与Linux/UNIX上的情况类似,Windows上的Oracle环境也依赖于服务而存在,如图1-19所示。

我们注意到Oracle环境的初始化是通过ORACLE.EXE eygle来完成的,至于实例和数据库是否随服务启动要依赖于注册表中的设置。
通过手动在命令行执行类似命令,可以初始化任意的Oracle环境:
C:\>oracle julia
Press CTRL-C to exit server:
此后就可以连接到这个环境启动实例:
C:\>set ORACLE_SID=juliaC:\>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期六 2月 17 10:11:13 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
已连接到空闲例程。
SQL> startup nomount;
ORA-01078: failure in processing system parameters
LRM-00109: ???????????????? 'C:\ORACLE\10.2.0\DATABASE\INITJULIA.ORA'
当然还需要创建参数文件和口令文件等:
C:\>cp c:\oracle\10.2.0\database\SPFILEEYGLE.ORA c:\Oracle\10.2.0\database\spfilejulia.oraC:\>orapwd file=c:\oracle\10.2.0\database\PWDjulia.ora password=oracle entries=5
此后,实例可以顺利启动,并可以挂接和打开数据库:
C:\>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期六 2月 17 10:13:10 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
已连接到空闲例程。SQL> startup nomount;
ORACLE 例程已经启动。
<...ignore SGA info here...>SQL> set linesize 120
SQL> show parameter instance_name
NAME TYPE VALUE
------------------------------------ ---------------------- ---------------
instance_name string julia
SQL> show parameter db_name
NAME TYPE VALUE
------------------------------- ------------------ ------------------------------
db_name string eygle
SQL> alter database mount;
数据库已更改。
SQL> alter database open;
数据库已更改。
如果在环境窗口中按下CTRL+C组合键退出,则数据库将异常中断。
总结一下,实际上不管在Windows还是Linux/UNIX环境下,ORACLE_SID的作用就是设置一个Oracle环境窗口,通过这个环境变量来标示和命名系统进程,此后Oracle的活动可以由此展开。
Posted by eygle at 2:39 PM | Comments (12)
