环境介绍:

双机
操作系统:solaris 10
数据库版本:oracle 11g R1 64bit

      1、在双机软件界面上,点击进入维护模式,然后在操作系统,手动关闭监听,关闭数据库时报:ORA-03113: end-of-file on communication channel

bash-3.00$lsnrctl stop
bash-3.00$sqlplus /nolog
SQL>conn /as sysdba
SQL> shutdown immediate
Database closed.
Database dismounted.
ORA-03113: end-of-file on communication channel

     2、看到该错误,查看oracle的后台进程,已经没有了,如下所示:

bash-3.00$ ps -ef | grep ora_
oracle 17382 12315   0 01:06:20 pts/5       0:00 grep ora_

     3、退出当前的sqlplus,再次尝试启动数据库,报错如下:

bash-3.00$sqlplus /nolog
SQL> conn /as sysdba
Connected to an idle instance.
SQL> startup
ORA-01081: cannot start already-running ORACLE - shut it down first

      4、执行ipcs命令,查看到oracle并没有释放所占用的内存资源

bash-3.00$ ipcs
IPC status from <running system> as of Tue Dec 17 01:22:26 CST 2013
T         ID      KEY        MODE        OWNER    GROUP
Message Queues:
q         53   0x4c544952 --rw-rw-rw-     root     root
q         32   0x4d6      --rw-rw-rw-     root     root
Shared Memory:
m  335544442   0x4d4e5251 --rw-r--r--     root     root
m  503316539   0x75a5fd0  --rw-rw----   oracle oinstall
m  503316538   0          --rw-rw----   oracle oinstall
m  503316537   0          --rw-rw----   oracle oinstall
m  503316536   0          --rw-rw----   oracle oinstall
m  503316535   0          --rw-rw----   oracle oinstall
m  503316518   0          --rw-------   oracle     root
Semaphores:
s   16777253   0x5653     --ra-ra-ra-     root     root
s         64   0x5301e9e8 --ra-------     root     root

      5、当时提出的解决办法是,要么重启操作系统,要么执行shutdown abort,执行shutdown abort,再启动数据库,数据库能够正常启动

bash-3.00$sqlplus /nolog
SQL>conn /as sysdba
SQL>shutdown abort
SQL>startup

     6、其实,也是可以通过ipcrm删除oracle未释放的共享内存段,如上ipcs的输出,可以通过如下命令删除oracle未释放的共享内存段:

ipcrm -m 503316538   //当执行了 ipcrm -m 503316538命令后,可能不需要执行以下3条命令了
ipcrm -m 503316537
ipcrm -m 503316536
ipcrm -m 503316535

      关于ipc的相关知识:

IPC Inter-Process Communication 进程间通信
ipcs可用来显示当前系统中的共享内存段、信号量集、消息队列等的使用情况。
命令示例:
ipcs -a或ipcs 显示当前系统中共享内存段、信号量集、消息队列的使用情况;
ipcs -m 显示共享内存段的使用情况;
ipcs -s 显示信号量集的使用情况;
ipcs -q 显示消息队列的使用情况;
ipcrm可用来删除对应的共享内存段、信号量、消息队列;
命令示例:
ipcrm -s semid  删除对应的信号量集
ipcrm -m shmid 删除对应的共享内存段
ipcrm -q msqid  删除对应的消息队列

      通过执行ipcs -mp可以获取和共享内存段相关的PID,然后通过ps -ef | grep PID,来决定是否kill这些占用共享内存段的PID

当执行ipcrm -m semid后,status字段将会标记dest,I just found out that "dest" means marked for destruction.To actually make the shared memory segment go away you need to kill the process using the shared memory segment.
when you call ipcs -mp you get a list of the PIDs associated with the shared memory segment. Then you can kill based on the PID or lookup the name of the PID by doing ps -ef | grep PID. I checked to see who is using the shared memory and then killed it.