Hola a todos. En esta ocasión hablaremos sobre PostgreSQL, vamos a ver cómo debemos proceder si hemos sufrido el llenado del directorio pg_wal y nos hemos quedado sin espacio en disco.
Write Ahead Logs (WAL)
Los registros de transacciones son un componente fundamental en la gestión de bases de datos relacionales. En PostgreSQL los conocemos como Write Ahead Logs (WAL) y por defecto se almacenan en la carpeta pg_wal del directorio de datos.
Cuando PostgreSQL escribe la información de las transacciones en estos registros (es lo primero que hace antes de que pueda ocurrir cualquier otra cosa) puede que devuelva el control al usuario antes de persistir los cambios de datos de esta transacción en el disco, por tanto, son necesarios tanto para mantener la integridad de la información como para poder restaurar la base de datos en caso de fallo.
Es por esto que PostgreSQL debe tener acceso a ellos en todo momento, así, si en algún momento no pudiera acceder a estos registros, como por ejemplo si el directorio se llenara y no pudieran crear nuevos archivos, la única opción que tiene es cerrarse a sí mismo, no permitiendo volver a abrir la base de datos y esperar hasta que un DBA solucione la causa del problema.
Solución del llenado del directorio pg_wal
Cuando la base de datos no se inicie porque le disco en el que se almacenan los WAL está lleno podremos ver en el log un error similar a este:
PANIC: could not write to file "pg_wal/waltemp.861": No space left on device
LOG: server process (PID 861) was terminated by signal 6: Aborted
LOG: terminating any other active server processes
LOG: archiver process (PID 861) exited with exit code 1
LOG: connection received: host=[local]
FATAL: the database system is in recovery mode
Para solucionarlo habrá que comprobar primero que el archivado funciona correctamente. Revisaremos que este configurado correctamente y el que el directorio tenga todos los permisos necesarios.
Estableceremos method=reject en el archivo pg_hba.conf para evitar conexiones a la base de datos mientras esté en matenimiento.
Entonces, tendremos dos opciones:
- Añadir más espacio a la partición donde se encuentra pg_wal, siempre que esto este permitido en el sistema operativo y el sistema de archivos.
- Mover el directorio a otra partición con más espacio:
- Si es posible y contamos con espacio en otro disco, hacer una copia de seguridad del directorio.
mv pg_wal /home/postgre/pg_wal_bkp
- Copiar los registros WAL a la nueva ubicación.
cp -rf /database/testDB/pg_wal/* /home/transaction/testDB/newPGWALdir/
- Crear un enlace simbólico desde pg_wal a la nueva ubicación.
ln -s /home/transaction/testDB/newPGWALdir/ pg_wal
- Iniciar PostgreSQL y comprobar que se generan nuevos registros WAL correctamente en la nueva ubicación.
No hay que olvidar devolver al archivo pg_hba.conf la configuración correcta para poder volver a permitir las conexiones.

Otras opciones para solucionarlo
Si las opciones anteriores no fueran viables, todavía tendríamos otra opción:
Hay que encontrar el registro WAL en el que se está escribiendo actualmente, pero no podemos usar comandos de la base de datos ya que no está accesible. Deberemos usar el siguiente comando:
pg_controldata -D /database/testDB
Lo que nos dará el siguiente resultado:
Database system identifier: 6841654614416864114
Database cluster state: in production
pg_control last modified: Fri 9 Feb 2024 14:51:45 AEST
Latest checkpoint location: 0/F681ACC4
Prior checkpoint location: 0/F6816084
Latest checkpoint's REDO location: 0/F681ACC4
Latest checkpoint's REDO WAL file: 000000010000000F00000081
Conociendo el archivo WAL del último punto de control (000000010000000F00000081) podremos borrar todos los anteriores con los siguientes comandos (ejecutaremos con la opción -n en primer lugar para hacerlo de forma más segura):
pg_archivecleanup -n /home/transaction/inst5/transactionlog 000000010000000F00000081
pg_archivecleanup -d /home/transaction/inst5/transactionlog 000000010000000F00000081
Una vez que este borrado, podremos iniciar la base de datos y comprobar que pg_wal recupera espacio.
Hay que tener en cuenta que con esta solución deberíamos hacer una nueva copia de seguridad del clúster.
Esperamos que os haya resultado interesante y os pueda servir de ayuda. Sobre todo, una buena práctica sería evitar con acciones preventivas que este llenado llegue a suceder.
No dudéis en poneros en contacto con nosotros si necesitáis ayuda con la gestión de vuestras bases de datos.
Échale un vistazo a nuestros servicios de soporte y mantenimiento PostgreSQL.
¿Aún no conoces Query Performance? Descubre cómo puede ayudarte en tu entorno Oracle. Más información en su página de LinkedIn.
Sígue a GPS en LinkedIn
