sql >> Base de Datos >  >> RDS >> PostgreSQL

Gestión de la congelación en PostgreSQL

Postgres contiene un horizonte de eventos en movimiento, que está en efecto alrededor de 2 mil millones de transacciones por delante o por detrás de la identificación de transacción actual. Las transacciones de hasta 2 mil millones por delante o más de 2 mil millones por detrás de la identificación de transacción actual se consideran en el futuro y, por lo tanto, serán invisibles para las transacciones actuales.

Postgres evita esta catastrófica pérdida de datos al marcar especialmente las filas antiguas para que, sin importar dónde se encuentren en relación con la identificación de la transacción actual, sean visibles.

La congelación es este proceso de marcar tuplas vivas antiguas (es decir, filas de la base de datos) para que no sean atropelladas por el horizonte de eventos en movimiento que, de lo contrario, las haría parecer en el futuro. Esto contrasta con el vaciado, que es la liberación del espacio consumido por viejas tuplas inactivas que ya no son visibles para ninguna transacción.

Ambos procesos son gestionados por vacío.

Hay una serie de configuraciones que rigen cómo se realiza la congelación.

Primero, vacuum_freeze_min_age gobierna si una tupla se congelará o no mientras el vacío ya está mirando una página para ver si tiene tuplas muertas que se pueden limpiar. Tuplas anteriores a vacuum_freeze_min_age será congelado en este caso. Establecer este valor bajo significa que habrá menos trabajo por hacer más adelante, pero con el posible costo de un esfuerzo adicional tanto en la CPU como en la actividad de E/S o WAL. En general, es probable que desee que este conjunto tenga al menos unas pocas horas de transacciones. Digamos que espera realizar hasta 2000 transacciones por segundo como una tasa sostenida. 2000 TPS es de 7,2 millones de transacciones por hora. Por lo tanto, una configuración bastante agresiva para este caso podría ser, digamos, 20 m. La configuración predeterminada es 50 m. Del mismo modo para vacuum_multixact_freeze_min_age . Tenga en cuenta que los contadores transaction_id y multixid son independientes:debe realizar un seguimiento de ambos.

En segundo lugar, hay vacuum_freeze_table_age y vacuum_multixact_freeze_table_age . Estas configuraciones rigen cuándo el vacío automático no solo buscará páginas que puedan tener filas muertas, sino cualquier página que pueda tener filas no congeladas. Los valores predeterminados para estos ajustes son 150 m. Si ha reducido vacuum_freeze_min_age suficiente, en muchos casos esta aspiradora más agresiva tendrá poco o ningún trabajo que hacer. En cualquier caso, este proceso no es tan ajetreado como solía ser, ya que las versiones modernas de Postgres (9.6 y superiores) mantienen un mapa de páginas donde todas las tuplas están congeladas, y solo visitan aquellas páginas que no están todas congeladas. Eso significa que esto ya no es un escaneo completo de la tabla.

Lo último es autovacuum_freeze_max_age . Si la última vez que se escaneó por completo la tabla en busca de filas no congeladas fue hace más de esta cantidad de transacciones, autovacuum iniciará un vacío anti-wraparound en la tabla. El valor predeterminado es 200 m. De manera similar para autovacuum_multixact_freeze_max_age para el cual el valor predeterminado es 400 m. Esto es algo que realmente quieres evitar. Hay dos cosas que se pueden hacer. En primer lugar, es muy común aumentar esta configuración a algo así como mil millones, para tener más espacio libre, especialmente en sistemas que son grandes consumidores de transacciones. Podría hacer más, pero desea tener mucho espacio de transacción entre su tupla más antigua y el horizonte de eventos. En segundo lugar, es importante monitorear sus sistemas y tomar medidas correctivas antes de que las bases de datos se encuentren con esto. Esta acción correctiva a menudo incluye pasar la aspiradora manualmente.

Un problema que puede ocurrir es cuando tiene DDL que hace que el vacío automático normal (es decir, no anti-envolvente) se cancele solo. Si hace esto lo suficiente, eventualmente obtendrá un vacío anti-envolvente forzado, y cualquier DDL luego se pondrá en cola detrás del proceso de vacío, y eso a su vez bloqueará cualquier DML adicional. En esta etapa, su tabla es efectivamente ilegible hasta que finaliza el vacío. Esto depende del patrón de uso de su base de datos, pero no es solo una posibilidad teórica y las implementaciones de Postgres y los administradores de bases de datos deben tenerlo en cuenta.

El monitoreo de su clúster de base de datos es fundamental para administrar esto. En particular, debe monitorear el datfrozenxid y datminmxid de cada base de datos del clúster y, si envejecen demasiado, tome medidas correctivas antes de que se requiera un vacío anti-envolvente. A menudo, el problema está en una o varias tablas de la base de datos. Cuáles son los problemas se pueden descubrir examinando el relfrozenxid y relminmxid de las tablas en la base de datos. La age() y mxid_age() Las funciones son útiles para descubrir la antigüedad de los contadores de id de transacción y multixid respectivamente.

La congelación no es algo que pueda evitar, es una actividad de mantenimiento esencial en Postgres que debe administrarse activamente.