在sqlplus下,我们可以使用管理员sysdba/sysoper的身份启动数据库,即使用startup命令。而在这条命令的背后,Oracle系统做了很多的操作。总体来说,启动的过程分为三个步骤:
1. 启动到nomount状态,这个阶段数据库读取spfile/pfile文件中的参数,启动数据库实例。
2. 启动到mount状态,这个阶段数据库打开控制文件,验证控制文件。
3. 启动到open状态,这个阶段数据库打开控制文件里描述的文件。
在关闭数据库(shutdown)过程,正好相反。
我们首先看数据库启动到nomount状态的过程,这个过程即启动数据库的实例。首先找到oracle的二进制程序:
我们可以通过file命令查看该Oracle是32位还是64位版本:
bash-3.00$ file oracle
oracle: ELF 64-位 MSB 可执行 SPARCV9 版本 1,动态链接,没有除去
下面是一个正常情况下,数据库启动到nomount的过程:
bash-3.00$ sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on Sat Jul 4 12:39:48 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup
ORACLE instance started.
Total System Global Area 2550136832 bytes
Fixed Size 1980808 bytes
Variable Size 553649784 bytes
Database Buffers 1979711488 bytes
Redo Buffers 14794752 bytes
Database mounted.
Database opened.
我们可以看到,数据库实例已经启动了,且分配了相应的内存区域。现在我们看一下日志文件的内容:
bash-3.00$ pwd
/export/home/oracle/admin/uep4x/bdump
bash-3.00$ tail -50 alert_uep4x.log
Sat Jul 4 12:51:24 2009
Starting ORACLE instance (normal)
LICENSE_MAX_SESSION = 0
LICENSE_SESSIONS_WARNING = 0
Picked latch-free SCN scheme 3
Using LOG_ARCHIVE_DEST_10 parameter default value as USE_DB_RECOVERY_FILE_DEST
Autotune of undo retention is turned on.
IMODE=BR
ILAT =18
LICENSE_MAX_USERS = 0
SYS auditing is disabled
ksdpec: called for event 13740 prior to event group initialization
Starting up ORACLE RDBMS Version: 10.2.0.1.0.
System parameters with non-default values:
processes = 150
__shared_pool_size = 520093696
__large_pool_size = 16777216
__java_pool_size = 16777216
__streams_pool_size = 0
nls_language = SIMPLIFIED CHINESE
nls_territory = CHINA
sga_target = 2550136832
control_files = /export/home/oracle/oradata/uep4x/control01.ctl, /export/home/oracle/oradata/uep4x/control02.ctl, /export/home/oracle/oradata/uep4x/control03.ctl
db_block_size = 8192
__db_cache_size = 1979711488
compatible = 10.2.0.1.0
db_file_multiblock_read_count= 16
db_recovery_file_dest = /export/home/oracle/flash_recovery_area
db_recovery_file_dest_size= 2147483648
undo_management = AUTO
undo_tablespace = UNDOTBS1
remote_login_passwordfile= EXCLUSIVE
db_domain =
dispatchers = (PROTOCOL=TCP) (SERVICE=uep4xXDB)
job_queue_processes = 10
background_dump_dest = /export/home/oracle/admin/uep4x/bdump
user_dump_dest = /export/home/oracle/admin/uep4x/udump
core_dump_dest = /export/home/oracle/admin/uep4x/cdump
audit_file_dest = /export/home/oracle/admin/uep4x/adump
db_name = uep4x
open_cursors = 300
pga_aggregate_target = 848297984
PMON started with pid=2, OS id=6834
PSP0 started with pid=3, OS id=6836
MMAN started with pid=4, OS id=6838
DBW0 started with pid=5, OS id=6840
LGWR started with pid=6, OS id=6842
CKPT started with pid=7, OS id=6844
SMON started with pid=8, OS id=6846
RECO started with pid=9, OS id=6848
CJQ0 started with pid=10, OS id=6850
MMON started with pid=11, OS id=6852
Sat Jul 4 12:51:28 2009
starting up 1 dispatcher(s) for network address '(ADDRESS=(PARTIAL=YES)(PROTOCOL=TCP))'...
MMNL started with pid=12, OS id=6854
Sat Jul 4 12:51:28 2009
starting up 1 shared server(s) ...
从上面的日志文件中我们可以看到Oracle启动实例的时启动的进程,pid是进程在数据库内部的标识符编号,OS id是进程在操作系统中的进程号。
bash-3.00$ ps -ef | grep ora_
oracle 6840 1 0 12:51:28 ? 0:00 ora_dbw0_uep4x
oracle 6836 1 0 12:51:28 ? 0:00 ora_psp0_uep4x
oracle 6834 1 0 12:51:28 ? 0:00 ora_pmon_uep4x
oracle 6846 1 0 12:51:28 ? 0:00 ora_smon_uep4x
oracle 6842 1 0 12:51:28 ? 0:00 ora_lgwr_uep4x
oracle 6844 1 0 12:51:28 ? 0:00 ora_ckpt_uep4x
oracle 6838 1 0 12:51:28 ? 0:01 ora_mman_uep4x
oracle 6870 6738 0 12:59:00 pts/6 0:00 grep ora_
oracle 6850 1 0 12:51:28 ? 0:00 ora_cjq0_uep4x
oracle 6848 1 0 12:51:28 ? 0:00 ora_reco_uep4x
oracle 6856 1 0 12:51:29 ? 0:00 ora_d000_uep4x
oracle 6852 1 0 12:51:28 ? 0:00 ora_mmon_uep4x
oracle 6854 1 0 12:51:28 ? 0:00 ora_mmnl_uep4x
oracle 6858 1 0 12:51:29 ? 0:00 ora_s000_uep4x
我们发现,在日志里没有记录pid=1的进程,下面我们看下v$process这个视图。
SQL> select pid,spid,program
2 from v$process;
PID SPID PROGRAM
1 PSEUDO
2 6834 oracle@ZXNM01-N31-02 (PMON)
3 6836 oracle@ZXNM01-N31-02 (PSP0)
4 6838 oracle@ZXNM01-N31-02 (MMAN)
5 6840 oracle@ZXNM01-N31-02 (DBW0)
6 6842 oracle@ZXNM01-N31-02 (LGWR)
7 6844 oracle@ZXNM01-N31-02 (CKPT)
8 6846 oracle@ZXNM01-N31-02 (SMON)
9 6848 oracle@ZXNM01-N31-02 (RECO)
10 6850 oracle@ZXNM01-N31-02 (CJQ0)
11 6852 oracle@ZXNM01-N31-02 (MMON)
12 6854 oracle@ZXNM01-N31-02 (MMNL)
13 6856 oracle@ZXNM01-N31-02 (D000)
14 6858 oracle@ZXNM01-N31-02 (S000)
15 6878 oracle@ZXNM01-N31-02 (TNS V1-V3)
15 rows selected.
从以上输入我们可以看到pid为1的进程是个PSEUDO进程,该进程认为是初始化数据库的进程,数据库启动之后该进程会一直存在。
下面我们看一下v$process这个视图的结构:
SQL> desc v$process;
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
ADDR RAW(8)
PID NUMBER
SPID VARCHAR2(12)
USERNAME VARCHAR2(15)
SERIAL# NUMBER
TERMINAL VARCHAR2(30)
PROGRAM VARCHAR2(48)
TRACEID VARCHAR2(255)
BACKGROUND VARCHAR2(1)
LATCHWAIT VARCHAR2(16)
LATCHSPIN VARCHAR2(16)
PGA_USED_MEM NUMBER
PGA_ALLOC_MEM NUMBER
PGA_FREEABLE_MEM NUMBER
PGA_MAX_MEM NUMBER
其中ADDR字段是进程的地址,PID是数据库中的进程号,SPID是系统的进程号,LATCHWAIT是该进程当前正在等待的锁(latch)的信息,LATCHSPIN是该进程正在通过自旋(spin)进行锁(latch)竞争。另外几个PGA相关的字段记录了该进程使用PGA的情况。
Oracle启动需要选择参数文件,目录在$ORACLE_HOME/dbs下,选择参数文件的顺序首选spfile<ORACLE_SID>.ora,如果这个文件不存在的话则选择spfile.ora,如果spfile.ora不存在的话,则选择init<ORACLE_SID>.ora。如果都不存在的话,则数据库实例无法启动。
我们可以查看数据库启动是否使用了spfile文件:
SQL> show parameter spfile
NAME TYPE
------------------------------------ ----------------------
VALUE
------------------------------
spfile string
/export/home/oracle/product/10
g/dbs/spfileuep4x.ora
我们知道spfile是二进制文件,而pfile是文本文件,有时候我们需要在这两种文件之间做转换:
SQL> create pfile='tmp.ora' from spfile='spfileuep4x.ora';
File created.
我们启动一个数据库实例仅仅需要一个参数文件,我们可以做下面的实验说明。
bash-3.00$ export ORACLE_SID=david
bash-3.00$ sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on Sat Jul 4 16:23:26 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup
ORA-01078: failure in processing system parameters
LRM-00109: could not open parameter file '/export/home/oracle/product/10g/dbs/initdavid.ora'
提示缺少一个参数文件,然后我们创建一个参数文件。
SQL> !echo "db_name=david" > /export/home/oracle/product/10g/dbs/initdavid.ora
SQL> startup nomount;
ORACLE instance started.
Total System Global Area 171966464 bytes
Fixed Size 1977208 bytes
Variable Size 113251464 bytes
Database Buffers 50331648 bytes
Redo Buffers 6406144 bytes