La conmutación por error de disco compartido evita la sobrecarga de sincronización al tener solo una copia de la base de datos. Utiliza una única matriz de discos que se comparte entre múltiples servidores. Si el servidor de base de datos principal falla, el servidor standby puede montar e iniciar la base de datos como si se estuviera recuperando de una caída de la base de datos. Esto permite una conmutación por error rápida sin pérdida de datos.
La funcionalidad de hardware compartido es común en los dispositivos de almacenamiento en red. También es posible utilizar un sistema de archivos en red, aunque se debe tener cuidado de que el sistema de archivos tenga un comportamiento POSIX completo (consulta Section 18.2.2.1). Una limitación significativa de este método es que si la matriz de discos compartidos falla o se corrompe, los servidores primario y standby quedan inoperativos. Otro problema es que el servidor standby nunca debe acceder al almacenamiento compartido mientras el servidor primario esté en funcionamiento.
Una versión modificada de la funcionalidad de hardware compartido es la replicación del sistema de archivos, donde todos los cambios en un sistema de archivos se reflejan en un sistema de archivos que reside en otra computadora. La única restricción es que el reflejo (mirroring) debe hacerse de manera que se garantice que el servidor standby tenga una copia consistente del sistema de archivos — específicamente, las escrituras en el standby deben realizarse en el mismo orden que en el primario. DRBD es una solución popular de replicación de sistemas de archivos para Linux.
Los servidores warm standby y hot standby se pueden mantener al día leyendo un flujo de registros de escritura anticipada (WAL). Si el servidor principal falla, el standby contiene casi todos los datos del servidor principal, y se puede convertir rápidamente en el nuevo servidor de base de datos primario. Esto puede ser síncrono o asíncrono y solo se puede hacer para todo el servidor de base de datos.
Un servidor standby se puede implementar mediante el envío de registros basado en archivos (Section 26.2) o la replicación en flujo (streaming replication) (consulta Section 26.2.5), o una combinación de ambos. Para obtener información sobre hot standby, consulta Section 26.4.
La replicación lógica permite que un servidor de base de datos envíe un flujo de modificaciones de datos a otro servidor. La replicación lógica de PostgreSQL construye un flujo de modificaciones lógicas de datos a partir del WAL. La replicación lógica permite la replicación de cambios de datos tabla por tabla. Además, un servidor que está publicando sus propios cambios también puede suscribirse a los cambios de otro servidor, lo que permite que los datos fluyan en múltiples direcciones. Para obtener más información sobre la replicación lógica, consulta Chapter 29. A través de la interfaz de decodificación lógica (Chapter 47), las extensiones de terceros también pueden proporcionar una funcionalidad similar.
Una configuración de replicación basada en disparadores normalmente canaliza las consultas de modificación de datos a un servidor primario designado. Operando tabla por tabla, el servidor primario envía los cambios de datos (típicamente) de forma asíncrona a los servidores standby. Los servidores standby pueden responder a las consultas mientras el primario está en funcionamiento, y pueden permitir algunos cambios de datos locales o actividad de escritura. Esta forma de replicación se utiliza a menudo para descargar consultas analíticas grandes o consultas de almacén de datos (data warehouse).
Slony-I es un ejemplo de este tipo de replicación, con granularidad por tabla y soporte para múltiples servidores standby. Debido a que actualiza el servidor standby de forma asíncrona (en lotes), es posible que se pierdan datos durante una conmutación por error.
Con el middleware de replicación basado en SQL, un programa intercepta cada consulta SQL y la envía a uno o a todos los servidores. Cada servidor funciona de forma independiente. Las consultas de lectura/escritura deben enviarse a todos los servidores, para que cada servidor reciba los cambios. Pero las consultas de solo lectura se pueden enviar a un solo servidor, lo que permite distribuir la carga de trabajo de lectura entre ellos.
Si las consultas simplemente se transmiten sin modificar, las funciones como
random(), CURRENT_TIMESTAMP y las
secuencias pueden tener valores diferentes en servidores diferentes.
Esto se debe a que cada servidor funciona de forma independiente y a que
se transmiten consultas SQL en lugar de los cambios de datos reales. Si
esto es inaceptable, el middleware o la aplicación
deben determinar dichos valores a partir de una única fuente y luego utilizar esos
valores en las consultas de escritura. También se debe tener cuidado de que todas las
transacciones se confirmen o aborten en todos los servidores, tal vez
utilizando la confirmación en dos fases (PREPARE TRANSACTION
y COMMIT PREPARED).
Pgpool-II y Continuent Tungsten
son ejemplos de este tipo de replicación.
Para los servidores que no están conectados regularmente o que tienen enlaces de comunicación lentos, como las computadoras portátiles o los servidores remotos, mantener la consistencia de los datos entre los servidores es un desafío. Mediante la replicación multimaestro asíncrona, cada servidor trabaja de forma independiente y se comunica periódicamente con los demás servidores para identificar transacciones en conflicto. Los conflictos pueden ser resueltos por los usuarios o por reglas de resolución de conflictos. Bucardo es un ejemplo de este tipo de replicación.
En la replicación multimaestro síncrona, cada servidor puede aceptar
solicitudes de escritura, y los datos modificados se transmiten desde el
servidor original a todos los demás servidores antes de que se confirme cada
transacción. Una actividad de escritura intensa puede provocar bloqueos excesivos y
retrasos en las confirmaciones, lo que conduce a un rendimiento deficiente. Las solicitudes de lectura se pueden
enviar a cualquier servidor. Algunas implementaciones utilizan discos compartidos
para reducir la sobrecarga de comunicación. La replicación multimaestro
síncrona es mejor para cargas de trabajo principalmente de lectura, aunque su gran
ventaja es que cualquier servidor puede aceptar solicitudes de escritura —
no es necesario particionar las cargas de trabajo entre los servidores primario y
standby, y debido a que los cambios de datos se envían de un
servidor a otro, no hay problemas con las funciones no deterministas
como random().
PostgreSQL no ofrece este tipo de replicación, aunque la confirmación en dos fases de PostgreSQL (PREPARE TRANSACTION y COMMIT PREPARED) se puede utilizar para implementar esto en el código de la aplicación o en el middleware.
El Table 26.1 resume las capacidades de las diversas soluciones enumeradas anteriormente.
Table 26.1. Matriz de características de alta disponibilidad, balanceo de carga y replicación
| Característica | Disco compartido | Repl. Sist. Archivos | Envío de registros WAL | Replicación lógica | Replicación por disparadores | Middleware Replicación SQL | Repl. MM asíncrona | Repl. MM síncrona |
|---|---|---|---|---|---|---|---|---|
| Ejemplos populares | NAS | DRBD | replicación en flujo integrada | replicación lógica integrada, pglogical | Londiste, Slony | pgpool-II | Bucardo | |
| Método de com. | disco compartido | bloques de disco | WAL | decodificación lógica | filas de tabla | SQL | filas de tabla | filas de tabla y bloqueos de fila |
| No requiere hardware especial | • | • | • | • | • | • | • | |
| Permite múltiples servidores primarios | • | • | • | • | ||||
| Sin sobrecarga en el primario | • | • | • | • | ||||
| Sin esperar a múltiples servidores | • | con sincr. desactivada | con sincr. desactivada | • | • | |||
| La falla del primario nunca perderá datos | • | • | con sincr. activada | con sincr. activada | • | • | ||
| Las réplicas aceptan consultas de solo lectura | con hot standby | • | • | • | • | • | ||
| Granularidad por tabla | • | • | • | • | ||||
| No requiere resolución de conflictos | • | • | • | • | • | • |
Hay algunas soluciones que no encajan en las categorías anteriores:
El particionamiento de datos divide las tablas en conjuntos de datos. Cada conjunto puede ser modificado por un solo servidor. Por ejemplo, los datos pueden particionarse por oficinas, por ejemplo, Londres y París, con un servidor en cada oficina. Si son necesarias consultas que combinen datos de Londres y París, una aplicación puede consultar ambos servidores, o se puede utilizar la replicación primario/standby para mantener una copia de solo lectura de los datos de la otra oficina en cada servidor.
Muchas de las soluciones anteriores permiten que múltiples servidores manejen múltiples consultas, pero ninguna permite que una sola consulta utilice múltiples servidores para completarse más rápido. Esta solución permite que múltiples servidores trabajen concurrentemente en una sola consulta. Por lo general, se logra dividiendo los datos entre los servidores y haciendo que cada servidor ejecute su parte de la consulta y devuelva los resultados a un servidor central donde se combinan y se devuelven al usuario. Esto se puede implementar utilizando el conjunto de herramientas PL/Proxy.
También cabe señalar que debido a que PostgreSQL es de código abierto y fácilmente extensible, varias empresas han tomado PostgreSQL y han creado soluciones comerciales de código cerrado con capacidades únicas de conmutación por error, replicación y balanceo de carga. Estas no se discuten aquí.