28.6. Detalles internos del WAL #

El WAL se habilita automáticamente; no se requiere ninguna acción por parte del administrador, excepto asegurarse de que se cumplan los requisitos de espacio en disco para los archivos WAL y que se realice cualquier ajuste necesario (consulta Section 28.5).

Los registros WAL se añaden a los archivos WAL a medida que se escribe cada nuevo registro. La posición de inserción se describe mediante un Número de Secuencia de Registro o Log Sequence Number (LSN) que es un desplazamiento de bytes en el WAL, que aumenta monótonamente con cada nuevo registro. Los valores de LSN se devuelven como el tipo de datos pg_lsn. Los valores se pueden comparar para calcular el volumen de datos de WAL que los separa, por lo que se utilizan para medir el progreso de la replicación y la recuperación.

Los archivos WAL se almacenan en el directorio pg_wal bajo el directorio de datos, como un conjunto de archivos de segmento, normalmente cada uno de 16 MB de tamaño (pero el tamaño se puede cambiar alterando la opción --wal-segsize de initdb). Cada segmento se divide en páginas, normalmente de 8 kB cada una (este tamaño se puede cambiar mediante la opción de configuración --with-wal-blocksize). Las cabeceras de los registros WAL se describen en access/xlogrecord.h; el contenido del registro depende del tipo de evento que se esté registrando. A los archivos de segmento se les asignan números siempre crecientes como nombres, comenzando en 000000010000000000000001. Los números no se reinician, pero tomará muchísimo tiempo agotar el conjunto disponible de números.

Es ventajoso que el WAL esté ubicado en un disco diferente al de los archivos principales de la base de datos. Esto se puede lograr moviendo el directorio pg_wal a otra ubicación (mientras el servidor está apagado, por supuesto) y creando un enlace simbólico desde la ubicación original en el directorio principal de datos a la nueva ubicación.

El objetivo de WAL es asegurar que el registro se escriba antes de que se alteren los registros de la base de datos, pero esto puede ser subvertido por unidades de disco que informan falsamente de una escritura exitosa al kernel, cuando en realidad sólo han almacenado los datos en caché y aún no los han guardado en el disco. Un fallo de energía en tal situación podría conducir a una corrupción de datos irrecuperable. Los administradores deben intentar asegurarse de que los discos que contienen los archivos WAL de PostgreSQL no realicen tales informes falsos. (Consulta Section 28.1).

Una vez que se ha realizado un punto de control y se ha vaciado el WAL, la posición del punto de control se guarda en el archivo pg_control. Por lo tanto, al inicio de la recuperación, el servidor lee primero pg_control y luego el registro de punto de control; luego realiza la operación REDO escaneando hacia adelante desde la ubicación del WAL indicada en el registro de punto de control. Debido a que todo el contenido de las páginas de datos se guarda en el WAL en la primera modificación de página después de un punto de control (asumiendo que full_page_writes no está deshabilitado), todas las páginas modificadas desde el punto de control se restaurarán a un estado coherente.

Para hacer frente al caso en el que pg_control se corrompa, deberíamos admitir la posibilidad de escanear los segmentos de WAL existentes en orden inverso — del más nuevo al más antiguo — para encontrar el último punto de control. Esto aún no se ha implementado. pg_control es lo suficientemente pequeño (menos de una página de disco) como para no estar sujeto a problemas de escritura parcial, y al momento de escribir esto no ha habido informes de fallos de la base de datos debidos únicamente a la incapacidad de leer el propio pg_control. De modo que, aunque teóricamente es un punto débil, pg_control no parece ser un problema en la práctica.