Memoria y semaforos bloqueados shutdown abort (ORA-7307, ORA-27123, etc) | ExpoDBA

Memoria y semaforos bloqueados shutdown abort (ORA-7307, ORA-27123, etc)

Memoria y semaforos bloqueados shutdown abort (ORA-7307, ORA-27123, etc)

Cuando la base de datos levanta, intenta reservar semaforos en el sistema operativo y si no puede, falla con errores ORA-7307.

 
Luego de que el PMON muera en forma anormal,  porque lo hayan matado o lo que fuera, pueden haber quedado semáforos y segmentos de memoria bloqueados, por lo tanto la memoria no se libera y no se puede volver a levantar la base (existe la memoria pero no los procesos).
 
Esto se puede manifestar como una sesion colgada al momento de conectarse, o una conexión con sqlplus que al intentar hacer un shutdown indica que no hay instancias activas (y es verdad porque no está el pmon), y que al querer hacer un startup indica que no se pudo reservar memoria (Es verdad porque ya está reservada - ORA-7307)
 
En estos casos hay que liberar los segmentos de memoria y segmentos reservados para esa base de datos que ya no está levantada.
 
Para liberarlos primero debemos encontrarlos e identificarlos en la base de datos. 
 
Si en el server hay una sola base de datos, entonces simplemente debemos buscar que segmentos de memoria y semaforos están levantados con el usuario de la base de datos
 
ipcs -b muestra todos los segmentos de memoria, semaforos y queues tomados por el SO.
 
server> ipcs -b | grep  oracle
m   3145736 0x11893e1c --rw-r-----  oracle      dba 1346654208
En el ejemplo se filtra la salida del comando con un grep oracle, donde oracle es el osuser de la base de datos.
 
La salida de este comando muestra en la primera columna el tipo de recurso tomado y en este caso es m que representa un segmento de memoria, y si hubiese s representa un semaforo.
 
m   3145736 0x11893e1c --rw-r-----  oracle      dba 1346654208
La segunda columna muestra el ID del recurso, el cual necesitamos tener presente para poder liberarlo
 
m   3145736 0x11893e1c --rw-r-----  oracle      dba 1346654208
Para liberar los recursos necesitamos ejecutar el comando:
 
ipcrm -m 3145736
Donde -m indica que se trata de un segmento de memoria y 3145736 es para referenciar al ID del recurso.
Nota: si lo bloqueado hubiese sido un semaforo, deberíamos haber ejecutado ipcs -s <ID Semaforo>
 
Una vez ejecutado el comando los recursos tomados ya quedan liberadaos y se puede realizar un startup sin problemas.
 
En el caso de que tengamos con el usuario Oracle más de una base de datos levantada se nos puede complicar un poco más la busqueda de los recursos bloqueados.
 
Si la versión es 8.1.x o superior, debemos ingresar al server, setear las variables de entorno de la base de datos caída y ejecutar:
 
server> $ORACLE_HOME/bin/sysresv

IPC Resources for ORACLE_SID "MIBASE" :
Shared Memory:
ID              KEY
3145736         0x11893e1c
Oracle Instance not alive for sid "MIBASE"
Esto nos mostrará cuales son los recursos tomados y bastará con liberarlos como en el caso anterior.
 
Si la versión es anterior, lo que debemos hacer es lo siguiente:
Teniendo las variables ORACLE_SID y ORACLE_HOME  correctamente seteadas (Apuntando a la base de datos que actualmente tenemos caída) ingresamos al sqlplus como sysdba, configuramos oradebug para que trabaje con nuestro pid y pedimos a oradebug un trace con la configuración de memoria de nuestra sesion.
 
sqlplus "/ as sysdba"
SQL> oradebug setmypid
Sentencia procesada.
SQL> oradebug ipc
Information written to trace file.
SQL>exit
Esto lo que hace es justamente escribir un archivo trace en <user_dump_dest> que contiene información sobre los segmentos de memoria donde nuestra sesión guarda sus datos (que es la Memoria de la base).
 
cd <user_dump_dest>
ls -lrt *ora_*.trc
-rw-r-----   1 dbdata     dba           9255 Mar 16 13:42 <ORACLE_SID>_ora_3791.trc
Este archivo trace tiene información de segmentos y semaforos activos.
 
Ahora sí, con los ID de semaforo y segmento de memoria, se puede ejecutar el ipcrm respectivo a cada uno.
 
Nota:
En el caso de que conectados a la instancia caída, no se pueda sacar esta información, la única opción que queda es sacar los segmentos de memoria y semaforos de cada una de las bases levantadas en el server y por descarte identificar cual es el recurso que está tomado y no está en uso.
 
Referencias Metalink:

 

Agradecimientos:

A Andres Basile, Unix Administrator, por su ayuda en la redacción de esta nota.