28.1. Confiabilidad #

La confiabilidad es una propiedad importante de cualquier sistema de base de datos serio, y PostgreSQL hace todo lo posible para garantizar un funcionamiento confiable. Un aspecto del funcionamiento confiable es que todos los datos registrados por una transacción comprometida deben almacenarse en un área no volátil que esté a salvo de pérdidas de energía, fallos del sistema operativo y fallos de hardware (excepto el fallo de la propia área no volátil, por supuesto). El escribir con éxito los datos en el almacenamiento permanente de la computadora (unidad de disco o equivalente) normalmente cumple con este requisito. De hecho, incluso si una computadora resulta gravemente dañada, si las unidades de disco sobreviven, se pueden mover a otra computadora con hardware similar y todas las transacciones comprometidas permanecerán intactas.

Aunque forzar los datos a los platos del disco periódicamente pueda parecer una operación simple, no lo es. Debido a que las unidades de disco son dramáticamente lentas que la memoria principal y las CPU, existen varias capas de almacenamiento en caché entre la memoria principal de la computadora y los platos del disco. Primero, está el buffer cache del sistema operativo, que almacena en caché los bloques de disco solicitados con frecuencia y combina las escrituras de disco. Afortunadamente, todos los sistemas operativos brindan a las aplicaciones una forma de forzar las escrituras desde el buffer cache al disco, y PostgreSQL utiliza esas características. (Consulta el parámetro wal_sync_method para ajustar cómo se hace esto).

A continuación, podría haber una caché en el controlador de la unidad de disco; esto es particularmente común en las tarjetas controladoras RAID. Algunas de estas cachés son write-through (de escritura inmediata), lo que significa que las escrituras se envían a la unidad tan pronto como llegan. Otras son write-back (de escritura diferida), lo que significa que los datos se envían a la unidad en algún momento posterior. Estas cachés pueden ser un peligro para la confiabilidad porque la memoria en la caché del controlador de disco es volátil y perderá su contenido en caso de un fallo de energía. Las mejores tarjetas controladoras tienen unidades de batería de respaldo (BBUs), lo que significa que la tarjeta tiene una batería que mantiene la energía en la caché en caso de pérdida de energía del sistema. Una vez que se restablece la energía, los datos se escribirán en las unidades de disco.

And finalmente, la mayoría de las unidades de disco tienen cachés. Algunas son write-through mientras que otras son write-back, y existen las mismas preocupaciones sobre la pérdida de datos para las cachés de unidades write-back que para las cachés de controladores de disco. Las unidades IDE y SATA de grado de consumo son particularmente propensas a tener cachés write-back que no sobrevivirán a un fallo de energía. Muchas unidades de estado sólido (SSD) también tienen cachés write-back volátiles.

Estas cachés normalmente se pueden desactivar; sin embargo, el método para hacerlo varía según el sistema operativo y el tipo de unidad:

Las unidades SATA recientes (aquellas que siguen ATAPI-6 o posterior) ofrecen un comando de vaciado de caché de la unidad (FLUSH CACHE EXT), mientras que las unidades SCSI admiten desde hace mucho tiempo un comando similar SYNCHRONIZE CACHE. Estos comandos no son directamente accesibles para PostgreSQL, pero algunos sistemas de archivos (por ejemplo, ZFS, ext4) pueden utilizarlos para vaciar los datos a los platos en unidades con write-back habilitado. Desafortunadamente, tales sistemas de archivos se comportan de manera subóptima cuando se combinan con controladores de disco con unidad de batería de respaldo (BBU). En tales configuraciones, el comando de sincronización fuerza todos los datos desde la caché del controlador a los discos, eliminando gran parte del beneficio de la BBU. Puedes ejecutar el programa pg_test_fsync para ver si estás afectado. Si lo estás, los beneficios de rendimiento de la BBU se pueden recuperar desactivando las barreras de escritura (write barriers) en el sistema de archivos o reconfigurando el controlador de disco, si esa es una opción. Si se desactivan las barreras de escritura, asegúrate de que la batería siga funcionando; una batería defectuosa puede provocar una pérdida de datos. Con suerte, los diseñadores de sistemas de archivos y controladores de disco eventualmente abordarán este comportamiento subóptimo.

Cuando el sistema operativo envía una solicitud de escritura al hardware de almacenamiento, es poco lo que puede hacer para asegurarse de que los datos hayan llegado a un área de almacenamiento verdaderamente no volátil. Más bien, es responsabilidad del administrador asegurarse de que todos los componentes de almacenamiento garanticen la integridad tanto de los datos como de los metadatos del sistema de archivos. Evita los controladores de disco que tengan cachés de escritura sin batería de respaldo. A nivel de unidad, desactiva la caché write-back si la unidad no puede garantizar que los datos se escribirán antes del apagado. Si utilizas unidades SSD, ten en cuenta que muchas de ellas no respetan los comandos de vaciado de caché por defecto. Puedes probar el comportamiento confiable del subsistema de E/S utilizando diskchecker.pl.

Otro riesgo de pérdida de datos lo plantean las propias operaciones de escritura en los platos del disco. Los platos del disco se dividen en sectores, comúnmente de 512 bytes cada uno. Cada operación física de lectura o escritura procesa un sector completo. Cuando llega una solicitud de escritura a la unidad, puede ser por algún múltiplo de 512 bytes (PostgreSQL normalmente escribe 8192 bytes, o 16 sectores, a la vez), y el proceso de escritura podría fallar debido a una pérdida de energía en cualquier momento, lo que significa que algunos de los sectores de 512 bytes se escribieron mientras que otros no. Para protegerse contra tales fallos, PostgreSQL escribe periódicamente imágenes de página completa en el almacenamiento permanente de WAL antes de modificar la página real en el disco. Al hacer esto, durante la recuperación de un fallo, PostgreSQL puede restaurar las páginas parcialmente escritas desde el WAL. Si tienes un software de sistema de archivos que evita las escrituras parciales de páginas (por ejemplo, ZFS), puedes desactivar esta generación de imágenes de página desactivando el parámetro full_page_writes. Los controladores de disco con unidad de batería de respaldo (BBU) no evitan las escrituras parciales de páginas a menos que garanticen que los datos se escriban en la BBU como páginas completas (de 8 kB).

PostgreSQL también protege contra algunos tipos de corrupción de datos en dispositivos de almacenamiento que pueden ocurrir debido a errores de hardware o fallos del medio con el paso del tiempo, como la lectura/escritura de datos basura.

PostgreSQL no protege contra errores de memoria corregibles y se asume que operarás utilizando memoria RAM que use Códigos de Corrección de Errores (ECC) estándar de la industria o una protección mejor.