如果使用“alter database open;”命令打开一个曾经被“alter database close;”命令关闭的数据库时,您将会收到如下的报错信息:
"ORA-16196: database has been previously opened and closed"这个报错的原因是什么呢?
原因是:
一个实例在其生存期中最多只能装载和打开一个数据库。
要想再打开此数据库,必须先停掉这个实例再重新启动数据库。
基于上面的报错信息和原因,我来通过一个实验来展示一下这个过程,以便有一个感性上的认识。
1.为了保证实验环境的“纯洁”,先重新启动一下数据库(这里我使用的Oracle版本是10.2.0.3)
ora10g@secDB /home/oracle$ sqlplus / as sysdba
SQL*Plus: Release 10.2.0.3.0 - Production on Sun Oct 25 23:07:57 2009
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options
sys@ora10g> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
sys@ora10g> startup;
ORACLE instance started.
Total System Global Area 2147483648 bytes
Fixed Size 2074152 bytes
Variable Size 637536728 bytes
Database Buffers 1493172224 bytes
Redo Buffers 14700544 bytes
Database mounted.
Database opened.
sys@ora10g>
2.在数据库启动成功之后,我们通过v$database视图和v$instance视图查看一下当前数据库的状态,以便和close后的状态进行比较
sys@ora10g> select open_mode from v$database;
OPEN_MODE
----------
READ WRITE
sys@ora10g> select status from v$instance;
STATUS
------------
OPEN
可以看到现在的数据库状态是open并且是可读写操作的状态。
3.此时我们使用“alter database close;”命令关闭数据库(注意这里我的用词,关闭的是“数据库”不是“实例”)
执行这个命令需要等待一段时间才能完成,存在一个数据库连接清理的过程。如果在Oracle 9i的环境下使用这个close命令,若数据库中存在其他的连接,命令将无法完成,会收到“ORA-01093: ALTER DATABASE CLOSE only permitted with no sessions connected”报错信息,这里的演示环境时10g,在10g中即使是存在着其他的连接也同样可以完成close过程。
sys@ora10g> alter database close;
Database altered.
4.再次查询v$database视图和v$instance视图中有关数据库状态的信息,与上面的信息进行比较
sys@ora10g> select open_mode from v$database;
OPEN_MODE
----------
MOUNTED
sys@ora10g> select status from v$instance;
STATUS
------------
MOUNTED
可以看到,此时数据库的状态已经变为“MOUNTED”的状态。
进一步检查一下此时数据库服务器有关该实例的后台数据库进程信息。通过下面的结果信息可以进一步确信,“alter database close;”操作并没有将数据库的实例关闭,仅仅是将数据库的状态从“OPEN”状态带到了“MOUNT”状态
sys@ora10g> !ps -ef | grep 'ora_.*ora10g' | grep -v grep
oracle 867 1 0 22:31 ? 00:00:00 ora_pmon_ora10g
oracle 869 1 0 22:31 ? 00:00:00 ora_psp0_ora10g
oracle 871 1 0 22:31 ? 00:00:00 ora_mman_ora10g
oracle 873 1 0 22:31 ? 00:00:00 ora_dbw0_ora10g
oracle 875 1 0 22:31 ? 00:00:00 ora_dbw1_ora10g
oracle 877 1 0 22:31 ? 00:00:00 ora_lgwr_ora10g
oracle 879 1 0 22:31 ? 00:00:00 ora_ckpt_ora10g
oracle 881 1 0 22:31 ? 00:00:00 ora_smon_ora10g
oracle 883 1 0 22:31 ? 00:00:00 ora_reco_ora10g
oracle 887 1 0 22:31 ? 00:00:00 ora_mmon_ora10g
oracle 889 1 0 22:31 ? 00:00:00 ora_mmnl_ora10g
5.既然数据库的状态现在是mount状态,我们尝试使用open命令重新开启该数据库。结果很显然,在这样的状态下,我们是无法再次open该数据库的。
sys@ora10g> alter database open;
alter database open
*
ERROR at line 1:
ORA-16196: database has been previously opened and closed
6.使用oerr工具查看一下“ORA-16196”报错信息含义。从原因信息描述中可以非常清晰的得到具体的原因和后续的处理方法。
sys@ora10g> ! oerr ora 16196
16196, 00000, "database has been previously opened and closed"
// *Cause: The instance has already opened and closed the database,
// which is allowed only once in its lifetime.
// *Action: Shut down the instance.
7.此时如果想要重新使用该数据库,只有按照上面提示信息中“Action:”部分描述的操作:关闭数据库并重新开启。
sys@ora10g> shutdown immediate;
ORA-01109: database not open
Database dismounted.
ORACLE instance shut down.
sys@ora10g> startup ;
ORACLE instance started.
Total System Global Area 2147483648 bytes
Fixed Size 2074152 bytes
Variable Size 637536728 bytes
Database Buffers 1493172224 bytes
Redo Buffers 14700544 bytes
Database mounted.
Database opened.
sys@ora10g>
sys@ora10g> select open_mode from v$database;
OPEN_MODE
----------
READ WRITE
sys@ora10g> select status from v$instance;
STATUS
------------
OPEN
OK,到此,数据库又一个崭新的生命周期开始了。
8.小结
通过上面的演示,大家应该对“一个实例在其生存期中最多只能装载和打开一个数据库。”这句话有了一个更加具体的理解。其实Oracle数据库的每一个状态都很值得认真研究,其中充满了N多令人神往的细节。
Good luck.
-- The End --