Mejores prácticas de almacenamiento de OCI Database with PostgreSQL
Descubre las mejores prácticas para identificar, supervisar y resolver problemas relacionados con el almacenamiento al utilizar OCI Database with PostgreSQL.
OCI Database with PostgreSQL es un servicio totalmente gestionado que gestiona el almacenamiento automáticamente. A diferencia de la PostgreSQL tradicional que requiere que asigne espacio en disco manualmente, OCI PostgreSQL utiliza almacenamiento optimizado para bases de datos que se escala independientemente de los recursos informáticos.
OCI Database with PostgreSQL se basa en el estándar PostgreSQL y sigue las directrices de la comunidad para la seguridad y el diseño del disco, lo que garantiza una experiencia familiar para los usuarios de PostgreSQL. Para obtener más información, consulte el siguiente blog: Presentación de OCI Database with PostgreSQL: Completing Our Cloud Database Suite for Every Need.
Tipos de Almacenamiento
OCI Database with PostgreSQL utiliza las siguientes categorías de almacenamiento primario con diferentes características y requisitos de gestión:
Almacenamiento compartido de escala automática
El almacenamiento compartido de escala automática gestiona los datos de la base de datos y los archivos log de escritura anticipada (WAL). Este tipo de almacenamiento proporciona alta disponibilidad mediante la replicación entre dominios de disponibilidad.
Estas son las características clave del almacenamiento compartido de escala automática:
- Escala dinámica: el almacenamiento se escala automáticamente a medida que crea y borra objetos de base de datos. No se requiere aprovisionamiento previo y no se produce tiempo de inactividad durante la ampliación.
- Arquitectura desacoplada: los recursos informáticos y el almacenamiento están separados, lo que permite que cada uno se amplíe de forma independiente en función de sus necesidades.
- Alta disponibilidad: los datos se replican en los dominios de disponibilidad, lo que permite un failover rápido sin pérdida de datos.
- Límite estricto: la capacidad máxima es de 32 TB por sistema de base de datos.
El almacenamiento compartido de escala automática almacena los siguientes tipos de contenido:
- Datos de base de datos, como tablas, índices y otros objetos de base de datos.
- Archivos WAL para durabilidad y replicación de transacciones.
Almacenamiento temporal
El almacenamiento temporal se asigna por nodo y maneja archivos operativos que no requieren persistencia a largo plazo. Este almacenamiento no se escala automáticamente y su tamaño se basa en la unidad de computación. La fórmula para este tamaño de almacenamiento se basa en Max(50 GB, 2 GB + numOCPU × 32 GB).
Estas son las características clave del almacenamiento temporal:
- No se escala automáticamente: para aumentar la capacidad, debe actualizar a una unidad de computación más grande.
- Aislado de datos críticos: si se llena el almacenamiento temporal, los datos de la base de datos y el WAL no se verán afectados.
El almacenamiento temporal almacena los siguientes tipos de contenido:
- Archivos temporales/derrames de
pgsql_tmp/pg_tempdirypg_replslot, que se crean cuando las consultas superan la memoria disponible. - Archivos log PostgreSQL para supervisión y depuración.
- Archivos de desbordamiento de ranuras de replicación (para replicación lógica).
El resto de este tema aborda las mejores prácticas para gestionar los problemas de agotamiento del almacenamiento para estos tipos de almacenamiento.
Agotamiento del almacenamiento compartido
Las ranuras de replicación garantizan que los archivos WAL se retengan hasta que los suscriptores los hayan consumido. Cuando una ranura de replicación se vuelve inactiva o se queda atrás, PostgreSQL continúa acumulando archivos WAL, que eventualmente pueden agotar el almacenamiento compartido.
A continuación, se muestran escenarios comunes en los que puede producirse el agotamiento del almacenamiento compartido:
- Ranuras abandonadas: se ha desactivado un suscriptor, pero no se ha borrado la ranura de replicación
- Problemas de red: los problemas de alta latencia o conectividad entre la base de datos principal y la base de datos en espera hacen que la base de datos en espera se quede atrás
- Suscriptores lentos: herramientas de CDC de terceros o suscriptores federados que no pueden seguir el ritmo de la actividad de escritura
- Transacciones de ejecución incorrecta: las sesiones inactivas en transacción bloquean el buffer de reordenación, lo que hace que se acumule WAL
En la siguiente tabla, se muestran los parámetros clave de retención de WAL. El uso del disco WAL depende de estos parámetros combinados con ranuras de replicación activas o inactivas.
| Parámetro | Descripción |
|---|---|
max_slot_wal_keep_size |
Límite de retención de WAL para ranuras de replicación (-1 = ilimitado, lo que supone el riesgo de llenar el disco). Por ejemplo:
Siempre mantiene 20 GB de WAL de |
max_wal_size |
Tamaño máximo de WAL antes de forzar un CHECKPOINT. Por ejemplo:
obliga a CHECKPOINT cuando WAL alcanza los 5 GB. |
wal_keep_size |
Mínimo de archivos WAL que conservar para seguridad en espera (sin ranuras de replicación). Por ejemplo:
Siempre mantiene 10 GB de WAL del LSN actual. |
En la siguiente tabla, se muestran los beneficios y los riesgos de las configuraciones de WAL.
| Configuración de Parámetros | Beneficio | Riesgo |
|---|---|---|
max_slot_wal_keep_size = -1 |
La replicación no se interrumpe debido a la eliminación de WAL. | El disco principal se puede llenar. |
max_slot_wal_keep_size = 50GB |
El elemento primario está protegido contra el agotamiento del disco. | La replicación podría interrumpirse si la espera se retrasa demasiado. |
Supervisión y alertas
Utilice la siguiente consulta para identificar la retención de WAL por ranuras de replicación:
SELECT
slot_name,
active,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS wal_retained,
pg_size_pretty(safe_wal_size) AS safe_wal_remaining
FROM pg_replication_slots;
En este ejemplo de un retorno, se retienen 15 GB de WAL y solo se pueden retener 5 GB más antes de que la ranura se invalide (si se configura max_slot_wal_keep_size). Si max_slot_wal_keep_size = -1, safe_wal_remaining muestra NULL.
slot_name | active | wal_retained | safe_wal_remaining
-----------+--------+--------------+--------------------
replica_1 | t | 15 GB | 5 GB
Para obtener instrucciones sobre la configuración de alarmas personalizadas, consulte Creación de alarmas y paneles de control de supervisión de OCI personalizados de PostgreSQL mediante Container Instances
Le recomendamos que configure alertas si se produce alguna de las siguientes condiciones:
wal_retainedsupera el 50 % de la capacidad disponible.- Cualquier espacio tiene
active = falsedurante más de una hora.
Mitigación y prevención
Utilice las siguientes medidas de mitigación según sea necesario:
- Borrar ranuras abandonadas: si un suscriptor ya no es necesario o se puede volver a crear, borre la ranura de replicación:
SELECT pg_drop_replication_slot('slot_name'); - Definir límite de retención finito: configure
max_slot_wal_keep_sizeen un valor que equilibre la estabilidad de la replicación con la protección principal.
- Seleccione el valor
max_slot_wal_keep_sizeadecuado según los siguientes requisitos:- Para la replicación crítica: defina un valor superior o -1, pero supervise de cerca el uso del disco.
- Para protección principal: defina un valor finito y acepte que la replicación se pueda interrumpir durante interrupciones prolongadas.
- Para suscriptores que se pueden volver a crear: utilice valores inferiores porque el suscriptor se puede volver a crear si es necesario.
- Implantar la supervisión de ranuras: configure alertas automatizadas antes de que las ranuras causen problemas de almacenamiento.
- Propiedad de espacio de documento: mantenga un registro del cual la aplicación o el equipo sea propietario de cada espacio de replicación.
- Planificación de problemas de red: garantiza un ancho de banda adecuado y una baja latencia entre las réplicas y las primarias.
Agotamiento de almacenamiento temporal
El almacenamiento temporal se puede agotar debido a un registro excesivo, una configuración de memoria inadecuada que causa archivos de desbordamiento o archivos de desbordamiento de ranuras de replicación. En esta sección se trata cada escenario con orientación de supervisión y resolución.
Registro excesivo de PostgreSQL
PostgreSQL proporciona amplios parámetros de registro útiles para la depuración. Sin embargo, la configuración de registro agresiva puede generar una E/S de disco excesiva durante el tráfico máximo, llenando rápidamente el volumen de almacenamiento temporal.
Estas son las configuraciones problemáticas comunes:
- log_statement = 'all': registra cada sentencia SQL, generando volúmenes de log masivos en sistemas ocupados.
- log_min_duration_statement = 0: registra cada sentencia con su duración.
- log_connections/log_disconnections = on: en sistemas de alto tráfico, genera entradas para cada conexión.
- Registro de nivel de depuración activado: los parámetros como
log_executor_stats,log_parser_stats,log_planner_statsgeneran una salida detallada.
Los síntomas del registro excesivo de PostgreSQL incluyen:
- El uso de almacenamiento temporal aumenta rápidamente.
- E/S de disco alto en el volumen de registro.
Mitigación y prevención
Siga estas directrices para mitigar y evitar problemas relacionados con el registro excesivo:
- Revise y ajuste los parámetros de registro según los requisitos de la aplicación.
- Desactive el registro detallado una vez finalizada la depuración.
- Evite dejar activado el registro de nivel de depuración en producción, ya que esto agrega una carga innecesaria al servidor de la base de datos.
- Si el registro legítimo necesita más espacio, aumente la unidad del nodo o escale verticalmente el sistema de base de datos.
En la siguiente tabla, se muestran los parámetros de registro y la información relacionada.
| Parámetro | Descripción | Valor problemático | Valor Recomendado |
|---|---|---|---|
log_statement |
Controla qué sentencias SQL se registran | todos | Ninguno o ddl o mod |
log_min_duration_statement |
Sentencias de logs que superan los milisegundos especificados | 0 | -1 o ≥1000 |
log_connections |
Registra cada conexión correcta | en (alto tráfico) | desactivado |
log_disconnections |
Registra terminaciones de sesiones, incluida la duración | en (alto tráfico) | desactivado |
log_autovacuum_min_duration |
Registra acciones de vacío automático que exceden los milisegundos especificados | 0 | -1 o ≥60000 |
log_error_verbosity |
Controla el nivel de detalle de los mensajes de error | detallado | por defecto |
log_executor_stats |
Logs de estadísticas de rendimiento del ejecutor | activado | desactivado |
log_parser_stats |
Estadísticas de rendimiento del analizador de logs | activado | desactivado |
log_planner_stats |
Registra estadísticas de rendimiento del planificador | activado | desactivado |
log_statement_stats |
Logs de estadísticas de rendimiento total de sentencias | activado | desactivado |
log_duration |
Registra la duración de cada sentencia completada | en (alto tráfico) | desactivado |
Configuración de memoria inadecuada (archivos temporales/de recarga)
PostgreSQL utiliza memoria adicional más allá de shared_buffers para el procesamiento de consultas. Mientras que shared_buffers maneja el almacenamiento en caché de datos y las operaciones DML en memoria, work_mem se utiliza para operaciones de consulta como la ordenación, la unión y la agregación.
Cuando una consulta implica operaciones JOIN, AGGREGATE o SORT, PostgreSQL primero comprueba si las columnas relevantes tienen índices preordenados. Si los índices no están disponibles, PostgreSQL intenta realizar estas operaciones en la memoria.
Si el valor work_mem no es suficiente para los datos que se están procesando, PostgreSQL genera archivos temporales y utiliza disco en lugar de memoria.
A continuación, se muestran escenarios comunes en los que se puede producir una configuración de memoria inadecuada:
- Consultas analíticas complejas: consultas con varias JOIN, ordenaciones grandes o agregaciones en juegos de datos grandes.
- Valor por defecto work_mem demasiado bajo: el valor por defecto de 4 MB puede ser insuficiente para consultas complejas.
- Alta simultaneidad con consultas que hacen un uso intensivo de la memoria: muchas consultas simultáneas consumen work_mem cada una.
- Operaciones de mantenimiento: las operaciones como
CREATE INDEX,REINDEX,CLUSTERoREFRESH MATERIALIZED VIEWutilizanmaintenance_work_memy pueden generar archivos temporales si el tamaño es bajo.
En el siguiente ejemplo, se muestra una entrada de log de ejemplo cuando el disco se llena:
2025-12-03 10:55:25.650 UTC [249610] ERROR: could not write block 196800198 of temporary file: No space left on device
Los síntomas de una configuración de memoria inadecuada excesiva incluyen:
- El almacenamiento temporal se completa durante la ejecución de consultas complejas.
- Rendimiento de consultas lento en operaciones JOIN, SORT o AGGREGATE.
- Aumento de E/S de disco durante el procesamiento de consultas.
Supervisión y alertas
Utilice la siguiente consulta para identificar el uso de archivos temporales por base de datos:
SELECT
datname,
temp_files,
pg_size_pretty(temp_bytes) AS temp_size
FROM pg_stat_database
WHERE temp_bytes > 0
ORDER BY temp_bytes DESC;
A continuación, se muestra un ejemplo de lo que se devuelve:
datname | temp_files | temp_size
----------+------------+------------
app | 1523 | 45 GB
postgres | 12 | 120 MB
Estos valores son acumulativos. A medida que la base de datos continúa generando archivos temporales, estos valores aumentan con el tiempo.
Utilice la siguiente consulta para comprobar el uso de archivos temporales activos:
SELECT * FROM pg_ls_tmpdir();
A continuación, se muestra un ejemplo de lo que se devuelve:
name | size | modification
-------------------+----------+------------------------
pgsql_tmp249610.3 | 14000000 | 2025-12-03 10:20:16+00
pgsql_tmp249696.0 | 12394496 | 2025-12-03 10:20:16+00
pgsql_tmp249610.2 | 13860864 | 2025-12-03 10:20:16+00
pgsql_tmp249697.0 | 12910592 | 2025-12-03 10:20:16+00
Introduzca los siguientes comandos para comprobar la configuración de memoria actual:
SHOW work_mem;
SHOW hash_mem_multiplier;
SHOW maintenance_work_mem;
Para obtener instrucciones sobre la configuración de alarmas personalizadas, consulte Creación de alarmas y paneles de control de supervisión de OCI personalizados de PostgreSQL mediante Container Instances
Le recomendamos que configure alertas si se produce alguna de las siguientes condiciones:
TempStorageUsedPercentsupera los umbrales definidos.- El uso de archivos temporales (de
pg_ls_tmpdir()) muestra un crecimiento sostenido.
Mitigación y prevención
Siga estas prácticas para mitigar y evitar los problemas asociados con una configuración de memoria inadecuada:
- Identificar consultas que generan archivos temporales
Active el registro para capturar consultas que generan archivos temporales:
- Defina
log_temp_files = 0para registrar toda la creación de archivos temporales - Defina
log_min_error_statement = logpara incluir el texto de consulta SQL
A continuación, se muestra un ejemplo de entrada de archivo log temporal:
2025-12-03 10:45:17.650 UTC [249610] LOG: temporary file: path "pg_tempdir/pgsql_tmp/pgsql_tmp249610.5", size 14000000 - Defina
- Optimización de consultas
Revise las consultas registradas y optimícelas cuando sea posible. El ajuste de consultas debe ser el primer enfoque antes de aumentar la configuración de memoria. Considere la posibilidad de agregar índices adecuados para evitar ordenaciones en memoria.
- Ajustar work_mem (si no es posible la optimización de consultas)
Si no se pueden mejorar las consultas, considere aumentar
work_mem. Utilice la siguiente fórmula como punto de partida:work_mem <= (Available Memory) / (max_connections + max_parallel_workers)Donde
Available Memoryes la memoria total del sistema menos shared_buffers yoci.pagecache_size.Nota
En el peor de los casos, cada sesión puede consumir esta cantidad de memoria. Si todas las sesiones requierenwork_memsimultáneamente, podría agotar la memoria disponible del sistema.Reducir la generación temporal de archivos, pero no eliminarlos por completo. La eliminación de todos los archivos temporales puede requerir una unidad de computación más grande o el consumo de toda la memoria disponible.
- Ajustar hash_mem_multiplier (para operaciones hash)
Si las consultas siguen generando archivos temporales e implican operaciones hash (no SORT), aumente
hash_mem_multiplier:SHOW hash_mem_multiplier; hash_mem_multiplier --------------------- 1 (1 row)Al aumentar este valor, se asigna más memoria para las operaciones hash. La memoria hash efectiva es
work_mem × hash_mem_multiplier. - Ajustar maintenance_work_mem para operaciones de mantenimiento
Las consultas regulares de aplicaciones no son el único origen de archivos temporales. Las operaciones de mantenimiento también generan archivos temporales:
REFRESH MATERIALIZED VIEWCREATE INDEXCLUSTERREINDEX
Estas operaciones utilizan
maintenance_work_memen lugar dework_mem:
SHOW maintenance_work_mem;
Si las operaciones de mantenimiento se ejecutan en juegos de datos grandes y maintenance_work_mem es insuficiente, se generan archivos temporales.
En la siguiente tabla, se muestran los parámetros de memoria y la información relacionada.
| Parámetro | Descripción | Riesgo si está mal configurado | Valor Recomendado |
|---|---|---|---|
work_mem |
Memoria base por operación de ordenación/hash antes de derramarse al disco | Demasiado alto con alta simultaneidad | Menor para OLTP y mayor para análisis |
hash_mem_multiplier |
Multiplicador para operaciones hash: hash_mem = work_mem × este valor |
Demasiado alto (≥8.0) con alta simultaneidad | 2.0 (valor por defecto) |
maintenance_work_mem |
Memoria para operaciones VACUUM, CREATE INDEX, REFRESH MATERIALIZED VIEW | Demasiado alto con muchos trabajadores de autovacuum | Saldo con autovacuum_max_workers |
Archivos de desbordamiento de ranuras de replicación (replicación lógica)
La replicación lógica PostgreSQL utiliza la descodificación lógica para transformar los registros WAL raw en cambios significativos y estructurados a nivel de fila. A diferencia de la replicación física que copia bloques de disco de byte a byte, la descodificación lógica interpreta los datos transaccionales y los convierte en cambios lógicos (INSERT, UPDATE, DELETE) con valores de columna reales.
Cada ranura de replicación lógica tiene un proceso de remitente WAL asociado responsable de los cambios de transmisión en los suscriptores de destino. Las transacciones se envían en orden de confirmación, y el suscriptor recibe, descodifica y aplica estos cambios al sistema de destino.
PostgreSQL soporta la replicación lógica nativa donde el suscriptor es otra instancia PostgreSQL. A partir de PostgreSQL 14, los suscriptores pueden gestionar grandes transacciones en curso de forma eficaz con el modo streaming=on activado:
- Las transacciones en curso (todavía no confirmadas) se transmiten de forma incremental al suscriptor.
- El suscriptor aplica los cambios a un estado temporal/pendiente inmediatamente.
- Una vez que la transacción se confirma en el editor, el suscriptor confirma esos cambios.
- Si se realiza un rollback de la transacción, el suscriptor descarta los cambios pendientes.
Este enfoque evita que el editor acumule grandes cantidades de datos descodificados en la memoria o derrame archivos mientras espera que se completen las transacciones de larga ejecución.
Los suscriptores federados o de terceros también pueden consumir de ranuras de replicación lógicas PostgreSQL mediante el protocolo de replicación PostgreSQL. Sin embargo, a diferencia de los suscriptores PostgreSQL nativos, los suscriptores federados normalmente no soportan el modo streaming=on porque no pueden controlar cómo se comporta el sistema de destino subyacente.
Cuando un suscriptor no admite streaming=on, el remitente de WAL de PostgreSQL mantiene los cambios descodificados para las transacciones en curso en los archivos de vertido en:
pg_replslot/<slot_name>/xid-<xid>-lsn-<lsn>.spill
Estos archivos de derrame pueden crecer debido a la estricta garantía de orden de confirmación de PostgreSQL. Por ejemplo:
- La transacción TRX1 permanece abierta durante mucho tiempo (inactivo en la transacción o realizando operaciones masivas).
- Otras transacciones independientes (TRX2, TRX3, TRX4, etc.) continúan confirmándose.
- El remitente de WAL acumula datos de transacciones confirmadas en los archivos de derrames.
- Estas transacciones solo se envían al suscriptor después de que TRX1 emita COMMIT o ROLLBACK.
Este es el comportamiento esperado al trabajar con suscriptores federados que no soportan el modo streaming=on.
En el siguiente ejemplo, se muestran los detalles del archivo de derrames (registrados en el nivel DEBUG2) en el registro:
2025-12-03 10:28:14.650 UTC [249610] DEBUG: spill 4096 changes in XID 750 to disk
Si el disco se llena, las entradas del log cambian a lo siguiente:
2025-12-03 10:32:15.550 UTC [249610] ERROR: could not write to data file for XID <xid>: No space left on device
2025-12-03 10:32:15.554 UTC [249610] ERROR: could not read from reorderbuffer spill file: No space left on device
Los síntomas de los archivos de desbordamiento de ranura de replicación incluyen:
- El uso de almacenamiento temporal aumenta rápidamente.
- Muchos archivos
.spillestán presentes en la carpetapg_replslot.
Supervisión y alertas
Utilice la siguiente consulta para identificar estadísticas de archivos de desbordamiento para ranuras de replicación:
SELECT
slot_name,
spill_txns,
spill_count,
pg_size_pretty(spill_bytes) AS spill_size,
stream_txns,
stream_count,
pg_size_pretty(stream_bytes) AS stream_size
FROM pg_stat_replication_slots;
En el siguiente ejemplo de una devolución:
slot_name | spill_txns | spill_count | spill_size | stream_txns | stream_count | stream_size
------------------+------------+-------------+------------+-------------+--------------+-------------
federated_sub_1 | 847 | 15234 | 2458 MB | 0 | 0 | 0 bytes
spill_sizede 2458 MB indica un uso significativo del disco de los archivos de desbordamiento.stream_sizede 0 bytes confirma que el suscriptor no es nativo y no soporta el modo de transmisión.- El proceso de remitente WAL está reteniendo o derramando transacciones en el disco.
Utilice el siguiente comando para comprobar la configuración actual de logical_decoding_work_mem:
SHOW logical_decoding_work_mem;
logical_decoding_work_mem
---------------------------
64MB
Para obtener instrucciones sobre la configuración de alarmas personalizadas, consulte Creación de alarmas y paneles de control de supervisión de OCI personalizados de PostgreSQL mediante Container Instances
Le recomendamos que configure alertas si se produce alguna de las siguientes condiciones:
spill_bytespor espacio supera los umbrales definidos.- El uso de archivos de derramamiento muestra un rápido crecimiento.
Mitigación y prevención
Las transacciones de vertido son inevitables cuando están involucrados suscriptores no nativos. Sin embargo, puede reducir la frecuencia y el tamaño de los archivos de derrames siguiendo estas prácticas:
- Manejar cuidadosamente las transacciones grandes: realice operaciones masivas en lotes más pequeños.
- Evitar transacciones inactivas de larga ejecución: bloquean el buffer de reordenación y causan la acumulación de archivos de derrame.
- Aumentar logical_decoding_work_mem: retrasa el derrame al permitir más datos descodificados en la memoria.
- Definir idle_in_transaction_session_timeout: finaliza las sesiones que permanecen inactivas en la transacción durante demasiado tiempo.
En la siguiente tabla, se muestran los parámetros de descodificación lógica y la información relacionada.
| Parámetro | Descripción | Riesgo si no está configurado correctamente | Valor Recomendado |
|---|---|---|---|
logical_decoding_work_mem |
Umbral de memoria antes de derramar los cambios descodificados en pg_replslot/<slot>/. Este valor se aplica a cada ranura de replicación lógica. |
Demasiado bajo con transacciones grandes/largas | DE 256 MB A 1 GB |
idle_in_transaction_session_timeout |
Finaliza las sesiones de inactividad en transacción que bloquean la entrega del buffer de reorden | 0 (desactivado) | 10 min–30 min |