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.

SQL Server 2022. Alta Disponibilidad con Always ON. Instalación paso a paso (III)
¿Sabías qué? Truco para editar consultas en SQL*Plus

Deja un comentario