Disco Lleno: Cómo Encontrar y Limpiar Espacio
Introducción
Un disco lleno es uno de los problemas más comunes y críticos que afectan a los servidores Linux. Cuando los sistemas de archivos alcanzan el 100% de capacidad, las aplicaciones fallan al escribir datos, los logs dejan de registrarse, las bases de datos se corrompen y los servicios se caen. Comprender cómo identificar rápidamente qué está consumiendo espacio en disco y cómo recuperarlo de forma segura es esencial para cada administrador de sistemas.
Esta guía completa proporciona herramientas prácticas de línea de comandos y metodologías sistemáticas para diagnosticar y resolver problemas de espacio en disco. Aprenderás cómo encontrar archivos grandes, identificar directorios que consumen espacio, limpiar datos innecesarios e implementar medidas preventivas para evitar futuros problemas de espacio en disco.
Los problemas de espacio en disco a menudo escalan rápidamente, especialmente en servidores con registro intensivo o procesamiento de datos. Esta guía te enseñará a reconocer señales de advertencia temprana, realizar análisis detallados e implementar procedimientos de limpieza automatizados para mantener una utilización de disco saludable en tu infraestructura.
Comprendiendo los Problemas de Espacio en Disco
Causas Comunes de Disco Lleno
Archivos de Log: Logs de aplicación, sistema o servidor web que crecen rápidamente Archivos Temporales: Archivos acumulados en /tmp, /var/tmp y directorios de caché Crecimiento de Base de Datos: Archivos de base de datos en expansión y logs de transacciones Respaldos: Archivos de respaldo antiguos que no se rotan Core Dumps: Archivos de volcado grandes de aplicaciones caídas Caché de Paquetes: Paquetes descargados que no se limpian Datos de Usuario: Archivos cargados, adjuntos de correo, directorios home de usuario Archivos Huérfanos: Archivos de aplicaciones desinstaladas Agotamiento de Inodos: Demasiados archivos pequeños consumiendo todos los inodos
Umbrales Críticos
Comprendiendo umbrales de uso de disco:
- 0-70%: Rango saludable normal
- 70-85%: Monitorear de cerca
- 85-95%: Advertencia - tomar acción pronto
- 95-98%: Crítico - acción inmediata necesaria
- 98-100%: Emergencia - degradación de servicio probable
Importante: Algunos sistemas de archivos (como ext4) reservan 5% para root, por lo que 95% puede aparecer como 100% para usuarios regulares.
Evaluación Inicial del Espacio en Disco
Verificación Rápida del Estado del Disco
Comienza con estos comandos de evaluación rápida:
# Vista general de todos los sistemas de archivos
df -h
# Legible por humanos con tipo de sistema de archivos
df -hT
# Uso de inodos
df -i
# Sistema de archivos específico
df -h /
# Excluir tipos específicos de sistema de archivos
df -h -x tmpfs -x devtmpfs
# Ordenar por uso
df -h | sort -k5 -rh
# Alertar en alto uso
df -h | awk '$5+0 > 85 {print $0}'
Interpretación rápida:
# Si Use% > 95%
# ENTONCES acción inmediata requerida
# Si IUse% > 90%
# ENTONCES demasiados archivos pequeños (agotamiento de inodos)
# Si /var, /var/log lleno
# ENTONCES probable problema de archivos de log
# Si /home lleno
# ENTONCES acumulación de datos de usuario
Comprendiendo la Salida de df
df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 47G 1.5G 97% /
/dev/sda2 ext4 100G 15G 80G 16% /home
tmpfs tmpfs 7.8G 0 7.8G 0% /dev/shm
Columnas clave:
- Filesystem: Dispositivo o partición
- Type: Tipo de sistema de archivos (ext4, xfs, etc.)
- Size: Capacidad total
- Used: Espacio actualmente usado
- Avail: Espacio disponible
- Use%: Porcentaje usado
- Mounted on: Punto de montaje
Paso 1: Identificar Directorios Grandes
Usando el Comando du
El comando du (disk usage - uso de disco) muestra tamaños de directorios:
# Tamaño del directorio actual
du -sh .
# Todos los subdirectorios
du -sh *
# Directorios de nivel superior desde raíz
du -sh /* 2>/dev/null
# Ordenar por tamaño
du -sh /* 2>/dev/null | sort -rh
# Top 10 directorios más grandes
du -h / 2>/dev/null | sort -rh | head -10
# Análisis de directorio específico
du -h /var/log | sort -rh | head -20
# Mostrar solo directorios mayores a 1GB
du -h / 2>/dev/null | grep "^[0-9\.]*G"
# Excluir ciertas rutas
du -h --exclude=/proc --exclude=/sys / 2>/dev/null | sort -rh | head -20
# Profundidad máxima
du -h --max-depth=1 /var | sort -rh
Analizando Directorios Comunes
# Directorio de logs
du -sh /var/log/* | sort -rh | head -10
# Directorios home
du -sh /home/* | sort -rh
# Directorios temporales
du -sh /tmp /var/tmp /dev/shm
# Caché de paquetes
du -sh /var/cache/apt/archives # Debian/Ubuntu
du -sh /var/cache/yum # CentOS/RHEL
# Docker
du -sh /var/lib/docker
# Base de datos
du -sh /var/lib/mysql
du -sh /var/lib/postgresql
# Directorios web
du -sh /var/www/*
# Directorios de correo
du -sh /var/mail/*
Script Automatizado de Análisis de Directorio
cat > /tmp/disk-analysis.sh << 'EOF'
#!/bin/bash
echo "Disk Space Analysis - $(date)"
echo "========================================"
echo ""
echo "Filesystem Usage:"
df -hT | grep -v "tmpfs\|devtmpfs"
echo ""
echo "Largest Directories in /:"
du -sh /* 2>/dev/null | sort -rh | head -10
echo ""
echo "Largest Directories in /var:"
du -sh /var/* 2>/dev/null | sort -rh | head -10
echo ""
echo "Log Files:"
du -sh /var/log/* 2>/dev/null | sort -rh | head -10
echo ""
echo "Largest Users:"
du -sh /home/* 2>/dev/null | sort -rh | head -10
echo ""
echo "Temporary Files:"
du -sh /tmp /var/tmp 2>/dev/null
EOF
chmod +x /tmp/disk-analysis.sh
/tmp/disk-analysis.sh
Paso 2: Encontrar Archivos Grandes
Usando el Comando find
Localizar archivos grandes específicos:
# Archivos mayores a 100MB
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
# Archivos mayores a 1GB con detalles
find / -type f -size +1G -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh
# Top 20 archivos más grandes
find / -type f -printf '%s %p\n' 2>/dev/null | sort -nr | head -20 | awk '{print $1/1024/1024 "MB", $2}'
# Archivos grandes en directorio específico
find /var -type f -size +50M -exec ls -lh {} \; 2>/dev/null
# Archivos grandes modificados en los últimos 7 días
find / -type f -size +100M -mtime -7 -exec ls -lh {} \; 2>/dev/null
# Archivos mayores a 500MB ordenados
find / -type f -size +500M -printf '%s %p\n' 2>/dev/null | sort -rn | awk '{printf "%.2f GB %s\n", $1/1024/1024/1024, $2}'
# Archivos de log grandes
find /var/log -type f -size +50M -exec ls -lh {} \; 2>/dev/null
# Archivos core dump
find / -name "core.*" -o -name "*.core" 2>/dev/null -exec ls -lh {} \;
Encontrar Archivos por Antigüedad
# Archivos mayores a 30 días
find / -type f -mtime +30 -size +10M 2>/dev/null
# Archivos no accedidos en 90 días
find / -type f -atime +90 -size +50M 2>/dev/null
# Archivos grandes creados recientemente
find / -type f -size +100M -mtime -1 -exec ls -lh {} \; 2>/dev/null
# Archivos temporales antiguos
find /tmp -type f -mtime +7 -exec ls -lh {} \; 2>/dev/null
find /var/tmp -type f -mtime +30 -exec ls -lh {} \; 2>/dev/null
Script Rápido de Búsqueda de Archivos Grandes
cat > /tmp/find-large-files.sh << 'EOF'
#!/bin/bash
SIZE_MB=${1:-100}
echo "Finding files larger than ${SIZE_MB}MB..."
echo ""
find / -type f -size +${SIZE_MB}M 2>/dev/null -printf '%s %p\n' |
sort -rn |
head -20 |
while read size path; do
size_mb=$(echo "scale=2; $size/1024/1024" | bc)
printf "%8.2f MB %s\n" $size_mb "$path"
done
EOF
chmod +x /tmp/find-large-files.sh
# Encontrar archivos > 100MB
/tmp/find-large-files.sh 100
# Encontrar archivos > 500MB
/tmp/find-large-files.sh 500
Paso 3: Analizar Áreas Problemáticas Específicas
Análisis de Archivos de Log
Los logs son la causa más común de problemas de espacio en disco:
# Tamaño del directorio de logs
du -sh /var/log
du -sh /var/log/* | sort -rh | head -10
# Archivos de log más grandes
find /var/log -type f -printf '%s %p\n' | sort -rn | head -20 | awk '{print $1/1024/1024 "MB", $2}'
# Logs que crecen activamente
ls -lth /var/log/*.log | head -10
# Encontrar logs no rotados
find /var/log -name "*.log" -size +100M
# Tamaño de logs de journal
du -sh /var/log/journal
journalctl --disk-usage
# Verificar configuración de rotación de logs
cat /etc/logrotate.conf
ls -la /etc/logrotate.d/
# Probar logrotate
logrotate -d /etc/logrotate.conf
Caché del Gestor de Paquetes
Las cachés de paquetes pueden consumir espacio significativo:
# Caché APT de Debian/Ubuntu
du -sh /var/cache/apt/archives
ls -lh /var/cache/apt/archives/*.deb 2>/dev/null | wc -l
# Limpiar caché APT
apt clean
apt autoclean
# Caché YUM de CentOS/RHEL
du -sh /var/cache/yum
yum clean all
# Caché DNF (sistemas más nuevos)
du -sh /var/cache/dnf
dnf clean all
# Listar paquetes en caché
ls -lh /var/cache/apt/archives/*.deb 2>/dev/null
Limpieza de Docker
Docker puede acumular almacenamiento significativo:
# Uso de disco de Docker
docker system df
# Desglose detallado
docker system df -v
# Eliminar contenedores no usados
docker container prune -f
# Eliminar imágenes no usadas
docker image prune -a -f
# Eliminar volúmenes no usados
docker volume prune -f
# Eliminar todo lo no usado
docker system prune -a -f --volumes
# Verificar tamaño del directorio raíz de Docker
du -sh /var/lib/docker
du -sh /var/lib/docker/overlay2
Archivos de Base de Datos
Los archivos de base de datos pueden crecer rápidamente:
# Directorio de datos MySQL/MariaDB
du -sh /var/lib/mysql
du -sh /var/lib/mysql/* | sort -rh
# Logs binarios MySQL
du -sh /var/lib/mysql/mysql-bin.*
mysql -e "SHOW BINARY LOGS;"
# Purgar logs binarios antiguos (mantener últimos 3 días)
mysql -e "PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 3 DAY);"
# PostgreSQL
du -sh /var/lib/postgresql
du -sh /var/lib/postgresql/*/main/base/* | sort -rh
# MongoDB
du -sh /var/lib/mongodb
# Verificar tamaños de base de datos
mysql -e "SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables GROUP BY table_schema ORDER BY SUM(data_length + index_length) DESC;"
Archivos de Servidor Web
# Directorios web
du -sh /var/www/* | sort -rh
# Directorios de uploads
find /var/www -name uploads -o -name files | xargs du -sh
# Archivos subidos antiguos
find /var/www -name uploads -type d -exec find {} -type f -mtime +90 \; | wc -l
# Archivos temporales web
find /var/www -name "*.tmp" -o -name "*.cache" | xargs du -ch
Paso 4: Agotamiento de Inodos
Verificar Uso de Inodos
# Uso de inodos
df -i
# Encontrar directorios con más archivos
for dir in /*; do
echo "$dir: $(find $dir -type f 2>/dev/null | wc -l) files"
done | sort -t: -k2 -rn
# Contar archivos en subdirectorios
find /var -maxdepth 2 -type d -exec sh -c 'echo "{}: $(find "{}" -type f | wc -l)"' \; | sort -t: -k2 -rn | head -20
# Encontrar directorios con archivos pequeños excesivos
du -a / 2>/dev/null | sort -n -r | head -n 50 | awk '{if($1 < 100) print $0}'
# Archivos de sesión
ls /tmp | wc -l
ls /var/tmp | wc -l
ls /var/lib/php/sessions 2>/dev/null | wc -l
Limpieza de Problemas de Inodos
# Eliminar sesiones PHP antiguas
find /var/lib/php/sessions -type f -mtime +7 -delete
# Eliminar archivos temporales antiguos
find /tmp -type f -mtime +7 -delete
find /var/tmp -type f -mtime +30 -delete
# Limpiar cola de correo
postqueue -p | wc -l
postsuper -d ALL deferred
Paso 5: Procedimientos de Limpieza Segura
Limpieza de Archivos de Log
# Truncar logs grandes (preservar archivo)
truncate -s 0 /var/log/large.log
# Alternativa: vaciar log manteniendo archivo
> /var/log/large.log
# Eliminar logs rotados antiguos
find /var/log -name "*.log.*" -mtime +30 -delete
find /var/log -name "*.gz" -mtime +30 -delete
# Limpiar logs de journal (mantener 2 días)
journalctl --vacuum-time=2d
# Limpiar logs de journal (mantener 1GB)
journalctl --vacuum-size=1G
# Rotar logs manualmente
logrotate -f /etc/logrotate.conf
# Eliminar archivos kern.log antiguos
find /var/log -name "kern.log.*" -mtime +7 -delete
Limpieza de Archivos Temporales
# Limpiar /tmp (archivos mayores a 7 días)
find /tmp -type f -atime +7 -delete
# Limpiar /var/tmp (mayores a 30 días)
find /var/tmp -type f -atime +30 -delete
# Limpiar caché de usuario
rm -rf ~/.cache/*
# Limpiar caché de miniaturas
rm -rf ~/.thumbnails/*
# Archivos temporales del sistema
rm -rf /tmp/*
rm -rf /var/tmp/*
# Advertencia: Solo si no hay procesos activos usando estos archivos
Limpieza de Paquetes
# Debian/Ubuntu
apt autoremove -y
apt autoclean
apt clean
# Eliminar kernels antiguos (mantener actual y uno anterior)
apt autoremove --purge -y
# Listar kernels instalados
dpkg --list | grep linux-image
# CentOS/RHEL
yum autoremove -y
yum clean all
# Eliminar kernels antiguos
package-cleanup --oldkernels --count=2
# Listar kernels instalados
rpm -qa kernel
Limpieza de Datos de Usuario
# Encontrar archivos grandes de usuario
du -sh /home/* | sort -rh
# Descargas antiguas
find /home/*/Downloads -type f -mtime +30
# Archivos de correo grandes
du -sh /var/mail/*
# Limpiar historial de bash
history -c
> ~/.bash_history
# Eliminar volcados de core antiguos
find /home -name "core.*" -delete
find / -name "core" -type f -delete 2>/dev/null
Paso 6: Técnicas Avanzadas de Limpieza
Encontrar Archivos Eliminados pero Abiertos
Archivos eliminados pero aún mantenidos abiertos por procesos:
# Listar archivos eliminados aún abiertos
lsof | grep deleted
# Vista detallada
lsof +L1
# Tamaño de archivos eliminados abiertos
lsof +L1 | awk '{sum+=$7} END {print "Total:", sum/1024/1024 "MB"}'
# Matar proceso manteniendo archivo eliminado
kill -9 $(lsof +L1 | grep filename | awk '{print $2}')
# Alternativa: reiniciar servicio
systemctl restart service-name
Detección de Archivos Sparse
# Encontrar archivos sparse
find / -type f -printf "%S %p\n" 2>/dev/null | awk '$1 < 1.0 {print}'
# Verificar si archivo es sparse
du --apparent-size -h file.img
du -h file.img
# Si son diferentes, el archivo es sparse
Encontrar Duplicados
# Encontrar archivos duplicados con fdupes
apt install fdupes
fdupes -r /home
# Eliminar duplicados interactivamente
fdupes -rd /home
# Encontrar archivos duplicados manualmente
find /path -type f -exec md5sum {} + | sort | uniq -w32 -dD
Soluciones y Prevención
Implementar Rotación de Logs
# Configurar logrotate para aplicación personalizada
cat > /etc/logrotate.d/myapp << 'EOF'
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
sharedscripts
postrotate
systemctl reload myapp >/dev/null 2>&1 || true
endscript
}
EOF
# Probar configuración
logrotate -d /etc/logrotate.d/myapp
# Forzar rotación
logrotate -f /etc/logrotate.d/myapp
Scripts de Limpieza Automatizada
cat > /usr/local/bin/disk-cleanup.sh << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/disk-cleanup.log"
echo "$(date): Starting disk cleanup" >> "$LOG_FILE"
# Limpiar caché de paquetes
apt autoclean -y >> "$LOG_FILE" 2>&1
apt autoremove -y >> "$LOG_FILE" 2>&1
# Limpiar logs antiguos
find /var/log -name "*.log.*" -mtime +30 -delete
find /var/log -name "*.gz" -mtime +30 -delete
# Limpiar archivos temporales
find /tmp -type f -atime +7 -delete
find /var/tmp -type f -atime +30 -delete
# Limpiar journal
journalctl --vacuum-time=7d >> "$LOG_FILE" 2>&1
# Limpiar Docker (si está instalado)
if command -v docker &> /dev/null; then
docker system prune -f >> "$LOG_FILE" 2>&1
fi
# Reportar uso de disco
echo "$(date): Disk cleanup completed" >> "$LOG_FILE"
df -h >> "$LOG_FILE"
EOF
chmod +x /usr/local/bin/disk-cleanup.sh
# Programar limpieza semanal
echo "0 2 * * 0 /usr/local/bin/disk-cleanup.sh" | crontab -
Monitoreo de Uso de Disco
cat > /usr/local/bin/disk-monitor.sh << 'EOF'
#!/bin/bash
THRESHOLD=85
ALERT_EMAIL="[email protected]"
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $1 " " $6}' | while read output;
do
usage=$(echo $output | awk '{print $1}' | cut -d'%' -f1)
partition=$(echo $output | awk '{print $2}')
mount=$(echo $output | awk '{print $3}')
if [ $usage -ge $THRESHOLD ]; then
echo "Alert: Disk usage on $partition ($mount) is ${usage}%" | \
mail -s "Disk Space Alert on $(hostname)" "$ALERT_EMAIL"
# Registrar principales consumidores de espacio
echo "Top consumers in $mount:" | mail -s "Disk Details" "$ALERT_EMAIL"
du -sh $mount/* 2>/dev/null | sort -rh | head -10 | \
mail -s "Disk Usage Details" "$ALERT_EMAIL"
fi
done
EOF
chmod +x /usr/local/bin/disk-monitor.sh
# Ejecutar cada hora
echo "0 * * * * /usr/local/bin/disk-monitor.sh" | crontab -
Implementación de Cuotas
# Instalar herramientas de cuota
apt install quota
# Editar /etc/fstab, agregar usrquota,grpquota
/dev/sda2 /home ext4 defaults,usrquota,grpquota 0 2
# Remontar
mount -o remount /home
# Crear archivos de cuota
quotacheck -cum /home
quotacheck -cgm /home
# Habilitar cuotas
quotaon -v /home
# Establecer cuota de usuario (1GB soft, 1.5GB hard)
setquota -u username 1000000 1500000 0 0 /home
# Establecer cuota de grupo
setquota -g groupname 5000000 6000000 0 0 /home
# Verificar cuota
quota -u username
repquota -a
Configurar Alertas
cat > /etc/cron.hourly/disk-alert << 'EOF'
#!/bin/bash
USAGE=$(df / | tail -1 | awk '{print $5}' | cut -d'%' -f1)
if [ $USAGE -gt 90 ]; then
echo "Critical: Root filesystem is ${USAGE}% full on $(hostname)" | \
mail -s "CRITICAL: Disk Space Alert" [email protected]
elif [ $USAGE -gt 80 ]; then
echo "Warning: Root filesystem is ${USAGE}% full on $(hostname)" | \
mail -s "WARNING: Disk Space Alert" [email protected]
fi
EOF
chmod +x /etc/cron.hourly/disk-alert
Procedimientos de Emergencia
Cuando el Disco Está 100% Lleno
# 1. Liberar algo de espacio inmediatamente
rm -f /var/log/*.log.1 /var/log/*.log.*.gz
# 2. Truncar log más grande
largest_log=$(find /var/log -type f -printf '%s %p\n' | sort -rn | head -1 | awk '{print $2}')
truncate -s 0 "$largest_log"
# 3. Limpiar caché de paquetes
apt clean
yum clean all
# 4. Limpiar archivos temporales
rm -rf /tmp/*
rm -rf /var/tmp/*
# 5. Verificar y reiniciar servicios afectados
systemctl status
systemctl restart failing-service
Partición de Boot Llena
# Listar kernels instalados
dpkg --list | grep linux-image
# Eliminar kernels antiguos (mantener actual + 1)
apt autoremove --purge -y
# Eliminar manualmente kernel antiguo
apt remove linux-image-VERSION-generic
# Limpiar /boot
rm -f /boot/*.old-dkms
update-grub
Conclusión
La gestión del espacio en disco es crucial para la estabilidad del sistema y requiere monitoreo y mantenimiento proactivos. Conclusiones clave:
- Monitorear proactivamente: No esperar hasta llegar al 100% para tomar acción
- Implementar rotación de logs: Prevenir que los logs consuman todo el espacio
- Automatizar limpieza: Programar tareas de mantenimiento regulares
- Configurar alertas: Ser notificado antes de umbrales críticos
- Usar cuotas: Prevenir que usuarios individuales consuman todo el espacio
- Conocer tus datos: Comprender qué debería y no debería estar en el sistema
- Documentar procedimientos: Mantener scripts y procedimientos de limpieza listos
El monitoreo regular, procedimientos de limpieza automatizados y la comprensión de estas herramientas de diagnóstico te ayudarán a prevenir emergencias de espacio en disco y resolver rápidamente problemas cuando ocurran. Mantén estos comandos fácilmente disponibles para solución rápida de problemas cuando surjan problemas de espacio en disco.


