Disco do servidor 100% cheo (0 bytes libres): recuperando unha base de datos accidentada cando rm e apt Fallo por falta de inodos/espazo¶
Os números de emerxencia varían segundo o país. Esta páxina usa 911, o número dos Estados Unidos e Canadá. Moitos outros países usan 112, 999 ou outro número. Busca o número do teu país.
Descubrindo que un servidor Linux de produción chegou 100% utilización do disco (0 bytes free) ou 100% utilización de inodos (df -i) mentres se executa unha base de datos PostgreSQL, MySQL/InnoDB, MariaDB ou SQLite activa é un dos modos de falla máis perigosos na administración de sistemas. A cero bytes ou cero inodos libres, a crise cae en cascada rapidamente: o núcleo do sistema operativo xa non pode crear sockets de dominio Unix en /tmp ou /var/run, bash non pode completar a tabulación porque non pode escribir shell pipes temporais, apt ou dnf non se pode executar para limpar paquetes porque os xestores de paquetes requiren ficheiros de bloqueo temporais e o seu motor de base de datos falla no medio dun rexistro de escritura anticipada (WAL) ou rexeita apagarse de forma limpa porque non pode asignar un só bloque de 4 kilobytes (0,004 megabytes) para o seu .pid ou bloquear o ficheiro. Peor aínda, os administradores en pánico adoitan executarse rm -rf /var/log/*.log en ficheiros de rexistro de varios gigabytes e mira con horror como df -h aínda informa 100% Use% (0 Avail), ou eliminan fatalmente pg_wal (pg_xlog) ou ib_logfile0 para liberar espazo, corrompindo permanentemente a base de datos máis aló da recuperación da transacción. Se eliminou accidentalmente ficheiros de base de datos críticos durante un intento de limpeza, pare inmediatamente e cambie a accidental rm -rf ou Shift-Delete de só lectura remonta e escultura de inodo; se o seu hardware de almacenamento subxacente está lanzando erros de E/S ou se bloqueou contra as escrituras, consulte Modo de só lectura súbito SSD e NVMe e o rescate desactivando TRIM ou recuperación de ficheiros de Word, Excel, PDF e bases de datos corruptos. Se esta interrupción afecta aos sistemas de seguridade dos hospitais, ao envío de emerxencias ou aos servizos públicos críticos, chame ao número de emerxencia local (911 nos Estados Unidos e Canadá, 112 en toda a Unión Europea, 999 no Reino Unido) ou consulte o noso directorio global de números de emerxencia.
Fai isto agora¶
- ** NON borrar
pg_wal/,pg_xlog/,pg_multixact/,ib_logfile*,undo_*, ou-wal/-shmficheiros para facer espazo**: a eliminación dos ficheiros de rexistro de Write-Ahead ou de InnoDB refacer/desfacer mentres unha base de datos está bloqueada ou desactivada destrúe o único rexistro de páxinas non comprometidas e en voo. Unha base de datos cun disco cheo é recuperable ao 100 por cento unha vez que se libera espazo; unha base de datos cuxos ficheiros WAL foron eliminados manualmentermsufrirá unha corrupción irreversible da árbore B e do montón. - Diagnóstica en 5 segundos se estás sen bloques de disco (
df -h), fóra dos inodos do sistema de ficheiros (df -i), ou mantendo abertos ficheiros desvinculados (lsof +L1): - Corre
df -hpara comprobar a capacidade do bloque edf -ipara comprobar a capacidade do inodo. Un servidor con 50 gigabytes (53.600 millóns de bytes) de espazo libre en disco aíndaNo space left on device (ENOSPC)sedf -imostraIUse% = 100%(normalmente causado por millóns de pequenos ficheiros de sesión, caché ou spool de correo). - Se
df -hmostra100%usado (0 Avail) mesmo despois de correrrmen ficheiros de rexistro enormes, executasudo lsof +L1. Calquera ficheiro eliminado conrmmentresnginx,rsyslog,docker,postgres, oumysqldaínda ten un descritor de ficheiro aberto segue consumindo o 100 por cento dos seus bloques de disco ata que se reinicie o proceso ou trunque o descritor directamente. - Gigabytes gratuítos de espazo en 1 segundo sen reiniciar os daemons truncando os ficheiros abertos no seu lugar (
: > /path/to/logfileou: > /proc/<pid>/fd/<n>): - No canto de
rm /var/log/syslog(o que deixa os bloques bloqueados polo rexistrador en execución), cero o ficheiro no seu lugar usando a redirección nula de shell:sudo sh -c ': > /var/log/syslog'ousudo truncate -s 0 /var/log/syslog. - Se xa correches
rmnun ficheiro de rexistro masivo edf -hnon caeu, busque o seu ID de proceso (PID) e o descritor do ficheiro (FD) ensudo lsof +L1e trunqueo directamente a través da interface procfs do núcleo:sudo sh -c ': > /proc/<PID>/fd/<FD>'. O espazo volverádf -hinstantáneamente. - ** Desbloquea a sala de respiración de emerxencia instantánea activada
ext4/ext3reducindo a porcentaxe de bloque raíz reservado (tune2fs -m 1)**: Por defecto,ext4reserva o 5 por cento de toda a partición (25 gigabytessobre a500 gigabytedisco) exclusivamente paraUID 0(root), é dicir, servizos non root comopostgres(UID 109),mysql, ewww-databaterNo space left on deviceao 95 por cento de utilización. Recupera o 80 por cento desa reserva en liña en 1 segundo sen tempo de inactividade correndosudo tune2fs -m 1 /dev/sda1(ou o seu dispositivo de bloqueo raíz defindmnt /). - ** Baleiro
systemd-journaldrexistros binarios e cachés de paquetes antigos con seguridade**: Executarsudo journalctl --vacuum-size=50M(que xira con seguridade e purga o binario/var/log/journalarquivos ata 50 megabytes) esudo apt-get clean(ousudo dnf clean all), que elimina os descargados.deb/.rpmarquivos en/var/cache/apt/archives/sen necesidade de escribir na base de datos dpkg. - Unha vez que polo menos 1 gigabyte a 5 gigabytes (de 1.070 a 5.360 millóns de bytes) de espazo estean libres, abra a base de datos en modo de usuario único ou de recuperación para completar o seu punto de control WAL antes de permitir o tráfico do cliente: Permita que PostgreSQL, MySQL/InnoDB ou SQLite reproduzan o seu rexistro de escritura anticipada (
WAL), limpa as páxinas sucias aos ficheiros de datos principais e recicla os seus segmentos WAL inchados limpamente antes de volver abrir o teu firewall de aplicacións ou o servidor web.
Danger
Nunca corres pg_resetwal (ou pg_resetxlog) en PostgreSQL ou innodb_force_recovery = 6 en MySQL simplemente porque o disco se encheu: En execución pg_resetwal borra os punteiros do rexistro de transaccións e obriga a PostgreSQL a comezar con páxinas de datos a medio escribir, o que garante a perda de filas silenciosas, as claves primarias duplicadas e as árbores B de claves estranxeiras rotas. No 99,9 por cento dos fallos de bases de datos con disco cheo, simplemente liberar de 2 gigabytes a 10 gigabytes (de 2.100 a 10.700 millóns de bytes) de espazo na partición e iniciar o daemon da base de datos normalmente permite a recuperación automática do fallo (REDO fase) para rematar limpamente sen perda de datos.
Árbore de decisións: servidor de espazo cero e triaxe de bases de datos fallidas¶
Use esta árbore de decisións para identificar por que o sistema operativo está a informar ENOSPC (No space left on device) e seleccione o camiño exacto de recuperación non destrutivo:
flowchart TD
Start["Lanzamento do servidor ou da base de datos: non queda espazo no dispositivo (ENOSPC)"] --> CheckDF["Executar: df -h E df -i"]
CheckDF --> DiagType{"Que informa df?"}
DiagType -->|"df -h Mostra o 100 % de uso (0 Dispoñibilidade) E df -i < 95 %"| BlockFull["Esgotamento do bloque: comproba se du -shx / Coincide con df -h"]
DiagType -->|"df -h mostra GB gratuítos PERO df -i mostra 100% de uso"| InodeFull["Esgotamento do inodo: millóns de ficheiros pequenos de 0 a 4 KB"]
DiagType -->|"Tanto df -h como df -i amosan < 90 % de uso"| RamOrQuota["Límite oculto: verifique df -h /tmp (tmpfs RAM chea), Docker Overlay2 ou XFS/ext4 Disk Quotas"]
BlockFull --> GhostCheck{"Xa executaches rm en ficheiros grandes sen soltar df?"}
GhostCheck -->|"Si: du é moito máis pequeno que df"| UnlinkedFD["Executar: sudo lsof +L1 -> Truncar Ghost File a través de: > /proc/PID/fd/FD"]
GhostCheck -->|"Non: os ficheiros reais están enchendo o disco"| EmergencySpace["Crear unha sala de respiración inmediata (de 1 GB a 5 GB)"]
EmergencySpace --> Ext4Check{"O sistema de ficheiros é ext4/ext3?"}
Ext4Check -->|"Si"| Tune2fs["Executar: sudo tune2fs -m 1 /dev/root_dev (libera instantáneamente o 4% do disco para usuarios de base de datos non root)"]
Ext4Check -->|"Non (XFS/Btrfs/ZFS)"| TruncLogs["Trunca os rexistros no lugar (: > /var/log/syslog) e executa journalctl --vacuum-size=50M"]
InodeFull --> InodeClean["Buscar directorio con millóns de ficheiros usando find / -xdev -printf '%h\n' | ordenar | uniq -c | ordenar -k 1 -r | cabeza -20 -> Eliminar con find -delete"]
UnlinkedFD --> DBRecover["Vaia a Database Engine WAL & B-Tree Recovery"]
Tune2fs --> DBRecover
TruncLogs --> DBRecover
InodeClean --> DBRecover
RamOrQuota --> DBRecover
DBRecover --> WhichDB{"Que motor de base de datos fallou?"}
WhichDB -->|"PostgreSQL"| PGFlow["Mantén pg_wal intacto -> Iniciar Postgres para reproducir WAL -> Executar CHECKPOINT; -> Eliminar ranuras de replicación obsoletas"]
WhichDB -->|"MySQL / MariaDB (InnoDB)"| MyFlow["Manter ib_logfile* intacto -> Iniciar mysqld -> Purgar rexistros binarios mediante PURGAR REGISTROS BINARIOS -> Optimizar táboas"]
WhichDB -->|"SQLite 3"| SqFlow["Facer unha copia de seguridade .db + .db-wal + .db-shm -> Executa PRAGMA wal_checkpoint (TRUNCATE) ou sqlite3 broken.db '.recover'"]
Fase 1: Por que os comandos estándar (rm, apt, tab-completion) falla en 0 bytes libres¶
Cando unha partición de Linux alcanza o 100 por cento de bloqueo ou esgotamento do inodo, os comandos de corrección estándar fallan de xeito inesperado:
- Presionando Tab en bash lanzamentos cannot create temp file for here-document: No space left on device: Moderno bash-completion scripts crean ficheiros temporais en /tmp. Se /tmp reside na raíz / partición en lugar de a tmpfs Montaxe de RAM, finalización de shell e heredocs (<<EOF) falla. Corrixa isto inmediatamente apuntando TMPDIR á memoria RAM compartida:
apt-get autoremove ou dpkg --configure -a falla con No space left on device: Cando /boot ou / está cheo ao 100%, apt non pode eliminar núcleos antigos porque dpkg primeiro debe escribir as actualizacións de estado /var/lib/dpkg/updates/. Pola contra, corre sudo apt-get clean (que desliga da caché .deb arquivos en /var/cache/apt/archives/ directamente), ou trunque unha imaxe do núcleo non utilizada /boot (sudo sh -c ': > /boot/initrd.img-<old-unused-version>') dar dpkg os 50 megabytes (52,4 millóns de bytes) que precisa para executarse sudo dpkg --purge linux-image-<old-unused-version>.
- rm /path/to/dir/* falla con Argument list too long: Cando df -i está ao 100 por cento porque un directorio como /var/lib/php/sessions contén millóns de ficheiros pequenos, comodíns globbing (*) desborda o núcleo ARG_MAX buffer (2 megabytes) antes rm comeza. Use find con -delete en cambio:
As 5 causas distintas de No space left on device (ENOSPC)¶
Antes de tocar calquera ficheiro de base de datos, compare estes cinco escenarios para confirmar que recurso está realmente esgotado:
| Comando de diagnóstico | Síntoma observado | Causa raíz | Corrección inmediata de 10 segundos |
|---|---|---|---|
df -h vs sudo du -shx / |
df -h mostra 100% usado (0 Avail), pero du -shx / suma só 60% do tamaño do disco. |
Abrir ficheiros sen ligar ("Ficheiros pantasma"): alguén correu rm nun enorme ficheiro de rexistro ou temporal durante un proceso (nginx, java, postgres, docker) aínda o tiña aberto. |
Corre sudo lsof +L1, localiza o PID e FD da (deleted) arquivo e executalo sudo sh -c ': > /proc/<PID>/fd/<FD>'. |
df -h espectáculos 95% usado, 0 Avail |
Used + Avail non é igual Size; root pode escribir ficheiros, pero postgres ou mysql recibe ENOSPC. |
ext4 Bloques raíz reservados (5 % predeterminado): ext4 Retén o 5 por cento dos bloques de usuarios non root (UID > 0) para evitar bloqueos de raíz e fragmentación. |
Corre sudo tune2fs -m 1 /dev/<partition> para baixar a reserva do 5 por cento ao 1 por cento inmediatamente en liña. |
df -i |
df -h mostra gigabytes de espazo libre, pero df -i mostra IUse% = 100% (IFree = 0). |
Egotamento do inodo: ext4 ten un número fixo de inodos creados en mkfs tempo; millóns de ficheiros pequenos consumiron cada ranura de inodo. |
Atopar o cartafol culpable (sudo find / -xdev -printf '%h\n' \ | ordenar \ | uniq -c \ | ordenar -k 1 -r \ | cabeza -10) and run sudo find /culprit/dir -type f -delete. |
sudo mount\ | grep /ruta |
du -sh /var/log é pequeno, aínda / ten 40 gigabytes de espazo perdido. |
Ficheiros ocultos baixo un punto de montaxe: un proceso escribiu 40 gigabytes /mnt/backup mentres que a unidade externa estaba desmontada, e máis tarde alguén montou un disco enriba de /mnt/backup, ocultando os ficheiros subxacentes du. |
Montar o sistema de ficheiros raíz nunha vista temporal (sudo mkdir /dev/shm/rootview && sudo mount --bind / /dev/shm/rootview), comprobar du -sh /dev/shm/rootview/mnt/*, e elimine os ficheiros ocultos. |
btrfs filesystem df / |
df -h mostra 20 gigabytes gratis en a Btrfs volume, pero as escrituras fallan ENOSPC. |
Btrfs Esgotamento de fragmentos de metadatos: Btrfs asigna espazo en anacos de datos e metadatos separados; se todo o espazo en bruto non asignado está bloqueado en fragmentos de datos escasos, os anacos de metadatos alcanzan o 100 por cento. |
Engade temporalmente un dispositivo de bucle de ficheiros RAM de 2 gigabytes (dd if=/dev/zero of=/dev/shm/btrfs_ram bs=1M count=2048 && sudo btrfs device add -f /dev/shm/btrfs_ram /), correr sudo btrfs balance start -dusage=10 /, entón sudo btrfs device remove /dev/shm/btrfs_ram /. |
Fase 2: recuperar espazo no disco de forma segura en menos de 60 segundos¶
Siga estes pasos exactos para recuperar entre 500 megabytes e 50 gigabytes (de 0.530 a 53.600 millóns de bytes) de espazo sen corromper os procesos activos:
Paso 1: trunque os ficheiros abertos eliminados ("pantasma") mediante /proc/<pid>/fd/¶
Se vostede ou un script de logrotate automatizado xa eliminou ficheiros grandes pero non se devolveu espazo no disco, comprobe a táboa de ficheiros abertos desvinculados do núcleo:
Mira oSIZE/OFF columna (medido en bytes). Se ves unha entrada como:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
mysqld 1942 mysql 6u REG 259,1 34896609280 0 918273 /tmp/ibXz91aB (deleted)
rsyslogd 612 syslog 7w REG 259,1 18253611008 0 131092 /var/log/syslog.1 (deleted)
rsyslogd (PID 612, descritor do ficheiro 7w -> 7) mantén aberto un ficheiro de rexistro eliminado de 18,2 gigabytes. Non kill -9 procesos de bases de datos (mysqld ou postgres) para liberar /tmp ficheiros se pode liberar espazo noutro lugar primeiro. Pola contra, pon a cero o descritor do ficheiro de rexistro (PID 612, FD 7) directamente na memoria do núcleo:
Corre df -h inmediatamente: todos os 18,2 gigabytes son liberados no lugar sen reiniciar un só servizo.
Paso 2: Recuperar ext4 bloques reservados en liña con tune2fs¶
En calquera ext4 ou ext3 sistema de ficheiros, verifique o número de bloques reservados actual:
postgres), MySQL (mysql), Redis (redis), e aplicacións web SQLite (www-data, node) executados como usuarios non root sen privilexios, o núcleo de Linux impide que usen o último 5 por cento do disco. Reducindo a proporción de bloques reservados de 5% a 1% (ou 0% durante unha emerxencia activa) ten efecto instantáneamente nun sistema de ficheiros montado en directo:
Nun volume de base de datos de 1 terabyte (1.000 gigabytes), este comando único envía inmediatamente 40 gigabytes (42.900 millóns de bytes) de espazo de escritura ao motor de base de datos para que poida rematar o seu punto de control WAL. Unha vez resolta a crise e purgando os datos antigos, restablece a reserva 2% ou 5% (sudo tune2fs -m 2 /dev/nvme0n1p1).
Paso 3: trunque os rexistros de texto activos no lugar e pase o baleiro journald¶
Atopar os ficheiros máis grandes no sistema de ficheiros raíz (permanecer no mesmo sistema de ficheiros con -xdev para que non perdas o tempo escaneando /proc ou montaxes externas):
/var/log/nginx/access.log, /var/log/syslog, /var/log/postgresql/*.log, Docker *-json.log):
Nunca corras rm nun ficheiro de rexistro activo. Trunqueo a cero bytes no seu lugar para que o descritor de ficheiros do daemon permaneza válido e os punteiros de compensación se reinicien limpamente:
sudo truncate -s 0 /var/log/nginx/error.log
sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
systemd-journald rexistros binarios (/var/log/journal/):
Fase 3: Recuperación de PostgreSQL despois dunha falla de disco cheo ao 100 % (pg_wal inchar)¶
Cando un servidor PostgreSQL queda sen espazo no disco, rexistra PANIC: could not write to file "pg_wal/xlogtemp.1234": No space left on device, aborta inmediatamente os procesos fillos do administrador de correos e négase a iniciar.
Por que pg_wal (pg_xlog en PostgreSQL 9.6 e anteriores) enche todo o disco¶
En funcionamento normal, PostgreSQL escribe cada cambio en ficheiros de segmento de 16 megabytes (16,7 millóns de bytes) dentro $PGDATA/pg_wal/ e recíclaos despois de cada un CHECKPOINT unha vez que se supere max_wal_size. Non obstante, PostgreSQL ** está prohibido eliminar ou reciclar vellos pg_wal ficheiros** baixo tres condicións:
1. Unha ranura de replicación física/lóxica retrasada ou orfa: un servidor de réplica (standby), conector Debezium/Kafka ou pg_receivewal cliente desconectouse hai días, pero o seu slot de replicación (pg_replication_slots) aínda está active = false no principal, instruíndo a PostgreSQL para conservar cada segmento de WAL xerado desde a desconexión.
2. Un fracaso archive_command: archive_mode = on está habilitado en postgresql.conf, e o script de copia de seguridade (pgBackRest, WAL-G, Barman, ou aws s3 cp) está devolvendo un código de saída distinto de cero (por exemplo, unha clave S3 caducada ou un host de copia de seguranza inalcanzable). PostgreSQL mantén todos os segmentos WAL sen arquivar pg_wal/ ata que archive_command volve 0.
3. Un punto morto de disco cheo: pg_wal medrou ata 0 bytes permaneceu encendido /var/lib/postgresql, e agora PostgreSQL non pode nin sequera comezar a soltar o slot de replicación ou completar un punto de verificación porque a propia recuperación do inicio precisa de varios megabytes de espazo libre en disco para escribir ficheiros de estado temporais.
Rescate de espazo cero de PostgreSQL paso a paso (perda cero de datos)¶
- Cree de 1 gigabyte a 5 gigabytes (de 1,07 a 5,36 millóns de bytes) de espazo temporal fóra
pg_wal/: - Primeiro uso
sudo tune2fs -m 0 /dev/<partition>e truncar os rexistros de texto do sistema/PostgreSQL (sudo truncate -s 0 /var/lib/postgresql/*/main/log/*.logou/var/log/postgresql/*.log). - ** E se a base de datos ten a súa propia partición dedicada con cero rexistros de texto e XFS (así
tune2fsnon está dispoñible)?** Move 10 a 20 dos máis antigos.readyou ficheiros inactivos fóra dun directorio que non sexa WAL, ou reubicar opg_waldirectorio temporalmente a outra partición con espazo libre mediante unha ligazón simbólica:# ONLY while PostgreSQL is completely stopped (verify with: ps aux | grep postgres) sudo mkdir -p /mnt/extra_space/pg_wal_rescue sudo chown -R postgres:postgres /mnt/extra_space/pg_wal_rescue sudo mv /var/lib/postgresql/16/main/pg_wal/* /mnt/extra_space/pg_wal_rescue/ sudo rmdir /var/lib/postgresql/16/main/pg_wal sudo ln -s /mnt/extra_space/pg_wal_rescue /var/lib/postgresql/16/main/pg_wal sudo chown -h postgres:postgres /var/lib/postgresql/16/main/pg_wal - Se
archive_commandestá fallando e bloqueando a reciclaxe de WAL, evítalo temporalmentepostgresql.conf: Se o teu obxectivo S3/backup está caído epg_wal/archive_status/contén miles de.readyarquivos, editarpostgresql.conf(archive_command = '/bin/true') só como medida de emerxencia de último recurso para evitar que o disco morra, sabendo que debes tomar un novopg_basebackupinmediatamente despois da recuperación porque a cadea de arquivos WAL terá un oco. - Inicie PostgreSQL e inspeccione inmediatamente os slots de replicación:
Iniciar PostgreSQL (
sudo systemctl start postgresql) e conéctese mediantesudo -u postgres psql: - Solta calquera ranura de replicación morta/inactiva que acumule gigabytes de WAL:
Se ves un slot inactivo (
active = f) con 80 gigabytes deretained_wal: - Forzar un inmediato
CHECKPOINTpara reciclar o inchadopg_walsegmentos: O momentoCHECKPOINT;remate despois de soltar o slot morto, PostgreSQL desligará ou reciclará automaticamente gigabytes de ficheiros antigos de segmentos de 16 megabytes enpg_wal/, devolvendo o uso do disco á normalidade. - Evitar a morte do disco de slot de replicación futura: Definido
max_slot_wal_keep_sizeenpostgresql.conf(dispoñible en PostgreSQL 13+) a un límite seguro (comomax_slot_wal_keep_size = 20GB) polo que PostgreSQL invalida a ranura dunha réplica morta en lugar de bloquear a base de datos primaria a 0 bytes libres.
Fase 4: Recuperación de MySQL / MariaDB (InnoDB) a 0 bytes libres¶
Cando MySQL ou MariaDB chegan 100% utilización do disco (/var/lib/mysql), InnoDB bloquea todas as escrituras ou falla [ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'.
Identificando o que encheu /var/lib/mysql¶
Corre sudo du -sh /var/lib/mysql/* | sort -hr | head -n 15 para ver cal destes catro culpables consumiu o disco:
1. ** Rexistros binarios ilimitados (binlog.000001, mysql-bin.000042): Por defecto en MySQL 8.0+, o rexistro binario está habilitado cunha retención de 30 días (binlog_expire_logs_seconds = 2592000), que pode xerar facilmente centos de gigabytes de eventos de fila durante as importacións masivas.
2. Unha consulta desbocada escribindo táboas temporais xigantes (#sql* ou ibtmp1): Un enorme GROUP BY ou ORDER BY consulta cuberta ibtmp1 ou /tmp/#sql_* ata que o disco toque 0 bytes.
3. Monolítico ibdata1 sistema tablespace bloat: Se innodb_file_per_table foi desactivado ou as transaccións de longa duración impediron a lista de historial de InnoDB (desfacer rexistros dentro ibdata1 ou undo_001) de purga.
4. ** Rexistro de consultas lentas ou rexistro de erros de MySQL (/var/log/mysql/mysql-slow.log).
Rescate de espazo cero de MySQL/MariaDB paso a paso¶
- ** NUNCA borres
ibdata1,ib_logfile0,ib_logfile1,#innodb_redo/*, ouundo_001conrm**: Eliminar calquera destes ficheiros fai que todos.ibdficheiro de táboa na súa base de datos non lexible. - Espazo de inicio gratuíto (de 500 megabytes a 2 gigabytes):
- Truncar
/var/log/mysql/error.logemysql-slow.logvíasudo truncate -s 0 /var/log/mysql/*.log. - Activado
ext4, corresudo tune2fs -m 1 /dev/<partition>. - Se
mysqldactualmente está detido e/var/lib/mysql/ibtmp1(o espazo de táboa temporal non comprimido) é enorme,ibtmp1recréase automaticamente ao iniciar, ou pode mover os **dos ou tres rexistros binarios máis antigos (binlog.000001,binlog.000002- nunca o binlog activo con maior número) a/dev/shmtemporalmente asímysqldpode arrincar. - Iniciar MySQL e purgar os rexistros binarios de forma segura usando SQL (
PURGE BINARY LOGS): Por que debes usar SQL en lugar derm /var/lib/mysql/binlog.*? Porque MySQL rastrexa cada nome de ficheiro de rexistro binariobinlog.index. Se eliminas rexistros binarios conrmsen actualizarbinlog.index, MySQL rexeitará iniciarse ou a replicación romperase. Unha vezmysqldcomeza, inicia sesión (sudo mysql) e executa: (Ou purga todo ata o ficheiro de rexistro activo actual que se mostra na parte inferior deSHOW BINARY LOGS;usandoPURGE BINARY LOGS TO 'binlog.000085';) - Establece un tamaño de rexistro binario permanente e un límite de retención
/etc/mysql/mysql.conf.d/mysqld.cnf:Tapón[mysqld] binlog_expire_logs_seconds = 259200 # Keep only 3 days (259,200 seconds) max_binlog_size = 256M innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:5Gibtmp1ásmax:5Ggarante que un pícaro non indexadoJOINouORDER BYa consulta falla con atable is fullerro en lugar de expandiribtmp1ata que todo o servidor Linux morra con 0 bytes libres.
Fase 5: Recuperación dunha base de datos SQLite3 corrupta (database or disk is full / SQLITE_FULL / malformed)¶
Aplicacións integradas, contedores Docker (Nextcloud, Vaultwarden, Home Assistant, Plex, Grafana, Gitea), e os servizos móbiles/de escritorio dependen de SQLite3. Cando un disco alcanza 0 bytes libres mentres SQLite está no medio dunha reversión de diario ou un rexistro de escritura anticipada (-wal), atopará unha das dúas emerxencias:
1. Masivo .db-wal arquivo inchazo (o .db-wal o ficheiro pasou a 10 gigabytes mentres que o .db o ficheiro ten só 200 megabytes, porque os lectores de longa duración impediron un punto de control WAL pasivo e agora o disco está cheo ao 100 por cento).
2. RuntimeError: database disk image is malformed (SQLITE_CORRUPT) causado por un hardware averiado fsync(), un contenedor matou a metade da recuperación a 0 bytes libres ou alguén que eliminou o -wal ou -journal arquivo a man.
Warning
Nunca mover, renomear ou copiar un .db arquivo por si mesmo mentres deixa o seu .db-wal (Registro de escritura anticipada) ou .db-journal (Rollback Journal) arquivo detrás: Se app.db-wal ou app.db-journal existe ao lado app.db, ese ficheiro acompañante contén transaccións comprometidas e páxinas orixinais de árbore B que se deben realizar app.db estruturalmente consistente. Copia sempre os tres ficheiros (app.db, app.db-wal, app.db-shm) xuntos antes de executar calquera comando.
Paso 1: encoller un inchado .db-wal ficheiro e aspirar SQLite cando o espazo no disco está preto de cero¶
- Detén o contedor da aplicación ou o servizo que mantén aberta a base de datos SQLite (
sudo systemctl stop appoudocker stop container_name). - Copiar
app.db,app.db-wal, eapp.db-shma unha partición ou unidade externa con moito espazo libre (ou libre 2 veces o tamaño deapp.dbprimeiro no disco local). - Abre a base de datos co
sqlite3CLI e forza un punto de verificación WAL truncado, que dobra todos os fotogramas comprometidos desdeapp.db-walenapp.dbe encolleapp.db-walata 0 bytes: - Verifique a integridade estrutural da árbore B e da lista libre:
Se imprime
ok, a súa base de datos é 100 por cento saudable. - Como
VACUUMunha enorme base de datos SQLite cando o disco local non ten espazo libre suficiente: EstándarVACUUM;require ata 2 veces o tamaño da base de datos en espazo libre no disco na mesma partición e/var/tmp. En cambio, usaVACUUM INTO(introducido en SQLite 3.27.0) para escribir unha copia recén compactada e desfragmentada directamente nun disco montado separado ou nun recurso compartido de rede:
Paso 2: salvar unha árbore B danada (database disk image is malformed) con .recover¶
Se PRAGMA integrity_check; informes row 412 missing from index, btreeInitPage() returns error code 11, ou database disk image is malformed:
- Primeiro intente reconstruír índices secundarios rotos (
REINDEX): Moitas veces os datos da táboa reais (table B-trees) está 100 por cento intacta e só se corrompiu unha árbore de índice secundario B cando o disco se encheu. Executar:Sesqlite3 /mnt/external_usb/copy_of_app.db "REINDEX;" sqlite3 /mnt/external_usb/copy_of_app.db "PRAGMA integrity_check;"PRAGMA integrity_check;agora volveok, recuperaches o 100 por cento da túa base de datos sen filas perdidas. - Se
REINDEXfalla, executa o escáner forense B-tree (.recover): A diferenza dos maiores.dumpcomando (que deixa de exportar unha táboa no momento en que chega a un punteiro da árbore B danado),.recover(integrado ensqlite3versión 3.29.0+) evita por completo os punteiros da árbore B interior corrompidos, escanea cada páxina de folla de 4 kilobytes do ficheiro de forma secuencial desde o byte 0 ata o EOF, reconstrúe todas as filas lexibles e coloca os rexistros orfos nun ficheiro.lost_and_foundtáboa: - Verifique a base de datos recén reconstruída:
Comproba se a
lost_and_foundcreouse a táboa (sqlite3 /mnt/external_usb/repaired_app.db ".tables") para inspeccionar as filas orfas recuperadas das páxinas de follas sen ligazón. Para bases de datos SQLCipher cifradas (como copias de seguridade de Signal ou WhatsApp), consulte a nosa guía dedicada en corrupción de copia de seguridade do chat cifrado de SQLite, Signal e WhatsApp e extracción de claves locais.
Fase 6: "Arquivo de lastre de tripwire" de emerxencia e lista de verificación de prevención de seguimento¶
Unha vez que o servidor e a base de datos estean en liña de novo, implemente estas catro garantías de inmediato para que nunca volva quedar atrapado en 0 bytes libres:
- Crear un gigabyte (
1,073,741,824byte) Ficheiro de lastre de emerxencia en cada partición da base de datos: Executarsudo fallocate -l 1G /var/lib/EMERGENCY_DELETE_ME.ballast. Se algunha vez chega o servidor100%disco cheo, en execuciónsudo rm /var/lib/EMERGENCY_DELETE_ME.ballastlibera 1 gigabyte de bloques contiguos en 1 milisegundo. - Cap
systemd-journalde rexistros do contedor Docker de forma permanente: EstablecidoSystemMaxUse=200Men/etc/systemd/journald.confe configurar/etc/docker/daemon.jsoncon"log-opts": {"max-size": "20m", "max-file": "3"}. - ** Illar
/var/log,/tmp, e/var/lib/postgresqlen volumes LVM separados**: Conservación/var/loge/tmpseparado dos volumes da base de datos garante que un rexistro web descontrolado nunca faga falla a base de datos nin bloquee os inicios de sesión SSH. - Alerta en AMBOS
df -h(> 80%) Edf -i(> 80%) máispg_replication_slotslag: configurar a monitorización (node_filesystem_avail_bytesenode_filesystem_files_free) para alertar antes de que a utilización supere o 85 por cento.
Números de emerxencia rexionais e protocolos da axencia¶
Aínda que un disco de servidor completo é normalmente unha emerxencia interna das operacións de TI, unha interrupción que afecta ao rexistro sanitario electrónico (EHR) bases de datos, envío de emerxencia (CAD), a telemetría municipal de auga/electricidade ou a dispoñibilidade legal de datos persoais poden requirir unha escalada formal de emerxencia:
- Estados Unidos e Canadá: Marque
911se un fallo do servidor desactiva o seguimento clínico ou o envío e activa os procedementos de tempo de inactividade. Informar de esgotamento de recursos de infraestrutura crítica ou ataques de ransomware a CISA (1-844-Say-CISA/cisa.gov/report) ou o Centro Canadiense de Seguridade Cibernética (1-833-CYBER-88). - Reino Unido: Marque
999para ameazas para a vida ou sistemas críticos do NHS. Segundo os regulamentos do GDPR e NIS do Reino Unido, avalía se a perda permanente de dispoñibilidade da base de datos require unha notificación ao ICO (0303 123 1113) nun prazo de 72 horas. - Unión Europea: Marque
112en todos os estados membros da UE. As entidades esenciais baixo a Directiva NIS2 deben notificar ao seu CSIRT nacional nun prazo de 24 horas despois dunha interrupción importante, e a perda permanente de datos persoais sen recuperación de copia de seguranza activa os informes do artigo 33 do GDPR nun prazo de 72 horas. - Australia e Nova Zelanda: Marque
000en Australia ou111en Nova Zelanda; póñase en contacto co ACSC (1300 CYBER1) para incidencias de infraestruturas. - India e Asia-Pacífico: Marque
112para resposta de emerxencia; informar cortes inducidos por cibernética a CERT-In (incident@cert-in.org.in) dentro da xanela obrigatoria de 6 horas.
Preguntas frecuentes¶
Por que fixo df -h permanecer ao 100% (0 Avail) mesmo despois de eliminar un ficheiro de rexistro de 50 GB con rm?¶
En sistemas de ficheiros Linux, rm só chamadas desvincular(), eliminando o nome do ficheiro do directorio mentres o núcleo mantén os bloques de disco asignados ata que cada proceso que mantén ese ficheiro aberto pecha o seu descritor de ficheiro (i_count == 0). Corre sudo lsof +L1 para atopar o ID do proceso (PID) e Descriptor de ficheiro (FD) do (eliminado) ficheiro e, a continuación, execute sudo sh -c ': > /proc/PID/fd/FD' para cero os bloques no lugar inmediatamente sen reiniciar o servizo.
E se non podo nin SSH no servidor porque /tmp ou /var/run está cheo ao 100% e sshd négase a asignar unha sesión?¶
Primeiro intente executar un comando directo non PTY sobre SSH sen asignar un pseudoterminal interactivo: ssh -T root@server "sh -c ': > /var/log/syslog'". Se raíz o inicio de sesión está desactivado, use a consola serie fóra de banda do seu provedor de nube (AWS EC2 Serial Console, DigitalOcean Console, Linode Lish ou Proxmox/VMware VNC) para iniciar sesión directamente en ttyS0 ou arrincar en modo de recuperación de usuario único.
Alguén xa eliminou ficheiros dentro de PostgreSQL pg_wal directorio antes de ler esta guía, e agora PostgreSQL négase a comezar PANIC: could not locate a valid checkpoint record. Perdéronse todos os datos?¶
Non, a maioría das filas da táboa aínda están dentro $PGDATA/base/, aínda que as transaccións durante o voo dentro dos ficheiros WAL eliminados pérdense e algunhas páxinas poden romperse. Primeiro fai unha copia completa do conxunto $PGDATA directorio (cp -a /var/lib/postgresql/16/main /mnt/backup/pgdata_raw). Despois corre sudo -u postgres /usr/lib/postgresql/16/bin/pg_resetwal -f /var/lib/postgresql/16/main, inicie PostgreSQL en modo de usuario único e execute inmediatamente pg_dumpall nun recén inicializado (initdb) cluster; nunca continúe executando o tráfico de produción nun clúster despois pg_resetwal.
Como borrar millóns de ficheiros pequenos cando rm -rf colga ou falla nun inodo esgotado (df -i 100%) servidor?¶
Cando un directorio contén millóns de pequenos ficheiros de sesión ou caché, o seu índice de directorio (htree) crece enorme, provocando ls e rm - rf para bloquear a clasificación de nomes de ficheiros na RAM. Pola contra, corre sudo find /path/to/million_files -mindepth 1 -eliminarou crear un directorio de RAM baleiro (mkdir /dev/shm/empty) e corre sudo rsync -a --delete /dev/shm/empty/ /path/to/million_files/ para desvincular os inodos rapidamente.
Por que Docker encheu todo o meu disco do servidor cando os meus contedores son pequenos e como limpo? /var/lib/docker con seguridade?¶
Docker acumula espazo en disco nos rexistros estándar JSON non rotados (/var/lib/docker/containers/*/*-json.log), colgando superposición 2 capas de imaxes e caché de kit de compilación. Nunca manualmente rm - rf carpetas dentro /var/lib/docker/overlay2/. Primeiro trunque os rexistros JSON (sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log) para que o demo teña espazo para respirar, entón corre sistema sudo docker prune -a -f (omitindo --volumes polo que os volumes da base de datos permanecen intactos).
Podo expandir un volume de disco persistente/EBS na nube en directo mentres o servidor está a utilizar o 100 % do disco?¶
Si, a expansión de volume en liña funciona sen reiniciar, cunha única captura: o script auxiliar growpart /dev/nvme0n1 1 tenta crear un ficheiro temporal en /tmp usando mktemp e falla en 0 bytes libres. Evita ese fallo executando sudo TMPDIR=/dev/shm growpart /dev/nvme0n1 1 (usando a memoria RAM /dev/shm monte) seguido de sudo resize2fs /dev/nvme0n1p1 (ext4) ou sudo xfs_growfs / (XFS).
Guías relacionadas¶
rm -rfouShift+Deleteaccidental en Linux, macOS ou Windows: remontada inmediata de só lectura- Corrupción da copia de seguranza do chat cifrado de SQLite, Signal e WhatsApp e extracción de claves locais
- Ficheiro corrupto de Word, Excel, PDF e base de datos e recuperación de documentos sen gardar
- Modo de só lectura súbita SSD e NVMe, 0 % de bloques de reserva e o rescate desactivando TRIM
- Crise de hospedaxe web, migración e restauración de copias de seguridade
- Números de emerxencia por país
Fontes e orientacións oficiais¶
- Grupo de desenvolvemento global de PostgreSQL: Documentación oficial de PostgreSQL 16 - Capítulo 30: Fiabilidade e rexistro de escritura anticipada (Configuración de WAL, slots de replicación e recuperación de fallos completos do disco).
- Consorcio SQLite (
sqlite.org): Como corromper un ficheiro de base de datos SQLite (bloqueo de ficheiros, ficheiros diarios/WAL sen ligar e.recoverExtensión CLI). - Documentación de Oracle Corporation / MySQL e MariaDB Foundation: Recuperación de fallos de InnoDB, Procedementos de purga de rexistros binarios (
PURGE BINARY LOGS) e espazo de táboa temporal (ibtmp1) Xestión. - Organización do núcleo de Linux (
kernel.org): Administración do sistema de ficheiros Ext4 (tune2fsBloques reservados, táboas de inodos e/proc/<pid>/fd/Truncamento do descritor de ficheiros). - Instituto Nacional de Estándares e Tecnoloxía (
NIST) (Estados Unidos): Publicación especial 800-123: Guide to General Server Security and Availability Management.