Servidores Linux

Disco, memoria y procesos

Lección 6 de 8 · 15 min

Casi todo lo raro es uno de estos tres

Cuando un servidor «se comporta raro» -la aplicación no guarda, la base de datos se cae, el servicio no arranca- el origen suele ser uno de tres: se acabó el disco, se acabó la memoria, o un proceso se descontroló.

Lo incómodo es que ninguno de los tres se anuncia con un mensaje claro. Fallan por los lados, y por eso hay que saber preguntarles.

Disco: cuánto queda y quién se lo comió

Son dos preguntas distintas y dos comandos distintos, y ahí se atasca mucha gente: df dice cuánto falta; du dice quién se lo llevó.

De «está lleno» a «esto es lo que lo llenó»
# 1. Cuanto queda
df -h

# 2. Quien ocupa mas, en el primer nivel de la raiz
sudo du -h --max-depth=1 / 2>/dev/null | sort -rh | head -10

# 3. Se repite bajando por la rama mas gorda
sudo du -h --max-depth=1 /var | sort -rh | head -10

# 4. Los diez archivos mas grandes de una rama
sudo find /var -type f -size +100M -exec ls -lh {} \; 2>/dev/null | head
Resultado
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       197G  188G  1.2G  99% /

188G	/
171G	/var
9.4G	/usr

168G	/var/log
2.1G	/var/lib

La técnica es bajar por la rama más gorda, un nivel cada vez, hasta dar con el archivo. En el ejemplo, en dos pasos: la raíz señala a /var y /var señala a /var/log, con 168 GB de registros. Es la causa número uno de discos llenos.

Un registro que crece sin control no se arregla borrándolo. Vuelve a llenarse. Se limita: sudo journalctl --vacuum-time=30d para el diario de systemd, y se revisa por qué un servicio está escribiendo tantísimo -casi siempre es un error repitiéndose miles de veces por minuto, y ese error es el problema de verdad-.

El caso que hace perder una tarde entera

Este merece su propio apartado porque no se deduce, y cuando pasa uno da vueltas durante horas: df dice 100% lleno y du no encuentra nada.

La explicación es que alguien borró un archivo enorme -un registro, por ejemplo- mientras un proceso lo tenía abierto. En Linux, el espacio no se libera hasta que ese proceso lo suelta. El archivo ya no aparece en ningún listado, pero sigue ocupando el disco entero.

Encontrar el archivo fantasma
# Archivos borrados que algun proceso sigue teniendo abierto
sudo lsof +L1 | head
Resultado
COMMAND    PID  USER   FD   TYPE DEVICE   SIZE/OFF NLINK  NODE NAME
nginx     1287 www-data 5w  REG    8,1 92341827584     0 26214 /var/log/nginx/error.log (deleted)

Ahí está: 92 GB en un archivo que ya no existe. Se libera reiniciando el proceso que lo tiene abierto -sudo systemctl restart nginx-, no buscando archivos que borrar. La palabra clave en la salida es (deleted).

Memoria: la que parece llena y no lo está

Ya lo viste en la lección 2 y aquí es donde se aplica: en Linux, la memoria libre es memoria desperdiciada. El sistema usa lo que sobra como caché de disco -para no volver a leer lo mismo- y lo suelta en cuanto alguien lo necesita.

Por eso la columna free siempre asusta y casi nunca significa nada. La que se mira es available.

Leer la memoria de verdad
free -h
Resultado
               total        used        free      shared  buff/cache   available
Mem:            7.8Gi       4.1Gi       412Mi        88Mi       3.3Gi       3.4Gi
Swap:           2.0Gi       1.8Gi       210Mi

Qué mirar y qué ignorar

available: 3.4 Gi

Lo que una aplicación nueva podría usar ahora mismo, contando lo que el sistema soltaría de la caché.

Es el número real. Aquí hay memoria de sobra.

buff/cache: 3.3 Gi

Caché de disco. Parece «gastada» y es rendimiento gratis: se libera sola cuando hace falta.

Vaciarla a mano no mejora nada; solo obliga a releer del disco.

Swap casi lleno

Esta sí es una alerta. Swap es disco usado como si fuera memoria: cientos de veces más lento.

Un servidor tirando de swap va lentísimo aunque el procesador esté ocioso. Si está lleno, falta memoria de verdad.

Procesos: quién se está comiendo la máquina

Para ver qué está corriendo y cuánto consume, la herramienta clásica es top. Si la máquina tiene htop instalado, es lo mismo pero legible -se instala con sudo apt install htop-.

Ver los que más consumen, sin abrir nada interactivo
# Los 5 que mas procesador consumen
ps aux --sort=-%cpu | head -6

# Los 5 que mas memoria consumen
ps aux --sort=-%mem | head -6

# Cuantos nucleos tiene la maquina (para interpretar la carga)
nproc
Resultado
USER   PID %CPU %MEM    RSS COMMAND
mysql 2043 187.0 31.2 2489120 /usr/sbin/mysqld
www-d 1287   2.1  0.4   34112 nginx: worker process

Un %CPU por encima de 100 no es un error de lectura: se cuenta por núcleo. 187% en una máquina de 4 núcleos significa que está usando casi dos enteros. Por eso nproc importa para interpretarlo, igual que para leer la carga media del uptime.

Un proceso descontrolado, paso a paso

  1. 1. Identificarlo bien

    ps aux --sort=-%cpu | head y anota el PID, que es su número.

    Comprueba que es el que crees: matar el proceso equivocado en un servidor de producción corta el servicio.

  2. 2. Pedirle que termine bien

    kill 2043

    Es una petición educada: el programa cierra sus archivos, termina lo que estaba escribiendo y sale. Es lo que se intenta primero siempre.

  3. 3. Solo si no responde, forzar

    kill -9 2043

    Lo mata sin darle oportunidad de cerrar nada. En una base de datos eso puede dejar datos a medio escribir, así que es el último recurso y no el primero.

  4. 4. Preguntarse por qué pasó

    Un proceso que se descontrola una vez, vuelve. Matarlo es el parche; la causa está en su registro (journalctl -u servicio) o en un cambio reciente.

«La aplicación se cierra sola y no hay ningún error en su registro». Es un caso clásico y desconcertante: cuando la memoria se agota de verdad, el núcleo elige un proceso y lo mata desde fuera. La aplicación no llega a escribir nada porque no se entera.

El rastro está en el registro del sistema, no en el suyo: sudo journalctl -k | grep -i "out of memory". Si aparece, el problema no es la aplicación: es que falta memoria.

Dudas que salen aquí

Borré archivos y df no baja

Es el caso del archivo fantasma de más arriba: algún proceso lo tiene abierto todavía.

sudo lsof +L1 lo enseña, y se libera reiniciando ese proceso.

Hay espacio pero dice «disco lleno»

Puede haberse agotado el número de inodos -la cuenta de archivos, que es un límite aparte del espacio-. Pasa con millones de archivos diminutos, típicamente de sesiones o caché.

df -i lo muestra: si IUse% está al 100%, es eso.

¿Cuánta carga es demasiada?

Los tres números del uptime se comparan con nproc: una carga sostenida por encima del número de núcleos significa que hay trabajo esperando.

Importa más la tendencia que el instante: el tercer número (15 minutos) es el que dice si el problema persiste.

¿Conviene vaciar la caché de memoria?

No. Circula un comando para «liberar memoria» que vacía la caché de disco.

Deja un número más bonito en free y hace el servidor más lento, porque tiene que releer del disco todo lo que ya tenía a mano.

Compruébalo tú mismo

df -h dice 100% de disco usado, pero du no encuentra archivos grandes. ¿Qué pasa?

free -h muestra 412 Mi libres y 3.3 Gi en buff/cache. ¿Falta memoria?

Una aplicación se cierra sola y su registro no muestra ningún error. ¿Dónde miras?

Lo que sigue

Ya sabes diagnosticar la máquina por dentro. La siguiente lección mira hacia fuera: qué puertos tienes abiertos al mundo -incluido el que causaba el error de la lección 5-, cómo cerrar lo que no debería estar abierto, y cómo endurecer el acceso por SSH antes de que alguien lo intente.

Siguiente: Red, puertos y firewall

Continuar ← Servicios con systemd