La confirmación asíncrona (asynchronous commit) es una opción que permite que las transacciones se completen más rápidamente, a costa de que las transacciones más recientes se puedan perder si la base de datos falla. En muchas aplicaciones, esta es una compensación aceptable.
Como se describió en la sección anterior, la confirmación de la transacción es normalmente síncrona: el servidor espera a que los registros WAL de la transacción se vacíen en el almacenamiento permanente antes de devolver una indicación de éxito al cliente. Por lo tanto, se garantiza al cliente que una transacción informada como confirmada se conservará, incluso en caso de que el servidor falle inmediatamente después. Sin embargo, para transacciones cortas, este retraso es un componente principal del tiempo total de la transacción. Seleccionar el modo de confirmación asíncrona significa que el servidor devuelve el éxito tan pronto como la transacción se completa lógicamente, antes de que los registros WAL que generó se hayan guardado realmente en el disco. Esto puede proporcionar un impulso significativo en el rendimiento de las transacciones pequeñas.
La confirmación asíncrona introduce el riesgo de pérdida de datos. Existe una pequeña ventana de tiempo entre el informe de finalización de la transacción al cliente y el momento en que la transacción se confirma verdaderamente (es decir, se garantiza que no se perderá si el servidor falla). Por lo tanto, la confirmación asíncrona no debe utilizarse si el cliente va a tomar medidas externas basadas en la suposición de que la transacción se recordará. Como ejemplo, un banco ciertamente no usaría la confirmación asíncrona para una transacción que registra la entrega de efectivo de un cajero automático. Pero en muchos escenarios, como el registro de eventos, no hay necesidad de una garantía sólida de este tipo.
El riesgo que se asume al utilizar la confirmación asíncrona es la pérdida de datos, no la corrupción de datos. Si la base de datos falla, se recuperará reproduciendo el WAL hasta el último registro que se vació. Por lo tanto, la base de datos se restaurará a un estado autoconsistente, pero las transacciones que aún no se hayan vaciado al disco no se reflejarán en ese estado. El efecto neto es, por lo tanto, la pérdida de las últimas transacciones. Debido a que las transacciones se reproducen en el orden de confirmación, no se puede introducir ninguna inconsistencia; por ejemplo, si la transacción B realizó cambios basándose en los efectos de una transacción anterior A, no es posible que los efectos de A se pierdan mientras se conservan los efectos de B.
El usuario puede seleccionar el modo de confirmación de cada transacción, de modo que es posible tener
transacciones de confirmación síncronas y asíncronas ejecutándose simultáneamente. Esto permite compensaciones
flexibles entre el rendimiento y la certeza de la durabilidad de la transacción. El modo de confirmación está
controlado por el parámetro configurable por el usuario synchronous_commit, que se puede
cambiar de cualquiera de las formas en que se puede establecer un parámetro de configuración. El modo utilizado
para cualquier transacción depende del valor de synchronous_commit cuando comienza la
confirmación de la transacción.
Ciertos comandos de utilidad, por ejemplo DROP TABLE, están forzados a confirmarse de forma
síncrona independientemente de la configuración de synchronous_commit. Esto es para garantizar
la coherencia entre el sistema de archivos del servidor y el estado lógico de la base de datos. Los comandos
que admiten la confirmación en dos fases, como PREPARE TRANSACTION, también son siempre síncronos.
Si la base de datos falla durante la ventana de riesgo entre una confirmación asíncrona y la escritura de
los registros WAL de la transacción, los cambios realizados durante esa transacción
se perderán. La duración de la ventana de riesgo es limitada porque un proceso en segundo
plano (el “WAL writer”) vacía los registros WAL no escritos al disco cada
wal_writer_delay milisegundos. La duración máxima real de la ventana de riesgo es tres
veces wal_writer_delay porque el WAL writer está diseñado para favorecer la escritura de
páginas completas a la vez durante los períodos de mayor actividad.
Un apagado en modo inmediato es equivalente a un fallo del servidor y, por lo tanto, provocará la pérdida de cualquier confirmación asíncrona que no haya sido vaciada.
La confirmación asíncrona proporciona un comportamiento diferente al de establecer fsync = off.
fsync es una configuración para todo el servidor que alterará el comportamiento de todas las
transacciones. Desactiva toda la lógica dentro de PostgreSQL que intenta sincronizar
las escrituras en diferentes porciones de la base de datos y, por lo tanto, un fallo del sistema (es decir,
un fallo del hardware o del sistema operativo, no un fallo de PostgreSQL en sí)
podría provocar una corrupción arbitrariamente grave del estado de la base de datos. En muchos escenarios,
la confirmación asíncrona proporciona la mayor parte de la mejora de rendimiento que se podría obtener desactivando
fsync, pero sin el riesgo de corrupción de datos.
commit_delay también suena muy similar a la confirmación asíncrona, pero en realidad
es un método de confirmación síncrona (de hecho, commit_delay se ignora durante una confirmación
asíncrona). commit_delay provoca un retraso justo antes de que una transacción vacíe el
WAL al disco, con la esperanza de que una sola operación de vaciado ejecutada por una de esas
transacciones también pueda servir a otras transacciones que se estén confirmando aproximadamente al mismo tiempo.
La configuración se puede considerar como una forma de aumentar la ventana de tiempo en la que las transacciones
pueden unirse a un grupo que está a punto de participar en un único vaciado, para amortizar el costo del vaciado
entre múltiples transacciones.