Error ORA-27102: out of memory
Hoy estoy trabajando con una base de datos Oracle. Está en versión 11.2.0.4 bajo un sistema Solaris 10 Sparc.
Tras unos cambios que estoy haciendo, tenía la necesidad de reiniciarla. La parada ha ido bien, pero al intentar arrancarla…
🤡 ¡SORPRESA! 🤹🏼♂️ La base de datos no arranca. Nos arroja un error ORA-27102: out of memory.
¿Qué puede estar pasando? ¿Se habrá quedado el servidor sin memoria?
Si yo no he tocado los parámetros de memoria… ¿a que se debe ahora este error?
El Error
servidor1:/home/bbdd $ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.4.0 Production on Fri Oct 18 11:25:51 2024
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup;
ORA-27102: out of memory
SVR4 Error: 22: Invalid argument
Reviso un poco el alert.log de la base de datos, y me encuentro lo siguiente:
Fri Oct 18 11:21:08 2024
Starting ORACLE instance (normal)
WARNING: The system does not seem to be configured optimally. Creating a segment of size 0x00000003fa000000 failed. Please change the shm parameters so that a segment can be created for this size. While this is not a fatal issue, creating one segment may improve performance.
Análisis del error
Ves el error y te empiezas a hacer preguntas.
Lo primero que he pensado. A nivel de base de datos no he tocado ningún parámetro de inicio, no he tocado ningún parámetro de memoria. A nivel de servidor no he modificado ningún fichero de sistema, no he modificado el project ni el profile del usuario… ¿De qué se queja mi base de datos?
Con el comando TOP vamos a consultar la memoria total que hay en el servidor, y cuanta hay libre.
load averages: 0.75, 0.56, 0.51; up 251+22:47:34 13:40:35
255 processes: 252 sleeping, 2 zombie, 1 on cpu
CPU states: 94.8% idle, 4.0% user, 1.2% kernel, 0.0% stolen, 0.0% swap
Kernel: 6105 ctxsw, 5821 trap, 3926 intr, 17812 syscall, 28 fork, 276505863 flt, pgin
Memory: 75G phys mem, 49G free mem, 100G total swap, 100G free swap
Hay memoria suficiente. 75G que tiene el servidor y 49GB libres.
¿Cuánta memoria va a necesitar mi base de datos?
Consulto en el pfile o spfile los parámetros de inicio, y la SGA está establecida en 16GB. Hay más que de sobra.
Revisamos el project del usuario que levanta la base de datos en /etc/project y observamos la cantidad de memoria que tiene establecida.
project.max-shm-memory=(priv,21474836480,deny)
En Oracle Solaris, el parámetro de kernel “max-shm-memory ” está configurado para el tamaño de la memoria compartida. Este parámetro permitirá cambiar el tamaño de la SGA.
Por ejemplo, si este parámetro está configurado en 20 GB, como es nuestro caso, no podrás configurar el parámetro memory_max_target superando este valor. De manera predeterminada, se asignará el 25 % de la memoria para el parámetro de kernel.
En nuestro caso, el parámetro memory_max_target está a 0, por lo que la memoria se asginará dinámicamente.
Causa del error
El error ORA-27102 se genera cuando se inicia la instancia.
Es posible que haya memoria libre y disponible en el servidor, y además, el valor de los parámetros sga_max_size y memory_max_target de esta instancia sean menores que el valor establecido en el parámetro ‘project.max-shm-memory‘ del project del usuario de sistema operativo al que pertenece la instancia. Se debería revisar que en el apagado anterior de la base de datos, la instancia haya liberado los semáforos y la memoria compartida que tenía asignada anteriormente.
Solución
Vamos a usar el comando ipcs para ver la memoria compartida y semáforos que están activos en el sistema operativo actualmente. Para ello usaremos la opción ipcs -b
servidor1:/home/bbdd$ ipcs -b
IPC status from <running system> as of Fri Oct 18 11:43:34 CEST 2024
T ID KEY MODE OWNER GROUP QBYTES
Message Queues:
T ID KEY MODE OWNER GROUP SEGSZ
Shared Memory:
m 67108975 0xe0bf6208 --rw------- usuario1 oinstall 81920
m 67108974 0x0 --rw------- usuario1 oinstall 46137344
m 67108973 0x0 --rw------- usuario1 oinstall 201326592
m 67108972 0x0 --rw------- usuario1 oinstall 16911433728
m 67108971 0x0 --rw------- usuario1 oinstall 25165824
m 50331747 0x64611e80 --rw------- usuario2 oinstall 57344
m 50331746 0x0 --rw------- usuario2 oinstall 20971520
m 50331745 0x0 --rw------- usuario2 oinstall 234881024
m 50331744 0x0 --rw------- usuario2 oinstall 5100273664
m 50331743 0x0 --rw------- usuario2 oinstall 16777216
m 0 0x559089f1 --rw-r--r-- root root 392068
T ID KEY MODE OWNER GROUP NSEMS
Semaphores:
Observamos como hay varias líneas en la parte de memoria compartida que se están ejecutando actualmente y están afectando a nuestro problema. Alguno de estos identificadores con un tamaño bastante considerable de memoria.
Usaremos el comando ipcrm -m para eliminar esos identificadores de memoria compartida. Con la opción -m debemos indicar el identificador que queremos eliminar.
ipcrm
– Elimina una cola de mensajes, un conjunto de semáforos o una identificación de memoria compartida
ipcrm [ -z zona ] [ -m shmid ] [ -q msqid ] [ -s semid ] [ -M shmkey ] [ -Q msgkey ] [ -S semkey ]
servidor1:/home/bbdd $ ipcrm -m 67108975
servidor1:/home/bbdd $ ipcrm -m 67108974
servidor1:/home/bbdd $ ipcrm -m 67108973
servidor1:/home/bbdd $ ipcrm -m 67108972
servidor1:/home/bbdd $ ipcrm -m 67108971
Volvemos a lanzar ipcs -b para revisar de nuevo si los identificadores siguen ahí o han desaparecido.
Solo quedan los de otro usuario y otra base de datos distinta a la nuestra.
servidor1:/home/bbdd $ ipcs -b
IPC status from <running system> as of Fri Oct 18 11:44:32 CEST 2024
T ID KEY MODE OWNER GROUP QBYTES
Message Queues:
T ID KEY MODE OWNER GROUP SEGSZ
Shared Memory:
m 50331747 0x64611e80 --rw------- usuario2 oinstall 57344
m 50331746 0x0 --rw------- usuario2 oinstall 20971520
m 50331745 0x0 --rw------- usuario2 oinstall 234881024
m 50331744 0x0 --rw------- usuario2 oinstall 5100273664
m 50331743 0x0 --rw------- usuario2 oinstall 16777216
m 0 0x559089f1 --rw-r--r-- root root 392068
T ID KEY MODE OWNER GROUP NSEMS
Semaphores:
Llegados a este punto, vamos a levantar la base de datos de nuevo.
servidor1:/home/bbdd$ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.4.0 Production on Fri Oct 18 11:44:40 2024
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup;
ORACLE instance started.
Total System Global Area 1.7108E+10 bytes
Fixed Size 2198680 bytes
Variable Size 1.4932E+10 bytes
Database Buffers 2147483648 bytes
Redo Buffers 26861568 bytes
Base de datos montada.
Base de datos abierta.
SQL>
Y ahora si, ya no hay ningún error y la base de datos queda totalmente disponible y accesible.