1. 在数据库启动之后,需要从操作系统上分配共享内存和信号量(Semaphore)资源,而在某些情况下,数据库异常关闭后,这些资源有可能无法正常释放,则在下次启动时,数据库可能遭遇错误,无法正常启动。  
  2.  
  3. 在一个客户环境(操作系统为SUN Solaris平台)中出现了ORA-04031错误之后,使用了shutdown abort选项关闭了数据库:  
  4.  
  5. Sun Jul 19 19:20:23 2009  
  6.  
  7. Errors in file /ora9i/oracle/admin/ora9i/bdump/ora9i1_j000_14337.trc:  
  8.  
  9. ORA-12012: error on auto execute of job 721  
  10.  
  11. ORA-04031: unable to allocate 4088 bytes of shared memory ("shared pool","STANDARDSYS","PL/SQL MPCODE","BAMIMA: Bam Buffer")  
  12.  
  13. Sun Jul 19 19:24:24 2009  
  14.  
  15. Errors in file /ora9i/oracle/admin/ora9i/bdump/ora9i1_j000_17497.trc:  
  16.  
  17. ORA-12012: error on auto execute of job 721  
  18.  
  19. ORA-04031: unable to allocate 4088 bytes of shared memory ("shared pool","STANDARDSYS","PL/SQL MPCODE","BAMIMA: Bam Buffer")  
  20.  
  21. Sun Jul 19 19:26:56 2009  
  22.  
  23. Shutting down instance (abort)  
  24.  
  25. License high water mark = 1012  
  26.  
  27. Instance terminated by USER, pid = 19157  
  28.  
  29. 接下来的尝试启动失败,告警日志记录了如下所示的错误信息:  
  30.  
  31. Sun Jul 19 19:35:27 2009  
  32.  
  33. Errors in file /ora9i/oracle/admin/ora9i/udump/ora9i1_ora_25055.trc:  
  34.  
  35. ORA-27154: post/wait create failed  
  36.  
  37. ORA-27300: OS system dependent operation:semget failed with status: 28  
  38.  
  39. ORA-27301: OS failure message: No space left on device  
  40.  
  41. ORA-27302: failure occurred at: sskgpsemsper  
  42.  
  43. 注意以上信息中,提示失败的操作是semget,其实如果仔细阅读这个提示,就可以获知错误的真正原因,在操作系统可以通过man semget查看手册,了解出错的真实原因。以下输出告诉我们,semget的任务是获得信号量集(get set of semaphores),所以也就可以知道之前的提示No space left on device并不是指存储空间,而是信号量资源:  
  44.  
  45. oracle@db-server # man semget  
  46.  
  47. NAME 
  48.  
  49.      semget - get set of semaphores  
  50.  
  51. SYNOPSIS  
  52.  
  53.      #include  
  54.  
  55.      #include  
  56.  
  57.      #include  
  58.  
  59.      int semget(key_t keyint nsems, int semflg);  
  60.  
  61. DESCRIPTION  
  62.  
  63.      The semget() function returns the semaphore identifier associated with key.  
  64.  
  65. 知道了这个原因以后,就可以通过ipcs命令来找到数据库的信号量资源占用,该主机上有三个数据库,Oracle用户的信号量集就是没有正常释放的那个:  
  66.  
  67. oracle@db-server # ipcs -sa  
  68.  
  69. IPC status from as of Sun Jul 19 22:01:09 CST 2009  
  70.  
  71. T      ID      KEY        MODE        OWNER GROUP  CREATOR   CGROUP NSEMS   OTIME    CTIME  
  72.  
  73. Semaphores:  
  74.  
  75. s  851977   0x462fcb40 --ra-r----- orabil9 dbabil9  orabil9  dbabil9   604 22:07:58 12:54:47  
  76.  
  77. s 1769482   0x6b997db0 --ra-r----- oracle9    dba9  oracle9     dba9  2004 22:07:15 17:03:39  
  78.  
  79. s 1245195   0x8ea0d4d4 --ra-ra----  oracle   dba   oracle      dba  2004 no-entry 19:27:06  
  80.  
  81. 接下来就可以通过操作系统的ipcrm命令来移除信号量集:  
  82.  
  83. oracle@db-server # man ipcrm  
  84.  
  85. NAME 
  86.  
  87.        ipcrm - remove a message queue, semaphore set or shared memory id  
  88.  
  89. 执行过程如下所示:  
  90.  
  91. oracle@db-server # ipcrm -s 1245195  
  92.  
  93. oracle@db-server # ipcs -sa  
  94.  
  95. IPC status from as of Sun Jul 19 22:09:01 CST 2009  
  96.  
  97. T      ID      KEY        MODE        OWNER    GROUP  CREATOR   CGROUP NSEMS   OTIME    CTIME  
  98.  
  99. Semaphores:  
  100.  
  101. s  851977   0x462fcb40 --ra-r----- orabil9 dbabil9  orabil9  dbabil9   604 22:07:58 12:54:47  
  102.  
  103. s 1769482   0x6b997db0 --ra-r----- oracle9    dba9  oracle9     dba9  2004 22:07:15 17:03:39  
  104.  
  105. 完成这个操作之后,数据库就可以正常启动了。  
  106.  
  107.    
  108. 这个案例告诉我们的是,如果采用特殊手段来进行维护和管理,那么必须清楚这些操作可能带来的影响和后果。