

# Ajuste con eventos de espera de RDS para PostgreSQL
<a name="PostgreSQL.Tuning"></a>

Los eventos de espera son una importante herramienta de ajuste para RDS para PostgreSQL. Si puede averiguar por qué las sesiones esperan recursos y qué están haciendo, podrá reducir mejor los cuellos de botella. Puede utilizar la información de esta sección para encontrar las posibles causas y acciones correctivas. En esta sección también se describen los conceptos básicos de ajuste de PostgreSQL.

Los eventos de espera en esta sección son específicos de RDS para PostgreSQL.

**Topics**
+ [

# Conceptos esenciales para el ajuste de RDS para PostgreSQL
](PostgreSQL.Tuning.concepts.md)
+ [

# Eventos de espera de RDS para PostgreSQL
](PostgreSQL.Tuning.concepts.summary.md)
+ [

# Client:ClientRead
](wait-event.clientread.md)
+ [

# Client:ClientWrite
](wait-event.clientwrite.md)
+ [

# CPU
](wait-event.cpu.md)
+ [

# IO:BufFileRead y IO:BufFileWrite
](wait-event.iobuffile.md)
+ [

# IO:DataFileRead
](wait-event.iodatafileread.md)
+ [

# IO:WALWrite
](wait-event.iowalwrite.md)
+ [

# Eventos de espera de IPC:parallel
](rpg-ipc-parallel.md)
+ [

# IPC:ProcArrayGroupUpdate
](apg-rpg-ipcprocarraygroup.md)
+ [

# Lock:advisory
](wait-event.lockadvisory.md)
+ [

# Lock:extend
](wait-event.lockextend.md)
+ [

# Lock:Relation
](wait-event.lockrelation.md)
+ [

# Lock:transactionid
](wait-event.locktransactionid.md)
+ [

# Lock:tuple
](wait-event.locktuple.md)
+ [

# LWLock:BufferMapping (LWLock:buffer\$1mapping)
](wait-event.lwl-buffer-mapping.md)
+ [

# LWLock:BufferIO (IPC:BufferIO)
](wait-event.lwlockbufferio.md)
+ [

# LWLock:buffer\$1content (BufferContent)
](wait-event.lwlockbuffercontent.md)
+ [

# LWLock:lock\$1manager (LWLock:lockmanager)
](wait-event.lw-lock-manager.md)
+ [

# LWLock:pg\$1stat\$1statements
](apg-rpg-lwlockpgstat.md)
+ [

# LWLock:SubtransSLRU (LWLock:SubtransControlLock)
](wait-event.lwlocksubtransslru.md)
+ [

# Timeout:PgSleep
](wait-event.timeoutpgsleep.md)
+ [

# Timeout:VacuumDelay
](wait-event.timeoutvacuumdelay.md)

# Conceptos esenciales para el ajuste de RDS para PostgreSQL
<a name="PostgreSQL.Tuning.concepts"></a>

Antes de ajustar la base de datos de RDS para PostgreSQL, asegúrese de saber qué son los eventos de espera y por qué se producen. Revise también la arquitectura básica de memoria y disco de RDS para PostgreSQL. Para ver un diagrama de arquitectura útil, consulte el wikibook de [PostgreSQL](https://en.wikibooks.org/wiki/PostgreSQL/Architecture).

**Topics**
+ [

# Eventos de espera de RDS para PostgreSQL
](PostgreSQL.Tuning.concepts.waits.md)
+ [

# Memoria de RDS para PostgreSQL
](PostgreSQL.Tuning.concepts.memory.md)
+ [

# Procesos de RDS para PostgreSQL
](PostgreSQL.Tuning.concepts.processes.md)

# Eventos de espera de RDS para PostgreSQL
<a name="PostgreSQL.Tuning.concepts.waits"></a>

Un *evento de espera* es una indicación de que la sesión espera un recurso. Por ejemplo, el evento de espera `Client:ClientRead` ocurre cuando RDS para PostgreSQL espera recibir datos del cliente. Por lo general, las sesiones esperan recursos como los siguientes.
+ Acceso de subproceso único a un búfer, por ejemplo, cuando una sesión intenta modificar un búfer
+ Una fila bloqueada actualmente por otra sesión
+ Lectura de un archivo de datos
+ Escritura de un archivo de registro

Por ejemplo, para satisfacer una consulta, la sesión podría hacer un escaneo de tabla completo. Si los datos ya no están en la memoria, la sesión espera a que se complete la E/S del disco. Cuando los búferes se leen en la memoria, es posible que la sesión tenga que esperar porque otras sesiones tienen acceso a los mismos búferes. La base de datos registra las esperas mediante un evento de espera predefinido. Estos eventos se agrupan en categorías.

Un evento de espera no significa por sí solo un problema de rendimiento. Por ejemplo, si los datos solicitados no están en memoria, es necesario leer los datos del disco. Si una sesión bloquea una fila para una actualización, otra sesión espera a que se desbloquee la fila para poder actualizarla. Una confirmación requiere un tiempo de espera para que se complete la escritura en un archivo de registro. Las esperas forman parte del funcionamiento normal de una base de datos. 

Por otro lado, un gran número de eventos de espera suele ser indicativo de un problema de rendimiento. En estos casos, se pueden utilizar los datos de los eventos de espera para determinar en qué se gastan las sesiones. Por ejemplo, si un informe que normalmente se ejecuta en minutos ahora se ejecuta durante horas, puede identificar los eventos de espera que más contribuyen al tiempo total de espera. Si puede determinar las causas de los principales eventos de espera, a veces puede hacer cambios que mejoren el rendimiento. Por ejemplo, si la sesión se encuentra a la espera de una fila que ha sido bloqueada por otra sesión, puede terminar la sesión de bloqueo. 

# Memoria de RDS para PostgreSQL
<a name="PostgreSQL.Tuning.concepts.memory"></a>

La memoria de RDS para PostgreSQL se divide en compartida y local.

**Topics**
+ [

## Memoria compartida en RDS para PostgreSQL
](#PostgreSQL.Tuning.concepts.shared)
+ [

## Memoria local en RDS para PostgreSQL
](#PostgreSQL.Tuning.concepts.local)

## Memoria compartida en RDS para PostgreSQL
<a name="PostgreSQL.Tuning.concepts.shared"></a>

RDS para PostgreSQL asigna memoria compartida cuando se inicia la instancia. La memoria compartida se divide en múltiples subáreas. En las siguientes secciones se proporcionan descripciones de las más importantes.

**Topics**
+ [

### Búferes compartidos
](#PostgreSQL.Tuning.concepts.buffer-pool)
+ [

### Búferes de registro de escritura anticipada (WAL)
](#PostgreSQL.Tuning.concepts.WAL)

### Búferes compartidos
<a name="PostgreSQL.Tuning.concepts.buffer-pool"></a>

El *grupo de búferes compartidos* es un área de memoria de RDS para PostgreSQL que contiene todas las páginas que utilizan o han utilizado las conexiones de la aplicación. Una *página* es la versión de memoria de un bloque de disco. El grupo de búferes compartidos almacena en caché los bloques de datos leídos desde el disco. El grupo reduce la necesidad de volver a leer los datos del disco, lo que hace que la base de datos funcione de forma más eficiente.

Cada tabla e índice se almacena como una matriz de páginas de tamaño fijo. Cada bloque contiene varias tuplas, que corresponden a filas. Una tupla se puede almacenar en cualquier página.

El grupo de búferes compartidos tiene memoria finita. Si una nueva solicitud requiere una página que no está en la memoria, y no hay más memoria, RDS para PostgreSQL desaloja una página que se utiliza con menos frecuencia para satisfacer la solicitud. La política de expulsión se implementa mediante un algoritmo de barrido de reloj.

El parámetro `shared_buffers` determina la cantidad de memoria que el servidor dedica al almacenamiento en caché de los datos. El valor predeterminado se establece en `{DBInstanceClassMemory/32768}` bytes, en función de la memoria disponible para la instancia de base de datos.

### Búferes de registro de escritura anticipada (WAL)
<a name="PostgreSQL.Tuning.concepts.WAL"></a>

Un *búfer del registro de escritura anticipada (WAL)* contiene datos de transacciones que RDS para PostgreSQL escribe posteriormente en el almacenamiento persistente. Con el mecanismo WAL, RDS para PostgreSQL puede hacer lo siguiente:
+ Recuperar datos después de un error
+ Reducir la E/S del disco al evitar las escrituras frecuentes en el disco

Cuando un cliente cambia los datos, RDS para PostgreSQL escribe los cambios en el búfer de WAL. Cuando el cliente emite un `COMMIT`, el proceso de escritura WAL escribe los datos de la transacción en el archivo WAL.

El parámetro `wal_level` determina la cantidad de información que se escribe en el WAL, con posibles valores como `minimal`, `replica` y `logical`.

## Memoria local en RDS para PostgreSQL
<a name="PostgreSQL.Tuning.concepts.local"></a>

Cada proceso de backend asigna memoria local para el procesamiento de consultas.

**Topics**
+ [

### Área de memoria de trabajo
](#PostgreSQL.Tuning.concepts.local.work_mem)
+ [

### Área de memoria de trabajo de mantenimiento
](#PostgreSQL.Tuning.concepts.local.maintenance_work_mem)
+ [

### Área de búfer temporal
](#PostgreSQL.Tuning.concepts.temp)

### Área de memoria de trabajo
<a name="PostgreSQL.Tuning.concepts.local.work_mem"></a>

El *área de memoria de trabajo* contiene datos temporales para las consultas que ejecutan ordenaciones y hashes. Por ejemplo, una consulta con una cláusula `ORDER BY` ejecuta una ordenación. Las consultas utilizan tablas hash en uniones hash y agregaciones.

El parámetro `work_mem` indica la cantidad de memoria que se utilizará en las operaciones internas de ordenación y en las tablas hash antes de escribir en los archivos temporales del disco, medido en megabytes. El valor predeterminado es 4 MB. Se pueden ejecutar varias sesiones simultáneamente, y cada sesión puede ejecutar operaciones de mantenimiento en paralelo. Por esta razón, la memoria de trabajo total utilizada puede ser múltiplo del parámetro `work_mem`. 

### Área de memoria de trabajo de mantenimiento
<a name="PostgreSQL.Tuning.concepts.local.maintenance_work_mem"></a>

El *área de memoria de trabajo de mantenimiento* almacena en caché los datos de las operaciones de mantenimiento. Estas operaciones incluyen el vaciado, creación de un índice y adición de claves externas.

El parámetro `maintenance_work_mem` especifica la cantidad máxima de memoria que utilizarán las operaciones de mantenimiento, medido en megabytes. El valor predeterminado es 64 MB. Una sesión de base de datos solo puede ejecutar una operación de mantenimiento a la vez.

### Área de búfer temporal
<a name="PostgreSQL.Tuning.concepts.temp"></a>

El *área de búfer temporal* almacena en caché las tablas temporales de cada sesión de la base de datos.

Cada sesión asigna búferes temporales según sea necesario hasta el límite que se especifique. Cuando finaliza la sesión, el servidor borra los búferes.

El parámetro `temp_buffers` establece el número máximo de búferes temporales utilizados por cada sesión, medido en megabytes. El valor predeterminado es 8 MB. Antes del primer uso de las tablas temporales dentro de una sesión, puede cambiar el valor de `temp_buffers`.

# Procesos de RDS para PostgreSQL
<a name="PostgreSQL.Tuning.concepts.processes"></a>

RDS para PostgreSQL utiliza varios procesos.

**Topics**
+ [

## Proceso de administrador de correos
](#PostgreSQL.Tuning.concepts.postmaster)
+ [

## Procesos de backend
](#PostgreSQL.Tuning.concepts.backend)
+ [

## Procesos en segundo plano
](#PostgreSQL.Tuning.concepts.vacuum)

## Proceso de administrador de correos
<a name="PostgreSQL.Tuning.concepts.postmaster"></a>

El *proceso de administrador de correos* es el primer proceso que se ejecuta cuando se inicia RDS para PostgreSQL. El proceso de administrador de correos tiene las siguientes funciones principales:
+ Bifurcar y monitorear los procesos en segundo plano
+ Recibir solicitudes de autenticación de los procesos cliente, y autenticarlos antes de permitir que la base de datos atienda las solicitudes

## Procesos de backend
<a name="PostgreSQL.Tuning.concepts.backend"></a>

Si el administrador de correos autentica una solicitud de cliente, el administrador de correos bifurca un nuevo proceso de backend, también llamado proceso postgres. Un proceso cliente se conecta exactamente a un proceso backend. El proceso cliente y el proceso backend se comunican directamente sin la intervención del proceso de administrador de correos.

## Procesos en segundo plano
<a name="PostgreSQL.Tuning.concepts.vacuum"></a>

El proceso de administrador de correos bifurca varios procesos que ejecutan distintas tareas de backend. Algunas de las más importantes son las siguientes:
+ Escritor de WAL

  RDS para PostgreSQL escribe datos en el búfer WAL (registro de escritura anticipada) en los archivos de registro. El principio del registro por adelantado es que la base de datos no puede escribir los cambios en los archivos de datos hasta que la base de datos escriba los registros que describen esos cambios en el disco. El mecanismo de WAL reduce la E/S del disco y permite a RDS para PostgreSQL utilizar los registros para recuperar la base de datos en caso de error.
+ Escritor en segundo plano

  Este proceso escribe de forma periódica las páginas sucias (modificadas) desde los búferes de memoria a los archivos de datos. Una página se vuelve sucia cuando un proceso de backend la modifica en la memoria.
+ Daemon de autovacuum

  El daemon consta de lo siguiente:
  + El iniciador de autovacuum
  + Los procesos de trabajo de autovacuum

  Cuando autovacuum está activado busca las tablas en las que se ha insertado, actualizado o eliminado un número elevado de tuplas. El daemon tiene las siguientes responsabilidades:
  + Recuperar o reutilizar el espacio de disco ocupado por las filas actualizadas o eliminadas
  + Actualizar las estadísticas utilizadas por el planificador
  + Proteger contra la pérdida de datos antiguos debido al reinicio del ID de transacción

  La característica de autovacuum automatiza la ejecución de los comandos `VACUUM` y `ANALYZE`. `VACUUM` tiene las siguientes variantes: estándar y completo. El vacío estándar se ejecuta en paralelo con otras operaciones de la base de datos. `VACUUM FULL` requiere un bloqueo exclusivo sobre la tabla en la que se trabaja. Por lo tanto, no puede ejecutarse en paralelo con operaciones que acceden a la misma tabla. `VACUUM` crea una cantidad considerable de tráfico de E/S, lo que puede causar un bajo rendimiento para otras sesiones activas.

# Eventos de espera de RDS para PostgreSQL
<a name="PostgreSQL.Tuning.concepts.summary"></a>

La siguiente tabla enumera los eventos de espera de RDS para PostgreSQL que suelen indicar problemas de rendimiento, y resume las causas más comunes y las acciones correctivas.


| Evento de espera | Definición | 
| --- | --- | 
|  [Client:ClientRead](wait-event.clientread.md)  |  Este evento ocurre cuando RDS para PostgreSQL espera recibir datos del cliente.  | 
|  [Client:ClientWrite](wait-event.clientwrite.md)  |  Este evento ocurre cuando RDS para PostgreSQL espera escribir datos en el cliente.  | 
|  [CPU](wait-event.cpu.md)  | Este evento ocurre cuando un subproceso está activo en la CPU o espera por la CPU.  | 
|  [IO:BufFileRead y IO:BufFileWrite](wait-event.iobuffile.md)  |  Los eventos ocurren cuando RDS para PostgreSQL crean archivos temporales.  | 
|  [IO:DataFileRead](wait-event.iodatafileread.md)  |  Este evento ocurre cuando una conexión espera en un proceso backend para leer una página requerida desde el almacenamiento porque la página no está disponible en la memoria compartida.   | 
| [IO:WALWrite](wait-event.iowalwrite.md)  | Este evento ocurre cuando RDS para PostgreSQL está esperando a que se escriban los búferes del registro de escritura anticipada (WAL) en un archivo WAL.  | 
|  [Lock:advisory](wait-event.lockadvisory.md)  |  Este evento ocurre cuando una aplicación PostgreSQL utiliza un bloqueo para coordinar la actividad en varias sesiones.  | 
|  [Lock:extend](wait-event.lockextend.md) |  Este evento ocurre cuando un proceso backend espera bloquear una relación para ampliarla mientras otro proceso tiene un bloqueo en esa relación para el mismo propósito.  | 
|  [Lock:Relation](wait-event.lockrelation.md)  |  Este evento ocurre cuando una consulta espera adquirir un bloqueo en una tabla o vista que está actualmente bloqueada por otra transacción.  | 
|  [Lock:transactionid](wait-event.locktransactionid.md)  | Este evento ocurre cuando una transacción espera un bloqueo a nivel de fila. | 
|  [Lock:tuple](wait-event.locktuple.md)  |  Este evento ocurre cuando un proceso de backend espera adquirir un bloqueo en una tupla.  | 
|  [LWLock:BufferMapping (LWLock:buffer\$1mapping)](wait-event.lwl-buffer-mapping.md)  |  Este evento se produce cuando una sesión espera asociar un bloque de datos con un búfer en el grupo de búferes compartidos.  | 
|  [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)  |  El evento ocurre cuando RDS para PostgreSQL espera que otros procesos terminen sus operaciones de entrada/salida (E/S) cuando intentan acceder a una página de forma simultánea.  | 
|  [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)  |  Este evento ocurre cuando una sesión espera leer o escribir una página de datos en la memoria mientras otra sesión bloquea esa página para la escritura.  | 
|  [LWLock:lock\$1manager (LWLock:lockmanager)](wait-event.lw-lock-manager.md)  | Este evento ocurre cuando el motor de RDS para PostgreSQL mantiene el área de memoria del bloqueo compartido para asignar, verificar y desasignar un bloqueo cuando no es posible un bloqueo de ruta rápida. | 
|  [LWLock:SubtransSLRU (LWLock:SubtransControlLock)](wait-event.lwlocksubtransslru.md)  |  Este evento se produce cuando un proceso está esperando para acceder a la caché simple de uso menos reciente (SLRU) para una subtransacción.  | 
|  [Timeout:PgSleep](wait-event.timeoutpgsleep.md)  |  Este evento ocurre cuando un proceso del servidor llamó a la función `pg_sleep` y espera que el tiempo de espera expire.   | 
|  [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)  | Este evento indica que el proceso de vacío está en reposo porque se ha alcanzado el límite de costo estimado.  | 

# Client:ClientRead
<a name="wait-event.clientread"></a>

El evento `Client:ClientRead` ocurre cuando RDS para PostgreSQL espera recibir datos del cliente.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.clientread.context.supported)
+ [

## Contexto
](#wait-event.clientread.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.clientread.causes)
+ [

## Acciones
](#wait-event.clientread.actions)

## Versiones del motor admitidas
<a name="wait-event.clientread.context.supported"></a>

Esta información de eventos de espera es compatible con RDS para PostgreSQL versión 10 y posteriores.

## Contexto
<a name="wait-event.clientread.context"></a>

Una instancia de base de datos de RDS para PostgreSQL espera recibir datos del cliente. La instancia de la base de datos de RDS para PostgreSQL tiene que recibir los datos del cliente antes de poder enviar más datos al cliente. El tiempo que la instancia espera antes de recibir los datos del cliente es un evento `Client:ClientRead`.

## Causas probables del aumento de las esperas
<a name="wait-event.clientread.causes"></a>

Las causas más comunes para que el evento `Client:ClientRead` aparezca en el máximo de esperas son las siguientes: 

**Aumento de la latencia de la red**  
Puede haber un aumento de la latencia de la red entre la instancia de la base de datos de RDS para PostgreSQL y el cliente. Una mayor latencia de la red aumenta el tiempo necesario para que la instancia de base de datos reciba los datos del cliente.

**Aumento de la carga en el cliente**  
Puede haber presión de la CPU o saturación de la red en el cliente. Un aumento de la carga en el cliente puede retrasar la transmisión de datos desde el cliente a la instancia de la base de datos de RDS para PostgreSQL.

**Excesivos viajes de ida y vuelta de la red**  
Un gran número de viajes de ida y vuelta de la red entre la instancia de la base de datos de RDS para PostgreSQL y el cliente puede retrasar la transmisión de datos del cliente a la instancia de la base de datos de RDS para PostgreSQL.

**Operación de copia grande**  
Durante una operación de copia, los datos se transfieren desde el sistema de archivos del cliente a la instancia de la base de datos de RDS para PostgreSQL. El envío de una gran cantidad de datos a la instancia de la base de datos puede retrasar la transmisión de datos del cliente a la instancia de la base de datos.

**Conexión de cliente inactivo**  
Cuando un cliente se conecta a la instancia de la base de datos de RDS para PostgreSQL en un estado `idle in transaction`, la instancia de la base de datos puede esperar a que el cliente envíe más datos o emita un comando. Una conexión en este estado puede conducir a un aumento de eventos `Client:ClientRead`.

**PgBouncer se utiliza para la agrupación de conexiones**  
PgBouncer tiene un ajuste de configuración de red de bajo nivel llamado `pkt_buf`, que se establece en 4.096 de forma predeterminada. Si la carga de trabajo envía paquetes de consulta de más de 4096 bytes a través de PgBouncer, recomendamos aumentar la configuración de `pkt_buf` a 8192. Si la nueva configuración no disminuye el número de eventos `Client:ClientRead`, recomendamos aumentar la configuración de `pkt_buf` a valores mayores, como 16 384 o 32 768. Si el texto de la consulta es grande, el ajuste más grande puede ser particularmente útil.

## Acciones
<a name="wait-event.clientread.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Colocar los clientes en la misma zona de disponibilidad y subred VPC que el evento de espera
](#wait-event.clientread.actions.az-vpc-subnet)
+ [

### Escalar el cliente
](#wait-event.clientread.actions.scale-client)
+ [

### Utilizar las instancias de generación actual
](#wait-event.clientread.actions.db-instance-class)
+ [

### Aumentar el ancho de banda de la red
](#wait-event.clientread.actions.increase-network-bandwidth)
+ [

### Monitorear los máximos de rendimiento de la red
](#wait-event.clientread.actions.monitor-network-performance)
+ [

### Monitorear las transacciones en el estado “inactivo en la transacción”
](#wait-event.clientread.actions.check-idle-in-transaction)

### Colocar los clientes en la misma zona de disponibilidad y subred VPC que el evento de espera
<a name="wait-event.clientread.actions.az-vpc-subnet"></a>

Para reducir la latencia de la red y aumentar su rendimiento, coloque los clientes en la misma zona de disponibilidad y subred de nube privada virtual (VPC) que la instancia de la base de datos de RDS para PostgreSQL. Asegúrese de que los clientes estén lo más cerca posible desde el punto de vista geográfico de la instancia de la base de datos.

### Escalar el cliente
<a name="wait-event.clientread.actions.scale-client"></a>

Con Amazon CloudWatch u otras métricas del anfitrión, determine si su cliente está actualmente limitado por la CPU o el ancho de banda de la red, o ambos. Si el cliente está restringido, escale su cliente en forma adecuada.

### Utilizar las instancias de generación actual
<a name="wait-event.clientread.actions.db-instance-class"></a>

En algunos casos, es posible que no utilice una clase de instancia de base de datos que admita tramas gigantes. Si ejecuta la aplicación en Amazon EC2, considere la posibilidad de utilizar una instancia de generación actual para el cliente. Además, configure la unidad de transmisión máxima (MTU) en el sistema operativo del cliente. Esta técnica podría reducir el número de viajes de ida y vuelta de la red y aumentar el rendimiento de la red. Para obtener más información, consulte [Tramas gigantes (MTU 9001)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) en la *Guía del usuario de Amazon EC2*.

Para obtener información acerca de las clases de instancia de base de datos, consulte [Clases de instancia de base de datos de ](Concepts.DBInstanceClass.md). Para determinar la clase de instancia de base de datos que equivale a un tipo de instancia de Amazon EC2, coloque `db.` antes del nombre del tipo de instancia de Amazon EC2. Por ejemplo, la instancia de Amazon EC2 `r5.8xlarge` equivale a la clase de instancia de base de datos `db.r5.8xlarge`.

### Aumentar el ancho de banda de la red
<a name="wait-event.clientread.actions.increase-network-bandwidth"></a>

Utilice las métricas de Amazon CloudWatch de `NetworkReceiveThroughput` y `NetworkTransmitThroughput` para monitorear el tráfico de red entrante y saliente en la instancia de la base de datos. Estas métricas pueden ayudarle a determinar si el ancho de banda de la red es suficiente para su carga de trabajo. 

Si el ancho de banda de su red no es suficiente, auméntelo. Si el cliente de AWS o la instancia de base de datos alcanza los límites del ancho de banda de la red, la única forma de aumentar el ancho de banda es aumentar el tamaño de la instancia de base de datos. Para obtener más información, consulte [Tipos de clase de instancia de base de datos](Concepts.DBInstanceClass.Types.md).

Para obtener más información acerca de las métricas de CloudWatch, consulte [Métricas de Amazon CloudWatch para Amazon RDS](rds-metrics.md). 

### Monitorear los máximos de rendimiento de la red
<a name="wait-event.clientread.actions.monitor-network-performance"></a>

Si utiliza clientes de Amazon EC2, Amazon EC2 proporciona límites máximos para las métricas de rendimiento de la red, incluido el ancho de banda de red entrante y saliente agregado. También proporciona un seguimiento de la conexión para garantizar que los paquetes se devuelven como se espera y el acceso a los servicios de enlace local para servicios como el sistema de nombres de dominio (DNS). Para monitorear estos máximos, utilice un controlador de red mejorado actual y monitoree el rendimiento de la red para su cliente. 

Para obtener más información, consulte [Monitorear el rendimiento de la red de la instancia de Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html) en la *Guía del usuario de Amazon EC2* y [Monitorear el rendimiento de la red de la instancia de Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/monitoring-network-performance-ena.html) en la *Guía del usuario de Amazon EC2*.

### Monitorear las transacciones en el estado “inactivo en la transacción”
<a name="wait-event.clientread.actions.check-idle-in-transaction"></a>

Verifique si tiene un número creciente de conexiones `idle in transaction`. Para ello, monitoree la columna `state` en la tabla `pg_stat_activity`. Es posible que pueda identificar el origen de la conexión si ejecuta una consulta similar a la siguiente.

```
select client_addr, state, count(1) from pg_stat_activity 
where state like 'idle in transaction%' 
group by 1,2 
order by 3 desc
```

# Client:ClientWrite
<a name="wait-event.clientwrite"></a>

El evento `Client:ClientWrite` ocurre cuando RDS para PostgreSQL espera escribir datos en el cliente.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.clientwrite.context.supported)
+ [

## Contexto
](#wait-event.clientwrite.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.clientwrite.causes)
+ [

## Acciones
](#wait-event.clientwrite.actions)

## Versiones del motor admitidas
<a name="wait-event.clientwrite.context.supported"></a>

Esta información de eventos de espera es compatible con RDS para PostgreSQL versión 10 y posteriores.

## Contexto
<a name="wait-event.clientwrite.context"></a>

Un proceso cliente debe leer todos los datos recibidos de un clúster de la base de datos de RDS para PostgreSQL antes de que el clúster pueda enviar más datos. El tiempo que el clúster espera antes de enviar más datos al cliente es un evento `Client:ClientWrite`.

La reducción del rendimiento de la red entre la instancia de base de datos de RDS para PostgreSQL y el cliente puede causar este evento. La presión de la CPU y la saturación de la red en el cliente también pueden causar este evento. La *presión de la CPU* es cuando la CPU se utiliza por completo y hay tareas esperando por el tiempo de la CPU. La *saturación de la red* es cuando la red entre la base de datos y el cliente transporta más datos de los que puede manejar. 

## Causas probables del aumento de las esperas
<a name="wait-event.clientwrite.causes"></a>

Las causas más comunes para que el evento `Client:ClientWrite` aparezca en el máximo de esperas son las siguientes: 

**Aumento de la latencia de la red**  
Puede haber un aumento de la latencia de la red entre la instancia de la base de datos de RDS para PostgreSQL y el cliente. Una mayor latencia de la red aumenta el tiempo necesario para que el cliente reciba los datos.

**Aumento de la carga en el cliente**  
Puede haber presión de la CPU o saturación de la red en el cliente. Un aumento de la carga en el cliente retrasa la recepción de los datos de la instancia de la base de datos de RDS para PostgreSQL.

**Gran volumen de datos enviados al cliente**  
La instancia de la base de datos de RDS para PostgreSQL puede estar enviando una gran cantidad de datos al cliente. Es posible que el cliente no pueda recibir los datos tan rápido como el clúster los envía. Actividades como una copia de una tabla grande pueden resultar en un aumento de eventos `Client:ClientWrite`.

## Acciones
<a name="wait-event.clientwrite.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Coloque los clientes en la misma zona de disponibilidad y subred VPC que el clúster
](#wait-event.clientwrite.actions.az-vpc-subnet)
+ [

### Utilizar las instancias de generación actual
](#wait-event.clientwrite.actions.db-instance-class)
+ [

### Reducir la cantidad de datos enviados al cliente
](#wait-event.clientwrite.actions.reduce-data)
+ [

### Escale el cliente
](#wait-event.clientwrite.actions.scale-client)

### Coloque los clientes en la misma zona de disponibilidad y subred VPC que el clúster
<a name="wait-event.clientwrite.actions.az-vpc-subnet"></a>

Para reducir la latencia de la red y aumentar su rendimiento, coloque los clientes en la misma zona de disponibilidad y subred de nube privada virtual (VPC) que la instancia de la base de datos de RDS para PostgreSQL.

### Utilizar las instancias de generación actual
<a name="wait-event.clientwrite.actions.db-instance-class"></a>

En algunos casos, es posible que no utilice una clase de instancia de base de datos que admita tramas gigantes. Si ejecuta la aplicación en Amazon EC2, considere la posibilidad de utilizar una instancia de generación actual para el cliente. Además, configure la unidad de transmisión máxima (MTU) en el sistema operativo del cliente. Esta técnica podría reducir el número de viajes de ida y vuelta de la red y aumentar el rendimiento de la red. Para obtener más información, consulte [Tramas gigantes (MTU 9001)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) en la *Guía del usuario de Amazon EC2*.

Para obtener información acerca de las clases de instancia de base de datos, consulte [Clases de instancia de base de datos de ](Concepts.DBInstanceClass.md). Para determinar la clase de instancia de base de datos que equivale a un tipo de instancia de Amazon EC2, coloque `db.` antes del nombre del tipo de instancia de Amazon EC2. Por ejemplo, la instancia de Amazon EC2 `r5.8xlarge` equivale a la clase de instancia de base de datos `db.r5.8xlarge`.

### Reducir la cantidad de datos enviados al cliente
<a name="wait-event.clientwrite.actions.reduce-data"></a>

Cuando sea posible, ajuste la aplicación para reducir la cantidad de datos que la instancia de la base de datos de RDS para PostgreSQL envía al cliente. Hacer estos ajustes reduce la contención de la CPU y de la red en el cliente.

### Escale el cliente
<a name="wait-event.clientwrite.actions.scale-client"></a>

Con Amazon CloudWatch u otras métricas del anfitrión, determine si su cliente está actualmente limitado por la CPU o el ancho de banda de la red, o ambos. Si el cliente está restringido, escale su cliente en forma adecuada.

# CPU
<a name="wait-event.cpu"></a>

Este evento ocurre cuando un subproceso está activo en la CPU o espera por la CPU.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.cpu.context.supported)
+ [

## Contexto
](#wait-event.cpu.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.cpu.causes)
+ [

## Acciones
](#wait-event.cpu.actions)

## Versiones del motor admitidas
<a name="wait-event.cpu.context.supported"></a>

Esta información de eventos de espera es relevante para todas las versiones de RDS para PostgreSQL.

## Contexto
<a name="wait-event.cpu.context"></a>

La *unidad de procesamiento central (CPU)* es el componente de un ordenador que ejecuta instrucciones. Por ejemplo, las instrucciones de la CPU hacen operaciones aritméticas e intercambian datos en la memoria. Si una consulta aumenta el número de instrucciones que ejecuta a través del motor de base de datos, aumenta el tiempo de ejecución de la consulta. La *programación de la CPU* consiste en dar tiempo de CPU a un proceso. La programación es orquestada por el núcleo del sistema operativo.

**Topics**
+ [

### Cómo saber cuándo se produce esta espera
](#wait-event.cpu.when-it-occurs)
+ [

### Métrica de DBloadCPU
](#wait-event.cpu.context.dbloadcpu)
+ [

### Métrica os.cpuUtilization
](#wait-event.cpu.context.osmetrics)
+ [

### Causa probable de la programación de la CPU
](#wait-event.cpu.context.scheduling)

### Cómo saber cuándo se produce esta espera
<a name="wait-event.cpu.when-it-occurs"></a>

Este evento de espera de `CPU` indica que un proceso del backend se encuentra activo en la CPU o en espera de la misma. Se sabrá que sucede cuando una consulta muestre la siguiente información:
+ La columna `pg_stat_activity.state` tiene el valor `active`.
+ Las columnas `wait_event_type` y `wait_event` en `pg_stat_activity` son `null`.

Para ver los procesos del backend que se encuentran en uso o en espera de CPU, ejecute la siguiente consulta.

```
SELECT * 
FROM   pg_stat_activity
WHERE  state = 'active'
AND    wait_event_type IS NULL
AND    wait_event IS NULL;
```

### Métrica de DBloadCPU
<a name="wait-event.cpu.context.dbloadcpu"></a>

La métrica de Información sobre rendimiento para la CPU es `DBLoadCPU`. El valor de `DBLoadCPU` puede diferir del valor de la métrica `CPUUtilization` de Amazon CloudWatch. Esta última métrica se recopila del hipervisor para una instancia de base de datos.

### Métrica os.cpuUtilization
<a name="wait-event.cpu.context.osmetrics"></a>

Las métricas del sistema operativo de Información sobre rendimiento proporcionan información detallada sobre la utilización de la CPU. Por ejemplo, puede mostrar las siguientes métricas:
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

Información sobre rendimiento informa del uso de la CPU por parte del motor de base de datos como `os.cpuUtilization.nice.avg`.

### Causa probable de la programación de la CPU
<a name="wait-event.cpu.context.scheduling"></a>

 El núcleo del sistema operativo (SO) ejecuta la programación de la CPU. Cuando la CPU está *activa*, es posible que un proceso tenga que esperar para programarse. La CPU está activa mientras realiza los cálculos. También está activa mientras ejecuta un subproceso inactivo, es decir, un subproceso inactivo que espera la E/S de la memoria. Este tipo de E/S domina la carga de trabajo típica de una base de datos. 

Es probable que los procesos esperen a que se programe una CPU cuando se cumplen las siguientes condiciones:
+ La métrica CloudWatch `CPUUtilization` está cerca del 100 por ciento.
+ La carga media es mayor que el número de vCPU, lo que indica una carga pesada. Puede encontrar la métrica `loadAverageMinute` en la sección de métricas del sistema operativo en Información sobre rendimiento.

## Causas probables del aumento de las esperas
<a name="wait-event.cpu.causes"></a>

Cuando el evento de espera de la CPU ocurre más de lo normal, lo que posiblemente indica un problema de rendimiento, las causas típicas pueden ser las siguientes.

**Topics**
+ [

### Causas probables de picos repentinos
](#wait-event.cpu.causes.spikes)
+ [

### Causas probables de alta frecuencia prolongada
](#wait-event.cpu.causes.long-term)
+ [

### Casos aislados
](#wait-event.cpu.causes.corner-cases)

### Causas probables de picos repentinos
<a name="wait-event.cpu.causes.spikes"></a>

Las causas más probables de picos repentinos son las siguientes:
+ La aplicación abrió demasiadas conexiones simultáneas a la base de datos. Este escenario se conoce como “tormenta de conexiones”
+ La carga de trabajo de la aplicación ha cambiado de alguna de las siguientes maneras:
  + Nuevas consultas
  + Un aumento del tamaño del conjunto de datos
  + Mantenimiento o creación de índices
  + Nuevas funciones
  + Nuevos operadores
  + Aumento de la ejecución de consultas en paralelo
+ Los planes de ejecución de sus consultas han cambiado. En algunos casos, un cambio puede provocar un aumento de los búferes. Por ejemplo, la consulta utiliza ahora un escaneo secuencial cuando antes utilizaba un índice. En este caso, las consultas necesitan más CPU para lograr el mismo objetivo.

### Causas probables de alta frecuencia prolongada
<a name="wait-event.cpu.causes.long-term"></a>

Las causas más probables de eventos que se repiten durante un periodo prolongado:
+ Demasiados procesos de backend se ejecutan de forma simultánea en la CPU. Estos procesos pueden llegar a ser procesos de trabajo paralelos.
+ Las consultas tienen un rendimiento subóptimo porque necesitan un gran número de búferes.

### Casos aislados
<a name="wait-event.cpu.causes.corner-cases"></a>

Si ninguna de las causas probables resulta ser la causa real, es posible que se produzcan las siguientes situaciones:
+ La CPU está intercambiando procesos de entrada y salida.
+ La CPU podría gestionar las entradas de la tabla de páginas si se ha desactivado la función de *páginas enormes*. Esta característica de administración de la memoria está habilitada de forma predeterminada para todas las clases de instancias de base de datos que no sean de la clase de instancia de base de datos micro, pequeña y mediana. Para obtener más información, consulte [Páginas enormes para RDS for PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md). 

## Acciones
<a name="wait-event.cpu.actions"></a>

Si el evento de espera de `CPU` domina la actividad de la base de datos, no indica necesariamente un problema de rendimiento. Responda a este evento solo cuando el rendimiento se deteriore.

**Topics**
+ [

### Investigue si la base de datos es la causa del aumento de la CPU
](#wait-event.cpu.actions.db-CPU)
+ [

### Determine si el número de conexiones aumentó
](#wait-event.cpu.actions.connections)
+ [

### Responder a los cambios en la carga de trabajo
](#wait-event.cpu.actions.workload)

### Investigue si la base de datos es la causa del aumento de la CPU
<a name="wait-event.cpu.actions.db-CPU"></a>

Examine la métrica `os.cpuUtilization.nice.avg` en Información sobre rendimiento. Si este valor es mucho menor que el uso de la CPU, los procesos ajenos a la base de datos son los que más contribuyen a la CPU.

### Determine si el número de conexiones aumentó
<a name="wait-event.cpu.actions.connections"></a>

Examine la métrica `DatabaseConnections` en Amazon CloudWatch. La acción a tomar depende de si el número aumentó o disminuyó durante el periodo de aumento de los eventos de espera de la CPU.

#### Las conexiones aumentaron
<a name="wait-event.cpu.actions.connections.increased"></a>

Si el número de conexiones aumentó, compare el número de procesos de backend que consumen CPU con el número de vCPU. Los siguientes escenarios son posibles:
+ El número de procesos de backend que consumen CPU es menor que el número de vCPU.

  En este caso, el número de conexiones no es un problema. Sin embargo, puede intentar reducir la utilización de la CPU.
+ El número de procesos de backend que consumen CPU es mayor que el número de vCPU.

  En este caso, considere las siguientes opciones:
  + Disminuya el número de procesos backend conectados a la base de datos. Por ejemplo, implemente una solución de agrupación de conexiones, como el proxy RDS. Para obtener más información, consulte [Amazon RDS Proxy ](rds-proxy.md).
  + Actualice el tamaño de su instancia para obtener un mayor número de vCPU.
  + Redirija algunas cargas de trabajo de solo lectura a nodos lectores, si procede.

#### Las conexiones no aumentaron
<a name="wait-event.cpu.actions.connections.decreased"></a>

Examine las métricas de `blks_hit` en Información sobre rendimiento. Busque una correlación entre el aumento de `blks_hit` y el uso de la CPU. Los siguientes escenarios son posibles:
+ El uso de la CPU y `blks_hit` están correlacionados.

  En este caso, encuentre las principales instrucciones SQL que están relacionadas con el uso de la CPU y busque los cambios de plan. Puede utilizar cualquiera de las siguientes técnicas:
  + Explicar los planes manualmente y compararlos con el plan de ejecución esperado.
  + Buscar un aumento en los aciertos de bloque por segundo y en los aciertos de bloque local por segundo. En la sección **Top SQL** (SQL principal) del panel de Información sobre rendimiento, elija **Preferences** (Preferencias).
+ El uso de la CPU y `blks_hit` no están correlacionados.

  En este caso, determine si se produce alguna de las siguientes situaciones:
  + La aplicación se conecta y desconecta con rapidez de la base de datos. 

    Diagnostique este comportamiento mediante la activación de `log_connections` y `log_disconnections`, y luego analice los registros de PostgreSQL. Considere utilizar el analizador de registros `pgbadger`. Para obtener más información, consulte [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger).
  + El sistema operativo está sobrecargado.

    En este caso, Información sobre rendimiento muestra que los procesos del backend consumen la CPU durante más tiempo del habitual. Busque pruebas en las métricas de Información sobre rendimiento `os.cpuUtilization` o en la métrica CloudWatch `CPUUtilization`. Si el sistema operativo está sobrecargado, consulte las métricas de Monitoreo mejorado para hacer un diagnóstico más profundo. Específicamente, observe la lista de procesos y el porcentaje de CPU que consume cada proceso.
  + Las instrucciones SQL más importantes son las que consumen demasiada CPU.

    Examine las instrucciones que se relacionan con el uso de la CPU para ver si pueden utilizar menos CPU. Ejecute un comando `EXPLAIN`, y céntrese en los nodos del plan que tienen el mayor impacto. Considere utilizar un visualizador de planes de ejecución de PostgreSQL. Para probar esta herramienta, consulte [http://explain.dalibo.com/](http://explain.dalibo.com/).

### Responder a los cambios en la carga de trabajo
<a name="wait-event.cpu.actions.workload"></a>

Si la carga de trabajo cambió, busque los siguientes tipos de cambios:

Nuevas consultas  
Verifique si las nuevas consultas son las esperadas. Si es así, asegúrese de que los planes de ejecución y el número de ejecuciones por segundo son los esperados.

Aumento del tamaño del conjunto de datos  
Determine si la partición, si no se ha implementado todavía, podría ayudar. Esta estrategia podrá reducir el número de páginas que debe recuperar una consulta.

Mantenimiento o creación de índices  
Verifique si el programa de mantenimiento es el previsto. Una práctica recomendada es programar las actividades de mantenimiento fuera de los picos de actividad.

Nuevas funciones  
Verifique si estas funciones se comportan como se espera durante las pruebas. En concreto, verifique si el número de ejecuciones por segundo es el esperado.

Nuevos operadores  
Verifique si su rendimiento es el esperado durante las pruebas.

Aumento de la ejecución de consultas paralelas  
Determine si se ha producido alguna de las siguientes situaciones:  
+ Las relaciones o los índices implicados han crecido repentinamente en tamaño de modo que difieren significativamente de `min_parallel_table_scan_size` o `min_parallel_index_scan_size`.
+ Se hicieron cambios recientes en `parallel_setup_cost` o `parallel_tuple_cost`.
+ Se hicieron cambios recientes en `max_parallel_workers` o `max_parallel_workers_per_gather`.

# IO:BufFileRead y IO:BufFileWrite
<a name="wait-event.iobuffile"></a>

Los eventos `IO:BufFileRead` e `IO:BufFileWrite` ocurren cuando RDS para PostgreSQL crea archivos temporales. Cuando las operaciones requieren más memoria de la que los parámetros de la memoria de trabajo definen actualmente, escriben datos temporales en el almacenamiento persistente. Esta operación se llama a veces *derramamiento en el disco*. Para obtener más información sobre los archivos temporales y su uso, consulte [Administración de archivos temporales con PostgreSQL](PostgreSQL.ManagingTempFiles.md).

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.iobuffile.context.supported)
+ [

## Contexto
](#wait-event.iobuffile.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.iobuffile.causes)
+ [

## Acciones
](#wait-event.iobuffile.actions)

## Versiones del motor admitidas
<a name="wait-event.iobuffile.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Contexto
<a name="wait-event.iobuffile.context"></a>

`IO:BufFileRead` e `IO:BufFileWrite` se relacionan con el área de memoria de trabajo y el área de memoria de trabajo de mantenimiento. Para obtener más información acerca de estas áreas de memoria locales, consulte el punto [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) (Consumo de recursos) en la documentación de PostgreSQL.

El valor predeterminado de `work_mem` es de 4 MB. Si una sesión ejecuta operaciones en paralelo, cada proceso de trabajo que maneja el paralelismo utiliza 4 MB de memoria. Por esta razón, configure `work_mem` con cuidado. Si el valor es demasiado alto, una base de datos con muchas sesiones puede consumir demasiada memoria. Si establece el valor demasiado bajo, RDS para PostgreSQL crea archivos temporales en el almacenamiento local. La E/S del disco para estos archivos temporales puede reducir el rendimiento.

Si se observa la siguiente secuencia de eventos, es posible que la base de datos genere archivos temporales:

1. Disminución repentina y brusca de la disponibilidad

1. Recuperación rápida del espacio libre

También puede observar un patrón de “motosierra”. Este patrón puede indicar que la base de datos crea archivos pequeños de forma constante.

## Causas probables del aumento de las esperas
<a name="wait-event.iobuffile.causes"></a>

En general, estos eventos de espera son causados por operaciones que consumen más memoria de la que asignan los parámetros `work_mem` o `maintenance_work_mem`. Para compensar, las operaciones se escriben en archivos temporales. Las causas más comunes de los eventos `IO:BufFileRead` y `IO:BufFileWrite` son las siguientes:

**Consultas que necesitan más memoria de la que existe en la zona de memoria de trabajo**  
Las consultas con las siguientes características utilizan el área de memoria de trabajo:  
+ Combinaciones hash
+ `ORDER BY`Cláusula 
+ `GROUP BY`Cláusula 
+ `DISTINCT`
+ Funciones de ventana
+ `CREATE TABLE AS SELECT`
+ Actualización de la vista materializada

**Instrucciones que necesitan más memoria de la que existe en el área de memoria de trabajo de mantenimiento**  
Las siguientes instrucciones utilizan el área de memoria de trabajo de mantenimiento:  
+ `CREATE INDEX`
+ `CLUSTER`

## Acciones
<a name="wait-event.iobuffile.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Identifique el problema
](#wait-event.iobuffile.actions.problem)
+ [

### Examine sus consultas de unión (join)
](#wait-event.iobuffile.actions.joins)
+ [

### Examinar las consultas ORDER BY y GROUP BY
](#wait-event.iobuffile.actions.order-by)
+ [

### Evite utilizar la operación DISTINCT
](#wait-event.iobuffile.actions.distinct)
+ [

### Considere la posibilidad de utilizar funciones de ventana en lugar de funciones GROUP BY
](#wait-event.iobuffile.actions.window)
+ [

### Investigar las vistas materializadas y las instrucciones CTA
](#wait-event.iobuffile.actions.mv-refresh)
+ [

### Utilizar pg\$1repack al reconstruir índices
](#wait-event.iobuffile.actions.pg_repack)
+ [

### Aumentar maintenance\$1work\$1mem al hacer un clúster de tablas
](#wait-event.iobuffile.actions.cluster)
+ [

### Ajustar la memoria para evitar IO:BufFileRead e IO:BufFileWrite
](#wait-event.iobuffile.actions.tuning-memory)

### Identifique el problema
<a name="wait-event.iobuffile.actions.problem"></a>

Puede ver el uso de archivos temporales directamente en información de rendimiento. Para obtener más información, consulte [Visualización del uso de archivos temporales con Información de rendimiento](PostgreSQL.ManagingTempFiles.Example.md). Cuando la información de rendimiento está desactivada, es posible que observe un aumento de las operaciones `IO:BufFileRead` e `IO:BufFileWrite`.

Para identificar el origen del problema, puede configurar el parámetro `log_temp_files` para registrar todas las consultas que generen más KB de archivos temporales que el umbral especificado. De forma predeterminada, `log_temp_files` se establece en `-1`, lo que desactiva esta función de registro. Si establece este parámetro como `0`, RDS para PostgreSQL registra todos los archivos temporales. Si lo establece en `1024`, RDS para PostgreSQL registra todas las consultas que produzcan archivos temporales de más de 1 MB. Para más información sobre `log_temp_files`, consulte [Error Reporting and Logging](https://www.postgresql.org/docs/current/runtime-config-logging.html) en la documentación de PostgreSQL.

### Examine sus consultas de unión (join)
<a name="wait-event.iobuffile.actions.joins"></a>

Es probable que la consulta utilice combinaciones. Por ejemplo, la siguiente consulta une cuatro tablas.

```
SELECT * 
       FROM "order" 
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = order.customer_id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

Una posible causa de los picos de uso de archivos temporales es un problema en la propia consulta. Por ejemplo, una cláusula rota podría no filtrar las uniones correctamente. Considere la segunda unión interna en el siguiente ejemplo.

```
SELECT * 
       FROM "order"
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = customer.id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

La consulta anterior une por error `customer.id` con `customer.id`, lo que genera un producto cartesiano entre cada cliente y cada pedido. Este tipo de unión accidental genera grandes archivos temporales. Según el tamaño de las tablas, una consulta cartesiana puede incluso llenar el almacenamiento. Es posible que la aplicación tenga uniones cartesianas cuando se den las siguientes condiciones:
+ Se observan grandes y bruscas disminuciones en la disponibilidad del almacenamiento, seguidas de una rápida recuperación.
+ No se crean índices.
+ No se emiten instrucciones `CREATE TABLE FROM SELECT`.
+ No se actualizan las vistas materializadas.

Para ver si las tablas se unen con las claves adecuadas, inspeccione las directivas de consulta y de asignación objeto-relacional. Tenga en cuenta que algunas consultas de la aplicación no se llaman todo el tiempo, y algunas consultas se generan de forma dinámica.

### Examinar las consultas ORDER BY y GROUP BY
<a name="wait-event.iobuffile.actions.order-by"></a>

En algunos casos, una cláusula `ORDER BY` puede dar lugar a un exceso de archivos temporales. Tenga en cuenta estas directrices:
+ Incluya las columnas en una cláusula `ORDER BY` solo cuando sea necesario ordenarlas. Esta directriz es especialmente importante para las consultas que devuelven miles de filas y especifican muchas columnas en la cláusula `ORDER BY`.
+ Considere la posibilidad de crear índices para acelerar las cláusulas `ORDER BY` cuando coincidan con columnas que tengan el mismo orden ascendente o descendente. Los índices parciales son preferibles porque son más pequeños. Los índices más pequeños se leen y recorren más rápidamente.
+ Si crea índices para columnas que pueden aceptar valores nulos, considere si quiere que los valores nulos se almacenen al final o al principio de los índices.

  Si es posible, reduzca el número de filas que hay que ordenar, mediante el filtrado del conjunto de resultados. Si utiliza instrucciones de la cláusula `WITH` o subconsultas, recuerde que una consulta interna genera un conjunto de resultados y lo pasa a la consulta externa. Cuantas más filas pueda filtrar una consulta, menos tendrá que ordenar esta última.
+ Si no necesita obtener el conjunto de resultados completo, utilice la cláusula `LIMIT`. Por ejemplo, si solo quiere las cinco primeras filas, una consulta que utilice la cláusula `LIMIT` no sigue generando resultados. De este modo, la consulta requiere menos memoria y archivos temporales.

Una consulta que utiliza una cláusula `GROUP BY` también puede requerir archivos temporales. Las consultas `GROUP BY` resumen los valores con funciones como las siguientes:
+ `COUNT`
+ `AVG`
+ `MIN`
+ `MAX`
+ `SUM`
+ `STDDEV`

Para ajustar las consultas `GROUP BY`, siga las recomendaciones para las consultas `ORDER BY`.

### Evite utilizar la operación DISTINCT
<a name="wait-event.iobuffile.actions.distinct"></a>

Si es posible, evite utilizar la operación `DISTINCT` para eliminar las filas duplicadas. Cuantas más filas innecesarias y duplicadas devuelva la consulta, más cara será la operación `DISTINCT`. Si es posible, agregue filtros en la cláusula `WHERE`, incluso si utiliza los mismos filtros para diferentes tablas. Filtrar la consulta y unirla correctamente mejora su rendimiento y reduce el uso de recursos. Además, evita que los informes y resultados sean incorrectos.

Si necesita utilizar `DISTINCT` para varias filas de una misma tabla, considere la posibilidad de crear un índice compuesto. Agrupar varias columnas en un índice puede mejorar el tiempo de evaluación de las filas distintas. Además, si utiliza RDS para PostgreSQL versión 10 o posterior, puede correlacionar estadísticas entre varias columnas con el comando `CREATE STATISTICS`.

### Considere la posibilidad de utilizar funciones de ventana en lugar de funciones GROUP BY
<a name="wait-event.iobuffile.actions.window"></a>

Al utilizar `GROUP BY`, se modifica el conjunto de resultados y luego se recupera el resultado agregado. Con las funciones de ventana, se agregan los datos sin cambiar el conjunto de resultados. Una función de ventana utiliza la cláusula `OVER` para efectuar cálculos a través de los conjuntos definidos por la consulta, correlacionando una fila con otra. Puede utilizar todas las funciones `GROUP BY` en las funciones de ventana, pero también puede utilizar funciones como las siguientes:
+ `RANK`
+ `ARRAY_AGG`
+ `ROW_NUMBER`
+ `LAG`
+ `LEAD`

Para minimizar el número de archivos temporales generados por una función de ventana, elimine las duplicaciones para el mismo conjunto de resultados cuando necesite dos agregaciones distintas. Analice la siguiente consulta.

```
SELECT sum(salary) OVER (PARTITION BY dept ORDER BY salary DESC) as sum_salary
     , avg(salary) OVER (PARTITION BY dept ORDER BY salary ASC) as avg_salary
  FROM empsalary;
```

Puede volver a escribir la consulta con la cláusula `WINDOW` de la siguiente manera.

```
SELECT sum(salary) OVER w as sum_salary
         , avg(salary) OVER w as_avg_salary
    FROM empsalary
  WINDOW w AS (PARTITION BY dept ORDER BY salary DESC);
```

De forma predeterminada, el planificador de ejecución de RDS para PostgreSQL consolida nodos similares para no duplicar operaciones. Sin embargo, al utilizar una declaración explícita para el bloque de la ventana, puede actualizar la consulta más fácilmente. También puede mejorar el rendimiento al evitar la duplicación.

### Investigar las vistas materializadas y las instrucciones CTA
<a name="wait-event.iobuffile.actions.mv-refresh"></a>

Cuando una vista materializada se actualiza, ejecuta una consulta. Esta consulta puede contener una operación como `GROUP BY`, `ORDER BY` o `DISTINCT`. Durante una actualización, es posible que observe un gran número de archivos temporales y los eventos de espera `IO:BufFileWrite` e `IO:BufFileRead`. Del mismo modo, cuando se crea una tabla basada en una instrucción `SELECT`, la instrucción `CREATE TABLE` ejecuta una consulta. Para reducir los archivos temporales necesarios, optimice la consulta.

### Utilizar pg\$1repack al reconstruir índices
<a name="wait-event.iobuffile.actions.pg_repack"></a>

Cuando se crea un índice, el motor ordena el conjunto de resultados. A medida que las tablas aumentan de tamaño y los valores de la columna indexada se diversifican, los archivos temporales requieren más espacio. En la mayoría de los casos, no se puede evitar la creación de archivos temporales para tablas grandes sin modificar el área de memoria de trabajo de mantenimiento. Para obtener más información acerca de `maintenance_work_mem`, consulte [https://www.postgresql.org/docs/current/runtime-config-resource.html](https://www.postgresql.org/docs/current/runtime-config-resource.html) en la documentación de PostgreSQL. 

Una posible solución para recrear un índice grande es utilizar la extensión pg\$1repack. Para más información, consulte [Reorganize tables in PostgreSQL databases with minimal locks](https://reorg.github.io/pg_repack/) en la documentación de pg\$1repack. Para obtener información sobre la configuración de la extensión en su instancia de base de datos de RDS para PostgreSQL, consulte [Reducción de la sobrecarga en tablas e índices con la extensión pg\$1repack](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md). 

### Aumentar maintenance\$1work\$1mem al hacer un clúster de tablas
<a name="wait-event.iobuffile.actions.cluster"></a>

El comando `CLUSTER` hace un clúster de la tabla especificada por *table\$1name* basado en un índice existente especificado por *index\$1name*. RDS para PostgreSQL recrea físicamente la tabla para que coincida con el orden de un índice determinado.

Cuando el almacenamiento magnético era frecuente, los clústeres eran comunes porque el rendimiento del almacenamiento era limitado. Ahora que el almacenamiento basado en SSD es común, los clústeres son menos populares. Sin embargo, si se hacen clústeres en las tablas, se puede aumentar ligeramente el rendimiento en función del tamaño de la tabla, índice, consulta, etc. 

Si ejecuta el comando `CLUSTER` y observa los eventos de espera `IO:BufFileWrite` e `IO:BufFileRead`, ajuste `maintenance_work_mem`. Aumente el tamaño de la memoria a una cantidad bastante grande. Un valor alto significa que el motor puede utilizar más memoria para la operación de clusterización.

### Ajustar la memoria para evitar IO:BufFileRead e IO:BufFileWrite
<a name="wait-event.iobuffile.actions.tuning-memory"></a>

En algunas situaciones, es necesario ajustar la memoria. Su objetivo es equilibrar la memoria en las siguientes áreas de consumo mediante los parámetros adecuados, de la siguiente manera.
+ El valor `work_mem` 
+ La memoria restante después de descontar el valor `shared_buffers`
+ El máximo de conexiones abiertas y en uso, que está limitado por `max_connections`

Para obtener más información sobre el ajuste de la memoria, consulte el punto [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) (Consumo de recursos) en la documentación de PostgreSQL. 

#### Aumentar el tamaño del área de memoria de trabajo
<a name="wait-event.iobuffile.actions.tuning-memory.work-mem"></a>

En algunas situaciones, la única opción es aumentar la memoria que utiliza la sesión. Si las consultas están correctamente escritas y se utilizan las claves correctas para las uniones, considere aumentar el valor `work_mem`. 

Para saber cuántos archivos temporales genera una consulta, establezca `log_temp_files` en `0`. Si aumenta el valor de `work_mem` hasta el valor máximo identificado en los registros, evitará que la consulta genere archivos temporales. Sin embargo, `work_mem` establece el máximo por nodo del plan para cada conexión o proceso de trabajo paralelo. Si la base de datos tiene 5000 conexiones, y si cada una utiliza 256 MiB de memoria, el motor necesita 1.2 TiB de RAM. Esto significa que la instancia podría quedarse sin memoria.

#### Reservar suficiente memoria para el grupo de búferes compartidos
<a name="wait-event.iobuffile.actions.tuning-memory.shared-pool"></a>

La base de datos utiliza áreas de memoria como el grupo de búferes compartidos, no solo el área de memoria de trabajo. Tenga en cuenta los requisitos de estas áreas de memoria adicionales antes de aumentar `work_mem`.

Por ejemplo, supongamos que su clase de instancia de RDS para PostgreSQL es db.r5.2xlarge. Esta clase tiene 64 GiB de memoria. De forma predeterminada, el 25 por ciento de la memoria se reserva para el grupo de búferes compartidos. Después de restar la cantidad asignada al área de memoria compartida, quedan 16 384 MB. No asigne la memoria restante exclusivamente al área de memoria de trabajo porque el sistema operativo y el motor también necesitan memoria.

La memoria que puedes asignar a `work_mem` depende de la clase de instancia. Si utiliza una clase de instancia más grande, habrá más memoria disponible. Sin embargo, en el ejemplo anterior, no puedes usar más de 16 GiB. De lo contrario, la instancia dejará de estar disponible cuando se agote la memoria. Para recuperar la instancia del estado no disponible, los servicios de automatización de RDS para PostgreSQL se reinician automáticamente.

#### Administrar el número de conexiones
<a name="wait-event.iobuffile.actions.tuning-memory.connections"></a>

Supongamos que la instancia de su base de datos tiene 5 000 conexiones simultáneas. Cada conexión utiliza al menos 4 MiB de `work_mem`. El alto consumo de memoria de las conexiones puede degradar el rendimiento. Para ello, tiene las siguientes opciones:
+ Actualizar a una clase de instancia mayor.
+ Disminuir el número de conexiones simultáneas a la base de datos mediante el uso de un proxy de conexión o un grupo de conexiones.

En el caso de los proxies, considere Amazon RDS Proxy, pgBouncer o un grupo de conexiones acorde con su aplicación. Esta solución alivia la carga de la CPU. También reduce el riesgo cuando todas las conexiones requieren el área de memoria de trabajo. Cuando hay menos conexiones a la base de datos, puede aumentar el valor de `work_mem`. De esta manera, se reduce la ocurrencia de los eventos de espera `IO:BufFileRead` y `IO:BufFileWrite`. Además, las consultas que esperan el área de memoria de trabajo se aceleran de forma significativa.

# IO:DataFileRead
<a name="wait-event.iodatafileread"></a>

El evento `IO:DataFileRead` ocurre cuando una conexión espera en un proceso backend para leer una página requerida del almacenamiento porque la página no está disponible en la memoria compartida.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.iodatafileread.context.supported)
+ [

## Contexto
](#wait-event.iodatafileread.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.iodatafileread.causes)
+ [

## Acciones
](#wait-event.iodatafileread.actions)

## Versiones del motor admitidas
<a name="wait-event.iodatafileread.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Contexto
<a name="wait-event.iodatafileread.context"></a>

Todas las consultas y operaciones de manipulación de datos (DML) acceden a páginas en el grupo de búferes. Las instrucciones que pueden inducir lecturas incluyen `SELECT`, `UPDATE` y `DELETE`. Por ejemplo, un `UPDATE` puede leer páginas de tablas o índices. Si la página que se solicita o actualiza no está en el grupo de búferes compartidos, esta lectura puede provocar el evento `IO:DataFileRead`.

Dado que el grupo de búferes compartidos es finito, puede llenarse. En este caso, las solicitudes de páginas que no están en la memoria obligan a la base de datos a leer bloques del disco. Si el evento `IO:DataFileRead` se produce con frecuencia, es posible que el grupo de búferes compartidos sea demasiado pequeño para acomodar la carga de trabajo. Este problema se agudiza en las consultas `SELECT` que leen un gran número de filas que no caben en el grupo de búferes. Para obtener más información acerca del grupo de búferes, consulte el punto [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) (Consumo de recursos) en la documentación de PostgreSQL.

## Causas probables del aumento de las esperas
<a name="wait-event.iodatafileread.causes"></a>

Las causas más comunes del evento `IO:DataFileRead` son las siguientes:

**Picos de conexión**  
Es posible que varias conexiones generen el mismo número de eventos de espera IO:DataFileRead. En este caso, puede producirse un pico (aumento repentino y grande) en los eventos `IO:DataFileRead`. 

**Instrucciones SELECT y DML que hacen escaneos secuenciales**  
Es posible que la aplicación realice una nueva operación. O una operación existente podría cambiar debido a un nuevo plan de ejecución. En estos casos, busque las tablas (particularmente las tablas grandes) que tengan un valor de `seq_scan` mayor. Encuéntrelas mediante la consulta de `pg_stat_user_tables`. Para rastrear las consultas que generan más operaciones de lectura, utilice la extensión `pg_stat_statements`.

**CTAS y CREATE INDEX para grandes conjuntos de datos**  
Un *CTAS* es una instrucción `CREATE TABLE AS SELECT`. Si ejecuta un CTAS con un conjunto de datos grande como origen, o crea un índice en una tabla grande, puede producirse el evento `IO:DataFileRead`. Cuando se crea un índice, es posible que la base de datos tenga que leer todo el objeto mediante una exploración secuencial. Un CTAS genera lecturas `IO:DataFile` cuando las páginas no están en la memoria.

**Varios procesos de trabajo de vacío que se ejecutan al mismo tiempo**  
Los procesos de trabajo de vacío pueden activarse de forma manual o automática. Se recomienda adoptar una estrategia de vacío agresiva. Sin embargo, cuando una tabla tiene muchas filas actualizadas o eliminadas, las esperas `IO:DataFileRead` aumentan. Una vez recuperado el espacio, el tiempo de vacío dedicado a `IO:DataFileRead` disminuye.

**Ingesta de grandes cantidades de datos**  
Cuando la aplicación ingiere grandes cantidades de datos, las operaciones `ANALYZE` pueden producirse con mayor frecuencia. El proceso `ANALYZE` se puede activar mediante un desencadenador de autovacuum o invocarse de forma manual.  
La operación `ANALYZE` lee un subconjunto de la tabla. El número de páginas que deben ser escaneadas se calcula al multiplicar 30 por el valor de `default_statistics_target`. Para obtener más información, consulte la [documentación de PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET). El parámetro `default_statistics_target` acepta valores entre 1 y 10 000, siendo el valor por defecto 100.

**Falta de recursos**  
Si el ancho de banda de la red de la instancia o la CPU se consumen, el evento `IO:DataFileRead` podría ocurrir con más frecuencia.

## Acciones
<a name="wait-event.iodatafileread.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Verificar los filtros de predicado para las consultas que generan esperas
](#wait-event.iodatafileread.actions.filters)
+ [

### Minimizar el efecto de las operaciones de mantenimiento
](#wait-event.iodatafileread.actions.maintenance)
+ [

### Responder a un gran número de conexiones
](#wait-event.iodatafileread.actions.connections)

### Verificar los filtros de predicado para las consultas que generan esperas
<a name="wait-event.iodatafileread.actions.filters"></a>

Supongamos que identifica consultas específicas que generan eventos de espera `IO:DataFileRead`. Puede identificarlos con las siguientes técnicas:
+ Información sobre rendimiento
+ Vistas de catálogo como la que proporciona la extensión `pg_stat_statements`
+ La vista de catálogo `pg_stat_all_tables`, si muestra de forma periódica un aumento del número de lecturas físicas
+ La vista `pg_statio_all_tables`, si muestra que los contadores `_read` aumentan

Le recomendamos que determine qué filtros se utilizan en el predicado (cláusula `WHERE`) de estas consultas. Siga estas instrucciones:
+ Ejecute el comando `EXPLAIN`. En la salida, identifique qué tipos de escaneos se utilizan. Un escaneo secuencial no indica necesariamente un problema. Las consultas que utilizan escaneos secuenciales producen naturalmente más eventos `IO:DataFileRead` en comparación con las consultas que utilizan filtros.

  Averigüe si la columna que aparece en la cláusula `WHERE` se encuentra en un índice. Si no es así, considere la posibilidad de crear un índice para esta columna. Este enfoque evita los escaneos secuenciales y reduce los eventos `IO:DataFileRead`. Si una consulta tiene filtros restrictivos y produce aún escaneos secuenciales, evalúe si se utilizan los índices adecuados.
+ Verifique si la consulta tiene acceso a una tabla muy grande. En algunos casos, la partición de una tabla puede mejorar el rendimiento, ya que permite que la consulta solo lea las particiones necesarias.
+ Examine la cardinalidad (número total de filas) de sus operaciones de unión. Tenga en cuenta lo restrictivos que son los valores que se pasan en los filtros de la cláusula `WHERE`. Si es posible, ajuste su consulta para reducir el número de filas que se pasan en cada paso del plan.

### Minimizar el efecto de las operaciones de mantenimiento
<a name="wait-event.iodatafileread.actions.maintenance"></a>

Las operaciones de mantenimiento como `VACUUM` y `ANALYZE` son importantes. Le recomendamos que no las desactive ya que encontrará eventos de espera `IO:DataFileRead` relacionados con estas operaciones de mantenimiento. Los siguientes enfoques pueden minimizar el efecto de estas operaciones:
+ Ejecute las operaciones de mantenimiento de forma manual durante las horas de menor actividad. Esta técnica evita que la base de datos alcance el umbral de las operaciones automáticas.
+ Para tablas muy grandes, considere la posibilidad de particionar la tabla. Esta técnica reduce la sobrecarga de las operaciones de mantenimiento. La base de datos solo accede a las particiones que requieren mantenimiento.
+ Cuando capture grandes cantidades de datos, considere la posibilidad de desactivar la característica de autoanálisis.

La característica de autovacuum se activa de forma automática para una tabla cuando la siguiente fórmula es verdadera.

```
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
```

La vista `pg_stat_user_tables` y el catálogo `pg_class` tienen varias filas. Una fila puede corresponder a una fila de la tabla. Esta fórmula asume que las `reltuples` son para una tabla específica. Los parámetros `autovacuum_vacuum_scale_factor` (0,20 de forma predeterminada) y `autovacuum_vacuum_threshold` (50 tuplas de forma predeterminada) se suelen establecer de forma global para toda la instancia. Sin embargo, puede establecer valores diferentes para una tabla específica.

**Topics**
+ [

#### Buscar tablas que consuman espacio de forma innecesaria
](#wait-event.iodatafileread.actions.maintenance.tables)
+ [

#### Buscar índices que consuman espacio de forma innecesaria
](#wait-event.iodatafileread.actions.maintenance.indexes)
+ [

#### Buscar tablas aptas para autovacuum
](#wait-event.iodatafileread.actions.maintenance.autovacuumed)

#### Buscar tablas que consuman espacio de forma innecesaria
<a name="wait-event.iodatafileread.actions.maintenance.tables"></a>

Para encontrar tablas que consuman espacio innecesariamente, puede utilizar funciones de la extensión `pgstattuple` de PostgreSQL. Esta extensión (módulo) está disponible de forma predeterminada en todas las instancias de base de datos de RDS para PostgreSQL y se puede instanciar en la instancia con el siguiente comando.

```
CREATE EXTENSION pgstattuple;
```

Para obtener más información sobre esta extensión, consulte [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html) en la documentación de PostgreSQL.

Puede comprobar si hay una sobrecarga de tablas e índices en su aplicación. Para obtener más información, consulte [Diagnóstico de sobrecarga de tablas e índices](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html).

#### Buscar índices que consuman espacio de forma innecesaria
<a name="wait-event.iodatafileread.actions.maintenance.indexes"></a>

Para encontrar índices sobrecargados y estimar la cantidad de espacio consumida innecesariamente en las tablas para las que tiene privilegios de lectura, puede ejecutar la siguiente consulta.

```
-- WARNING: rows with is_na = 't' are known to have bad statistics ("name" type is not supported).
-- This query is compatible with PostgreSQL 8.2 and later.

SELECT current_database(), nspname AS schemaname, tblname, idxname, bs*(relpages)::bigint AS real_size,
  bs*(relpages-est_pages)::bigint AS extra_size,
  100 * (relpages-est_pages)::float / relpages AS extra_ratio,
  fillfactor, bs*(relpages-est_pages_ff) AS bloat_size,
  100 * (relpages-est_pages_ff)::float / relpages AS bloat_ratio,
  is_na
  -- , 100-(sub.pst).avg_leaf_density, est_pages, index_tuple_hdr_bm, 
  -- maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, sub.reltuples, sub.relpages 
  -- (DEBUG INFO)
FROM (
  SELECT coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 
       -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
    ) AS est_pages,
    coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
    ) AS est_pages_ff,
    bs, nspname, table_oid, tblname, idxname, relpages, fillfactor, is_na
    -- , stattuple.pgstatindex(quote_ident(nspname)||'.'||quote_ident(idxname)) AS pst, 
    -- index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples 
    -- (DEBUG INFO)
  FROM (
    SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, relam, table_oid, fillfactor,
      ( index_tuple_hdr_bm +
          maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
            WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
            ELSE index_tuple_hdr_bm%maxalign
          END
        + nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
            WHEN nulldatawidth = 0 THEN 0
            WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
            ELSE nulldatawidth::integer%maxalign
          END
      )::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
      -- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
    FROM (
      SELECT
        i.nspname, i.tblname, i.idxname, i.reltuples, i.relpages, i.relam, a.attrelid AS table_oid,
        current_setting('block_size')::numeric AS bs, fillfactor,
        CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
          WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
          ELSE 4
        END AS maxalign,
        /* per page header, fixed size: 20 for 7.X, 24 for others */
        24 AS pagehdr,
        /* per page btree opaque data */
        16 AS pageopqdata,
        /* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
        CASE WHEN max(coalesce(s.null_frac,0)) = 0
          THEN 2 -- IndexTupleData size
          ELSE 2 + (( 32 + 8 - 1 ) / 8) 
          -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
        END AS index_tuple_hdr_bm,
        /* data len: we remove null values save space using it fractionnal part from stats */
        sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
        max( CASE WHEN a.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
      FROM pg_attribute AS a
        JOIN (
          SELECT nspname, tbl.relname AS tblname, idx.relname AS idxname, 
            idx.reltuples, idx.relpages, idx.relam,
            indrelid, indexrelid, indkey::smallint[] AS attnum,
            coalesce(substring(
              array_to_string(idx.reloptions, ' ')
               from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor
          FROM pg_index
            JOIN pg_class idx ON idx.oid=pg_index.indexrelid
            JOIN pg_class tbl ON tbl.oid=pg_index.indrelid
            JOIN pg_namespace ON pg_namespace.oid = idx.relnamespace
          WHERE pg_index.indisvalid AND tbl.relkind = 'r' AND idx.relpages > 0
        ) AS i ON a.attrelid = i.indexrelid
        JOIN pg_stats AS s ON s.schemaname = i.nspname
          AND ((s.tablename = i.tblname AND s.attname = pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE)) 
          -- stats from tbl
          OR  (s.tablename = i.idxname AND s.attname = a.attname))
          -- stats from functional cols
        JOIN pg_type AS t ON a.atttypid = t.oid
      WHERE a.attnum > 0
      GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9
    ) AS s1
  ) AS s2
    JOIN pg_am am ON s2.relam = am.oid WHERE am.amname = 'btree'
) AS sub
-- WHERE NOT is_na
ORDER BY 2,3,4;
```

#### Buscar tablas aptas para autovacuum
<a name="wait-event.iodatafileread.actions.maintenance.autovacuumed"></a>

Para buscar tablas que se puedan vaciar automáticamente, ejecute la siguiente consulta.

```
--This query shows tables that need vacuuming and are eligible candidates.
--The following query lists all tables that are due to be processed by autovacuum. 
-- During normal operation, this query should return very little.
WITH  vbt AS (SELECT setting AS autovacuum_vacuum_threshold 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_threshold')
    , vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_scale_factor')
    , fma AS (SELECT setting AS autovacuum_freeze_max_age 
              FROM pg_settings WHERE name = 'autovacuum_freeze_max_age')
    , sto AS (SELECT opt_oid, split_part(setting, '=', 1) as param, 
                split_part(setting, '=', 2) as value 
              FROM (SELECT oid opt_oid, unnest(reloptions) setting FROM pg_class) opt)
SELECT
    '"'||ns.nspname||'"."'||c.relname||'"' as relation
    , pg_size_pretty(pg_table_size(c.oid)) as table_size
    , age(relfrozenxid) as xid_age
    , coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age
    , (coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
         coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples) 
         as autovacuum_vacuum_tuples
    , n_dead_tup as dead_tuples
FROM pg_class c 
JOIN pg_namespace ns ON ns.oid = c.relnamespace
JOIN pg_stat_all_tables stat ON stat.relid = c.oid
JOIN vbt on (1=1) 
JOIN vsf ON (1=1) 
JOIN fma on (1=1)
LEFT JOIN sto cvbt ON cvbt.param = 'autovacuum_vacuum_threshold' AND c.oid = cvbt.opt_oid
LEFT JOIN sto cvsf ON cvsf.param = 'autovacuum_vacuum_scale_factor' AND c.oid = cvsf.opt_oid
LEFT JOIN sto cfma ON cfma.param = 'autovacuum_freeze_max_age' AND c.oid = cfma.opt_oid
WHERE c.relkind = 'r' 
AND nspname <> 'pg_catalog'
AND (
    age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
    or
    coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
      coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples <= n_dead_tup
    -- or 1 = 1
)
ORDER BY age(relfrozenxid) DESC;
```

### Responder a un gran número de conexiones
<a name="wait-event.iodatafileread.actions.connections"></a>

Cuando se monitorea Amazon CloudWatch, se puede encontrar que la métrica `DatabaseConnections` se dispara. Este aumento indica un mayor número de conexiones a su base de datos. Se recomienda el siguiente enfoque:
+ Limite el número de conexiones que la aplicación puede abrir con cada instancia. Si la aplicación tiene una característica de grupo de conexiones integrada, establezca un número razonable de conexiones. Base el número en lo que las vCPU de su instancia puedan paralelizar de forma efectiva.

  Si su aplicación no utiliza una característica de grupo de conexiones, considere utilizar Amazon RDS Proxy o una alternativa. Este enfoque permite que su aplicación abra varias conexiones con el equilibrador de carga. El equilibrador puede entonces abrir un número restringido de conexiones con la base de datos. Como se ejecutan menos conexiones en paralelo, la instancia de base de datos hace menos cambios de contexto en el núcleo. Las consultas deberían progresar más rápido, lo que provocaría menos eventos de espera. Para obtener más información, consulte [Amazon RDS Proxy ](rds-proxy.md).
+ Siempre que sea posible, aproveche las réplicas de lectura para RDS para PostgreSQL. Cuando la aplicación ejecute una operación de solo lectura, envíe estas solicitudes a la(s) réplica(s) de lectura. Esta técnica reduce la presión de E/S en el nodo principal (de escritura).
+ Considere la posibilidad de escalar verticalmente su instancia de base de datos. Una clase de instancia de mayor capacidad proporciona más memoria, lo que le da a RDS para PostgreSQL un grupo de búferes compartidos mayor para mantener las páginas. El tamaño más grande también le da a la instancia de base de datos más vCPU para manejar las conexiones. Más vCPU son especialmente útiles cuando las operaciones que generan eventos de espera `IO:DataFileRead` se escriben.

# IO:WALWrite
<a name="wait-event.iowalwrite"></a>



**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.iowalwrite.context.supported)
+ [

## Contexto
](#wait-event.iowalwrite.context)
+ [

## Causas probables del aumento del tiempo de espera
](#wait-event.iowalwrite.causes)
+ [

## Acciones
](#wait-event.iowalwrite.actions)

## Versiones del motor admitidas
<a name="wait-event.iowalwrite.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL 10 y posteriores.

## Contexto
<a name="wait-event.iowalwrite.context"></a>

La actividad de la base de datos que genera datos de registro de escritura anticipada llena primero los búferes de WAL y, a continuación, los escribe en el disco de forma asincrónica. El evento de espera `IO:WALWrite` se genera cuando la sesión de SQL espera a que los datos de WAL terminen de escribirse en el disco para poder lanzar la llamada COMMIT de la transacción. 

## Causas probables del aumento del tiempo de espera
<a name="wait-event.iowalwrite.causes"></a>

Si este evento de espera se produce con frecuencia, debe revisar su carga de trabajo, el tipo de actualizaciones que realiza y su frecuencia. En particular, busque los siguientes tipos de actividad.

**Actividad intensa de DML**  
El cambio de datos en las tablas de bases de datos no se produce de forma instantánea. Es posible que una inserción en una tabla deba esperar a que otro cliente inserte o actualice la misma tabla. Las instrucciones del lenguaje de manipulación de datos (DML) para cambiar los valores de los datos (INSERT, UPDATE, DELETE, COMMIT, ROLLBACK TRANSACTION) pueden generar disputas que hagan que el archivo de registro de escritura anticipada espere a que se vacíen los búferes. Esta situación se refleja en las siguientes métricas de Información de rendimiento de Amazon RDS, que indican una actividad de DML intensa.  
+  `tup_inserted`
+ `tup_updated`
+ `tup_deleted`
+ `xact_rollback`
+ `xact_commit`
Para obtener más información sobre estas métricas, consulte [Contadores de Información sobre rendimiento para Amazon RDS para PostgreSQL](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.PostgreSQL).

**Actividad de puntos de comprobación frecuente**  
Los puntos de control frecuentes contribuyen a aumentar el número de archivos WAL. En RDS para PostgreSQL, la escritura de páginas completas siempre está «activada». La escritura de páginas completas ayuda a proteger contra la pérdida de datos. Sin embargo, cuando los puntos de comprobación se realizan con demasiada frecuencia, el sistema puede sufrir problemas de rendimiento general. Esto es especialmente cierto en sistemas con una actividad intensa de DML. En algunos casos, es posible que encuentres mensajes de error en tel `postgresql.log` que indiquen que «los puntos de comprobación se producen con demasiada frecuencia».   
Le recomendamos que, al ajustar los puntos de comprobación, equilibre cuidadosamente el rendimiento con el tiempo esperado de recuperación en caso de que se produzca un cierre anormal. 

## Acciones
<a name="wait-event.iowalwrite.actions"></a>

Le recomendamos que realice las siguientes acciones para reducir los números de este evento de espera.

**Topics**
+ [

### Reducir el número de confirmaciones
](#wait-event.iowalwrite.actions.problem)
+ [

### Monitorear los puntos de comprobación
](#wait-event.iowalwrite.actions.monitor)
+ [

### Escalar la E/S verticalmente
](#wait-event.iowalwrite.actions.scale-io)
+ [

### Volumen de registro específico (DLV)
](#wait-event.iowalwrite.actions.dlv)

### Reducir el número de confirmaciones
<a name="wait-event.iowalwrite.actions.problem"></a>

Para reducir el número de confirmaciones, combine las instrucciones en bloques de transacciones. Utilice Información de rendimiento de Amazon RDS para examinar el tipo de consultas que se está ejecutando. También puede trasladar las grandes operaciones de mantenimiento a las horas de menor actividad. Por ejemplo, cree índices o utilice operaciones `pg_repack` durante las horas que no sean de producción.

### Monitorear los puntos de comprobación
<a name="wait-event.iowalwrite.actions.monitor"></a>

Hay dos parámetros que puede monitorear para ver con qué frecuencia su instancia de base de datos de RDS para PostgreSQL escribe puntos de comprobación en el archivo WAL. 
+ `log_checkpoints`: este parámetro está activado de forma predeterminada. Hace que se envíe un mensaje al registro de PostgreSQL para cada punto de comprobación. Estos mensajes de registro incluyen la cantidad de búferes escritos, el tiempo dedicado a escribirlos y la cantidad de archivos WAL agregados, eliminados o reciclados para un punto de comprobación determinado. 

  Para más información sobre este parámetro, consulte Error Reporting and Logging (Registro y notificación de errores) en la documentación de PostgreSQL. 
+ `checkpoint_warning`: este parámetro establece un valor umbral (en segundos) para la frecuencia del punto de comprobación por encima del cual se genera una advertencia. De forma predeterminada, este parámetro no está configurado en RDS para PostgreSQL. Puede establecer el valor de este parámetro de modo que reciba una advertencia cuando los cambios en la base de datos de su instancia de base de datos de RDS para PostgreSQL se escriban a una velocidad para la que los archivos WAL no tengan el tamaño adecuado. Por ejemplo, supongamos que establece este parámetro en 30. Si su instancia de RDS para PostgreSQL necesita escribir cambios con mayor frecuencia que cada 30 segundos, se envía la advertencia «los puntos de comprobación se producen con demasiada frecuencia» al registro de PostgreSQL. Esto puede indicar que su valor `max_wal_size` debe aumentarse. 

  Para obtener más información, consulte [Write Ahead Log](https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS) (Registro de escritura anticipada) en la documentación de PostgreSQL. 

### Escalar la E/S verticalmente
<a name="wait-event.iowalwrite.actions.scale-io"></a>

Este tipo de evento de espera de entrada/salida (E/S) se puede solucionar escalando las operaciones de entrada/salida por segundo (IOPS) para proporcionar una E/S más rápida. Es preferible escalar la E/S a escalar la CPU, ya que escalar la CPU puede generar aún más contención de E/S, ya que el aumento de la CPU puede soportar más trabajo y, por lo tanto, agravar aún más el cuello de botella de E/S. En general, recomendamos que considere ajustar la carga de trabajo antes de realizar las operaciones de escalado.

### Volumen de registro específico (DLV)
<a name="wait-event.iowalwrite.actions.dlv"></a>

Puede utilizar un volumen de registro específico (DLV) para una instancia de base de datos que utilice el almacenamiento de IOPS aprovisionadas (PIOPS) mediante la consola de Amazon RDS, la AWS CLI o la API de Amazon RDS. Un DLV transporta los registros de transacciones de la base de datos PostgreSQL a un volumen de almacenamiento independiente del volumen que contiene las tablas de la base de datos. Para obtener más información, consulte [Volumen de registro específico (DLV)](CHAP_Storage.md#CHAP_Storage.dlv).

# Eventos de espera de IPC:parallel
<a name="rpg-ipc-parallel"></a>

Los siguientes `IPC:parallel wait events` indican que una sesión está esperando una comunicación entre procesos relacionada con operaciones de ejecución de consultas en paralelo.
+ `IPC:BgWorkerStartup`: un proceso está esperando a que un proceso de trabajo paralelo complete la secuencia de inicio. Esto sucede al inicializar los procesos de trabajo para la ejecución de consultas en paralelo.
+ `IPC:BgWorkerShutdown`: un proceso está esperando a que un proceso de trabajo paralelo complete la secuencia de apagado. Esto sucede durante la fase de limpieza de la ejecución de consultas en paralelo.
+ `IPC:ExecuteGather`: un proceso está esperando recibir datos de procesos de trabajo paralelos durante la ejecución de consultas. Esto ocurre cuando el proceso líder necesita recopilar resultados de los procesos de trabajo.
+ `IPC:ParallelFinish`: un proceso está esperando a que los procesos de trabajo paralelos finalicen la ejecución y comuniquen los resultados finales. Esto sucede durante la fase de finalización de la ejecución de consultas en paralelo.

**Topics**
+ [

## Versiones del motor admitidas
](#rpg-ipc-parallel-context-supported)
+ [

## Contexto
](#rpg-ipc-parallel-context)
+ [

## Causas probables del aumento de las esperas
](#rpg-ipc-parallel-causes)
+ [

## Acciones
](#rpg-ipc-parallel-actions)

## Versiones del motor admitidas
<a name="rpg-ipc-parallel-context-supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de Aurora PostgreSQL.

## Contexto
<a name="rpg-ipc-parallel-context"></a>

La ejecución de consultas en paralelo en PostgreSQL implica que varios procesos trabajan juntos para procesar una sola consulta. Cuando se determina que una consulta es adecuada para la paralelización, un proceso líder coordina uno o varios procesos de trabajo paralelos en función de la configuración del parámetro `max_parallel_workers_per_gather`. El proceso líder divide el trabajo entre los procesos de trabajo, cada proceso de trabajo procesa la parte de los datos de forma independiente y los resultados se recopilan de nuevo en el proceso líder.

**nota**  
Cada proceso de trabajo paralelo funciona como un proceso independiente con requisitos de recursos similares a los de una sesión de usuario completa. Esto significa que una consulta en paralelo con cuatro procesos de trabajo puede consumir hasta cinco veces más recursos (CPU, memoria y ancho de banda de E/S) que una consulta que no sea en paralelo, ya que tanto el proceso líder como cada proceso de trabajo mantienen las asignaciones de recursos propias. Por ejemplo, la configuración como `work_mem` se aplica individualmente a cada proceso de trabajo, lo que puede multiplicar el uso total de memoria en todos los procesos.

La arquitectura de consulta en paralelo consta de tres componentes principales:
+ Proceso líder: el proceso principal que inicia la operación paralela, divide la carga de trabajo y coordina los procesos de trabajo.
+ Procesos de trabajo: procesos en segundo plano que ejecutan partes de la consulta en paralelo.
+ Recopilación/combinación de recopilaciones: operaciones que combinan los resultados de varios procesos de trabajo y los devuelven al líder

Durante la ejecución en paralelo, los procesos deben comunicarse entre sí a través de mecanismos de comunicación entre procesos (IPC). Estos eventos de espera de IPC se producen durante diferentes fases:
+ Inicio de procesos de trabajo: cuando se inicializan los procesos de trabajo paralelos
+ Intercambio de datos: cuando los procesos de trabajo procesan datos y envían los resultados al líder
+ Cierre de procesos de trabajo: cuando finaliza la ejecución paralela y se terminan los procesos de trabajo
+ Puntos de sincronización: cuando los procesos necesitan coordinarse o esperar a que otros procesos completen las tareas

Comprender estos eventos de espera es fundamental para diagnosticar problemas de rendimiento relacionados con la ejecución de consultas en paralelo, sobre todo en entornos de alta simultaneidad en los que pueden ejecutarse varias consultas en paralelo al mismo tiempo.

## Causas probables del aumento de las esperas
<a name="rpg-ipc-parallel-causes"></a>

Hay varios factores que pueden contribuir a un aumento de los eventos de espera de IPC relacionados con la ejecución en paralelo:

**Alta simultaneidad de consultas en paralelo**  
Cuando se ejecutan muchas consultas en paralelo al mismo tiempo, puede producirse una contención de recursos y un aumento de los tiempos de espera para las operaciones de IPC. Esto es muy habitual en sistemas con grandes volúmenes de transacciones o cargas de trabajo de análisis.

**Planes de consultas en paralelo poco óptimos**  
Si el planificador de consultas elige planes paralelos ineficientes, puede dar lugar a una paralelización innecesaria o a una distribución deficiente del trabajo entre los procesos de trabajo. Esto puede provocar un aumento de las esperas de IPC, sobre todo para los eventos `IPC:ExecuteGather` e `IPC:ParallelFinish`. Estos problemas de planificación suelen deberse a estadísticas obsoletas y a la saturación de tablas e índices.

**Inicio y apagado frecuentes de procesos de trabajo paralelos**  
Las consultas de corta duración que inician y terminan con frecuencia procesos de trabajo paralelos pueden provocar un aumento de los eventos `IPC:BgWorkerStartup` y `IPC:BgWorkerShutdown`. Esto se observa a menudo en cargas de trabajo OLTP con muchas consultas pequeñas y paralelizables.

**Limitaciones de recursos**  
La capacidad limitada de CPU, memoria o E/S puede provocar cuellos de botella en la ejecución paralela, lo que aumenta los tiempos de espera en todos los eventos de IPC. Por ejemplo, si la CPU está saturada, los procesos de trabajo pueden tardar más en iniciarse o en procesar la parte del trabajo.

**Estructuras de consultas complejas**  
Las consultas con varios niveles de paralelismo (por ejemplo, uniones paralelas seguidas de agregaciones paralelas) pueden dar lugar a patrones de IPC más complejos y a un aumento de los tiempos de espera, sobre todo para eventos `IPC:ExecuteGather`.

**Grandes conjuntos de resultados**  
Las consultas que producen conjuntos de resultados grandes pueden provocar un aumento de los tiempos de espera de `IPC:ExecuteGather`, ya que el proceso líder dedica más tiempo a recopilar y procesar los resultados de los procesos de trabajo.

Comprender estos factores puede ayudar a diagnosticar y resolver problemas de rendimiento relacionados con la ejecución de consultas paralelas en Aurora PostgreSQL.

## Acciones
<a name="rpg-ipc-parallel-actions"></a>

Cuando ve esperas relacionadas con consultas en paralelo, normalmente significa que un proceso backend está coordinando o esperando procesos de trabajo paralelos. Estas esperas son comunes durante la ejecución de planes paralelos. Puede investigar y mitigar el impacto de estas esperas mediante la supervisión del uso de procesos de trabajo paralelos, la revisión de la configuración de los parámetros y el ajuste de la ejecución de las consultas y asignación de recursos.

**Topics**
+ [

### Análisis de los planes de consulta en busca de paralelismo ineficiente
](#rpg-ipc-parallel-analyze-plans)
+ [

### Supervisión del uso de consultas en paralelo
](#rpg-ipc-parallel-monitor)
+ [

### Revisión y ajuste de la configuración de consultas en paralelo
](#rpg-ipc-parallel-adjust-settings)
+ [

### Optimización de la asignación de recursos
](#rpg-ipc-parallel-optimize-resources)
+ [

### Investigación de la administración de conexiones
](#rpg-ipc-parallel-connection-management)
+ [

### Revisión y optimización de las operaciones de mantenimiento
](#rpg-ipc-parallel-maintenance)

### Análisis de los planes de consulta en busca de paralelismo ineficiente
<a name="rpg-ipc-parallel-analyze-plans"></a>

La ejecución de consultas en paralelo a menudo puede provocar inestabilidad del sistema, picos de CPU y variaciones impredecibles en el rendimiento de las consultas. Es fundamental analizar a fondo si el paralelismo mejora realmente la carga de trabajo específica. Utilice EXPLAIN ANALYZE para revisar los planes de ejecución de consultas en paralelo.

Deshabilite temporalmente el paralelismo de la sesión para comparar la eficiencia del plan:

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
```

Vuelva a habilitar el paralelismo y compare:

```
RESET max_parallel_workers_per_gather;
EXPLAIN ANALYZE <your_query>;
```

Si al deshabilitar el paralelismo se obtienen resultados mejores o más coherentes, considere la posibilidad de deshabilitarlo para consultas específicas de sesión mediante comandos SET. Para lograr un impacto más amplio, es posible que desee deshabilitar el paralelismo de instancia mediante el ajuste de los parámetros pertinentes en el grupo de parámetros de base de datos. Para obtener más información, consulte [Modificación de los parámetros de un grupo de parámetros de base de datos en Amazon RDS](USER_WorkingWithParamGroups.Modifying.md).

### Supervisión del uso de consultas en paralelo
<a name="rpg-ipc-parallel-monitor"></a>

Utilice las siguientes consultas para obtener visibilidad de la actividad y la capacidad de las consultas en paralelo:

Compruebe los procesos de trabajo paralelos activos:

```
SELECT
    COUNT(*)
FROM
    pg_stat_activity
WHERE
    backend_type = 'parallel worker';
```

Esta consulta muestra el número de procesos de trabajo paralelos activos. Un valor alto puede indicar que “max\$1parallel\$1workers” se ha configurado con un valor alto y es recomendable que considere la posibilidad de reducirlo.

Compruebe las consultas en paralelo simultáneas:

```
SELECT
    COUNT(DISTINCT leader_pid)
FROM
    pg_stat_activity
WHERE
    leader_pid IS NOT NULL;
```

Esta consulta devuelve el número de procesos líderes distintos que han iniciado consultas en paralelo. Un número alto indica que varias sesiones están ejecutando consultas en paralelo simultáneamente, lo que puede aumentar la demanda de CPU y memoria.

### Revisión y ajuste de la configuración de consultas en paralelo
<a name="rpg-ipc-parallel-adjust-settings"></a>

Revise los siguientes parámetros para asegurarse de que se ajusten a la carga de trabajo:
+ `max_parallel_workers`: número total de procesos de trabajo paralelos en todas las sesiones.
+ `max_parallel_workers_per_gather`: número máximo de procesos de trabajo por consulta.

Para cargas de trabajo OLAP, aumentar estos valores puede mejorar el rendimiento. Para cargas de trabajo OLTP, por lo general, se prefieren valores más bajos.

```
SHOW max_parallel_workers;
SHOW max_parallel_workers_per_gather;
```

### Optimización de la asignación de recursos
<a name="rpg-ipc-parallel-optimize-resources"></a>

Supervise la utilización de la CPU y considere la posibilidad de ajustar el número de vCPU si es coherentemente alto y si la aplicación se beneficia de las consultas en paralelo. Asegúrese de que haya memoria suficiente para las operaciones paralelas.
+ Utilice las métricas de Información de rendimiento para determinar si el sistema está limitado por la CPU.
+ Cada proceso de trabajo paralelo utiliza un `work_mem` propio. Asegúrese de que el uso total de memoria se encuentre dentro de los límites de la instancia.

Las consultas en paralelo pueden consumir muchos más recursos que las consultas que no son en paralelo, ya que cada proceso de trabajo es un proceso completamente independiente que tiene aproximadamente el mismo impacto en el sistema que una sesión de usuario adicional. Esto debe tenerse en cuenta al elegir un valor para esta configuración, así como al configurar otras opciones que controlan la utilización de recursos, como `work_mem`. Para obtener más información, consulte la [documentación de PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM). Los límites de recursos, como `work_mem`, se aplican individualmente a cada proceso de trabajo, lo que significa que la utilización total puede ser mucho mayor en todos los procesos de lo que sería normalmente para un solo proceso.

Considere la posibilidad de aumentar las vCPU o ajustar los parámetros de memoria si la carga de trabajo está muy paralelizada.

### Investigación de la administración de conexiones
<a name="rpg-ipc-parallel-connection-management"></a>

Si se agota la conexión, revise las estrategias de agrupación de conexiones de la aplicación. Considere la posibilidad de implementar la agrupación de conexiones de aplicación si aún no se utiliza.

### Revisión y optimización de las operaciones de mantenimiento
<a name="rpg-ipc-parallel-maintenance"></a>

Coordine la creación de índices y otras tareas de mantenimiento para evitar la contención de recursos. Considere la posibilidad de programar estas operaciones durante las horas de menor actividad. Evite programar tareas de mantenimiento intensas (por ejemplo, creaciones de índices en paralelo) durante periodos de alta carga de consultas de los usuarios. Estas operaciones pueden consumir procesos de trabajo paralelos y afectar al rendimiento de las consultas habituales.

# IPC:ProcArrayGroupUpdate
<a name="apg-rpg-ipcprocarraygroup"></a>

El evento `IPC:ProcArrayGroupUpdate` se produce cuando una sesión está esperando a que líder de grupo actualice el estado de la transacción al final de esa operación. Mientras PostgreSQL generalmente asocia los eventos de espera de tipo IPC con las operaciones de consulta paralelas, este evento de espera en particular no es específico de las consultas paralelas.

**Topics**
+ [

## Versiones del motor admitidas
](#apg-rpg-ipcprocarraygroup.supported)
+ [

## Contexto
](#apg-rpg-ipcprocarraygroup.context)
+ [

## Causas probables del aumento de las esperas
](#apg-rpg-ipcprocarraygroup.causes)
+ [

## Acciones
](#apg-rpg-ipcprocarraygroup.actions)

## Versiones del motor admitidas
<a name="apg-rpg-ipcprocarraygroup.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Contexto
<a name="apg-rpg-ipcprocarraygroup.context"></a>

**Descripción de la matriz de procesos**: la matriz de procesos (proc) es una estructura de memoria compartida en PostgreSQL. Contiene información sobre todos los procesos en ejecución, incluidos los detalles de las transacciones. Al finalizar la transacción (`COMMIT` o `ROLLBACK`), el ProcArray debe actualizarse para reflejar el cambio y borrar el ID de transacción de la matriz. La sesión que intente finalizar su transacción debe adquirir un bloqueo exclusivo en el ProcArray. Esto evita que otros procesos obtengan bloqueos compartidos o exclusivos sobre ella.

**Mecanismo de actualización grupal**: al realizar un COMMIT o ROLLBACK, si un proceso de backend no puede obtener un ProcArrayLock en modo exclusivo, actualiza un campo especial llamado ProcArrayGroupMember. Esto agrega la transacción a la lista de sesiones que pretenden finalizar. A continuación, este proceso de backend se suspende y el tiempo que duerme se configura como el evento de espera ProcArrayGroupUpdate. El primer proceso de ProcArray con ProcArrayGroupMember, denominado proceso de líder, adquiere el ProcArrayLock en modo exclusivo. A continuación, borra la lista de procesos en espera de ser liquidados por el ID de transacción del grupo. Una vez finalizada esta operación, el líder libera el ProcArrayLock y activa todos los procesos de la lista y les notifica que la transacción se ha completado.

## Causas probables del aumento de las esperas
<a name="apg-rpg-ipcprocarraygroup.causes"></a>

Cuantos más procesos estén en ejecución, más tiempo conservará el líder un ProcArrayLock en modo exclusivo. En consecuencia, cuantas más transacciones de escritura acaben en un escenario de actualización grupal, más se provocará una posible acumulación de procesos en espera en el evento de espera `ProcArrayGroupUpdate`. En la vista de SQL principal de información de base de datos, verá que COMMIT es la instrucción que contiene la mayor parte del tiempo de espera. Esto es de esperar, pero requerirá una investigación más profunda del SQL de escritura específico que se está ejecutando para determinar qué medidas se deben tomar.

## Acciones
<a name="apg-rpg-ipcprocarraygroup.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera. Identifique eventos de `IPC:ProcArrayGroupUpdate` mediante Información de rendimiento de Amazon RDS o la consulta de la vista del sistema PostgreSQL `pg_stat_activity`.

**Topics**
+ [

### Supervisión de las operaciones de confirmación y reversión de transacciones
](#apg-rpg-ipcprocarraygroup.actions.monitor)
+ [

### Reducción de la simultaneidad
](#apg-rpg-ipcprocarraygroup.actions.concurrency)
+ [

### Implementación de la agrupación de conexiones
](#apg-rpg-ipcprocarraygroup.actions.pooling)
+ [

### Uso de un almacenamiento más rápido
](#apg-rpg-ipcprocarraygroup.actions.storage)

### Supervisión de las operaciones de confirmación y reversión de transacciones
<a name="apg-rpg-ipcprocarraygroup.actions.monitor"></a>

**Supervise las confirmaciones y las reversiones**: un mayor número de confirmaciones y reversiones puede aumentar la presión sobre ProcArray. Por ejemplo, si una instrucción SQL comienza a producir errores debido al aumento de las infracciones de claves duplicadas, es posible que se produzca un aumento de las reversiones, lo que puede aumentar la contención de ProcArray y la sobrecarga de tablas.

La información de base de datos de Amazon RDS proporciona las métricas de PostgreSQL `xact_commit` y `xact_rollback` para informar del número de confirmaciones y reversiones por segundo.

### Reducción de la simultaneidad
<a name="apg-rpg-ipcprocarraygroup.actions.concurrency"></a>

**Transacciones por lotes**: siempre que sea posible, agrupe las operaciones en transacciones individuales para reducir las operaciones de confirmación o reversión.

**Limite la simultaneidad**: reduzca la cantidad de transacciones activas simultáneamente para evitar la contención de bloqueos en ProcArray. Si bien requerirá algunas pruebas, reducir el número total de conexiones simultáneas puede reducir la contención y mantener el rendimiento.

### Implementación de la agrupación de conexiones
<a name="apg-rpg-ipcprocarraygroup.actions.pooling"></a>

**Soluciones de agrupación de conexiones**: utilice la agrupación de conexiones para administrar las conexiones de bases de datos de manera eficiente, lo que reduce la cantidad total de backends y, por lo tanto, la carga de trabajo de ProcArray. Si bien requerirá algunas pruebas, reducir el número total de conexiones simultáneas puede reducir la contención y mantener el rendimiento.

**Reduzca las tormentas de conexiones**: del mismo modo, un patrón de creación y terminación frecuentes de conexiones genera una presión adicional sobre ProcArray. Al reducir este patrón, se reduce la contención general.

### Uso de un almacenamiento más rápido
<a name="apg-rpg-ipcprocarraygroup.actions.storage"></a>

**Volumen de registro dedicado**: si el evento de espera `IPC:ProcArrayGroupUpdate` va acompañado de eventos de espera `IO:WALWrite` altos, la configuración de un volumen de registro dedicado puede reducir los cuellos de botella que se producen al escribir en WAL. A su vez, esto mejora el rendimiento de las confirmaciones.

Para obtener más información, consulte [Volumen de registro específico](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PIOPS.dlv.html).

# Lock:advisory
<a name="wait-event.lockadvisory"></a>

El evento `Lock:advisory` ocurre cuando una aplicación PostgreSQL utiliza un bloqueo para coordinar la actividad entre varias sesiones.

**Topics**
+ [

## Versiones del motor relevantes
](#wait-event.lockadvisory.context.supported)
+ [

## Context
](#wait-event.lockadvisory.context)
+ [

## Causas
](#wait-event.lockadvisory.causes)
+ [

## Acciones
](#wait-event.lockadvisory.actions)

## Versiones del motor relevantes
<a name="wait-event.lockadvisory.context.supported"></a>

La información de eventos de espera es relevante para RDS para PostgreSQL versión 9.6 y posteriores.

## Context
<a name="wait-event.lockadvisory.context"></a>

Los bloqueos consultivos de PostgreSQL son bloqueos cooperativos a nivel de aplicación, bloqueados y desbloqueados explícitamente por el código de la aplicación del usuario. Una aplicación puede usar los bloqueos consultivos de PostgreSQL para coordinar la actividad a través de varias sesiones. A diferencia de los bloqueos regulares a nivel de objeto o de fila, la aplicación tiene control total sobre el tiempo de vida del bloqueo. Para más información, consulte [Advisory Locks](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) en la documentación de PostgreSQL.

Los bloqueos consultivos se pueden liberar antes de que finalice una transacción o mantenerse en una sesión a través de las transacciones. Esto no es verdadero para los bloqueos implícitos, forzados por el sistema, como un bloqueo de acceso exclusivo a una tabla adquirido por una instrucción `CREATE INDEX`.

Para una descripción de las funciones que se utilizan para adquirir (bloquear) y liberar (desbloquear) los bloqueos de asesoramiento, consulte [Advisory Lock Functions](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) en la documentación de PostgreSQL.

Los bloqueos consultivos se implementan sobre el sistema de bloqueo regular de PostgreSQL y son visibles en la vista del sistema `pg_locks`.

## Causas
<a name="wait-event.lockadvisory.causes"></a>

Este tipo de bloqueo es controlado exclusivamente por una aplicación que lo utiliza de forma explícita. Los bloqueos consultivos que se adquieren para cada fila como parte de una consulta pueden causar un pico de bloqueos o una acumulación a largo plazo.

Estos efectos se producen cuando la consulta se ejecuta de forma que adquiere bloqueos en más filas de las que devuelve la consulta. La aplicación debe liberar finalmente todos los bloqueos, pero si se adquieren bloqueos en filas que no se devuelven, la aplicación no puede encontrar todos los bloqueos.

El siguiente ejemplo proviene de [Advisory Locks](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) en la documentación de PostgreSQL.

```
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100;
```

En este ejemplo, la cláusula `LIMIT` solo puede detener la salida de la consulta después de que las filas se hayan seleccionado internamente y sus valores de ID se hayan bloqueado. Esto puede ocurrir de forma repentina cuando un volumen de datos creciente hace que el planificador elija un plan de ejecución diferente que no fue probado durante el desarrollo. La acumulación en este caso ocurre porque la aplicación llama explícitamente a `pg_advisory_unlock` para cada valor de ID que fue bloqueado. Sin embargo, en este caso no se puede encontrar el conjunto de bloqueos adquiridos en las filas que no fueron devueltas. Como los bloqueos se adquieren a nivel de sesión, no se liberan automáticamente al final de la transacción.

Otra posible causa de los picos de intentos de bloqueo son los conflictos involuntarios. En estos conflictos, partes no relacionadas de la aplicación comparten el mismo espacio de ID de bloqueo por error.

## Acciones
<a name="wait-event.lockadvisory.actions"></a>

Revisar el uso de la aplicación de los bloqueos consultivos y detallar dónde y cuándo en el flujo de la aplicación se adquiere y libera cada tipo de bloqueo consultivo.

Determine si una sesión adquiere demasiados bloqueos o si una sesión de larga duración no libera los bloqueos con suficiente antelación, lo que provoca una acumulación lenta de bloqueos. Puede corregir una acumulación lenta de bloqueos de sesión si finaliza la sesión con `pg_terminate_backend(pid)`. 

Un cliente en espera de un bloqueo consultivo aparece en `pg_stat_activity` con `wait_event_type=Lock` y `wait_event=advisory`. Puede obtener valores de bloqueo específicos al consultar la vista del sistema `pg_locks` para el mismo `pid`, buscando `locktype=advisory` y `granted=f`.

A continuación, puede identificar la sesión de bloqueo al consultar `pg_locks` para el mismo bloqueo consultivo con `granted=t`, como se muestra en el siguiente ejemplo.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

Todas las funciones de la API de bloqueo consultivo tienen dos conjuntos de argumentos, un argumento `bigint` o dos argumentos `integer`:
+ Para las funciones API con un argumento `bigint`, los 32 bits superiores están en `pg_locks.classid` y los 32 bits inferiores están en `pg_locks.objid`.
+ Para las funciones de la API con dos argumentos `integer`, el primer argumento es `pg_locks.classid` y el segundo argumento es `pg_locks.objid`.

El valor de `pg_locks.objsubid` indica qué forma de la API se utilizó: `1` significa un argumento `bigint`; `2` significa dos argumentos `integer`.

# Lock:extend
<a name="wait-event.lockextend"></a>

El evento `Lock:extend` se produce cuando un proceso del backend espera bloquear una relación para extenderla mientras otro proceso tiene un bloqueo en esa relación con el mismo propósito.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.lockextend.context.supported)
+ [

## Context
](#wait-event.lockextend.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.lockextend.causes)
+ [

## Acciones
](#wait-event.lockextend.actions)

## Versiones del motor admitidas
<a name="wait-event.lockextend.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Context
<a name="wait-event.lockextend.context"></a>

El evento `Lock:extend` indica que un proceso backend se encuentra a la espera de extender una relación sobre la que otro proceso backend tiene un bloqueo mientras está extendiendo esa relación. Debido a que solo un proceso a la vez puede extender una relación, el sistema genera un evento de espera `Lock:extend`. Las operaciones `INSERT`, `COPY` y `UPDATE` pueden generar este evento.

## Causas probables del aumento de las esperas
<a name="wait-event.lockextend.causes"></a>

Cuando el evento `Lock:extend` aparece más de lo normal, lo que posiblemente indica un problema de rendimiento, las causas típicas son las siguientes:

**Aumento de las inserciones o actualizaciones concurrentes en la misma tabla **  
Puede haber un aumento en el número de sesiones concurrentes con consultas que insertan o actualizan la misma tabla.

**Ancho de banda de red insuficiente**  
El ancho de banda de la red en la instancia de base de datos puede ser insuficiente para las necesidades de comunicación del almacenamiento de la carga de trabajo actual. Esto puede contribuir a la latencia del almacenamiento que provoca un aumento de los eventos `Lock:extend`.

## Acciones
<a name="wait-event.lockextend.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Reducir las inserciones y actualizaciones concurrentes en la misma relación
](#wait-event.lockextend.actions.action1)
+ [

### Aumentar el ancho de banda de la red
](#wait-event.lockextend.actions.increase-network-bandwidth)

### Reducir las inserciones y actualizaciones concurrentes en la misma relación
<a name="wait-event.lockextend.actions.action1"></a>

En primer lugar, determine si hay un aumento de las métricas `tup_inserted` y `tup_updated` y un aumento de este evento de espera. Si es así, verifique qué relaciones están en alta contención para las operaciones de inserción y actualización. Para determinar esto, consulte la vista `pg_stat_all_tables` para los valores de los campos `n_tup_ins` y `n_tup_upd`. Para obtener información sobre la vista `pg_stat_all_tables`, consulte [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW) en la documentación de PostgreSQL. 

Para obtener más información acerca de las consultas bloqueadas y no bloqueadas, consulte `pg_stat_activity` como en el siguiente ejemplo:

```
SELECT
    blocked.pid,
    blocked.usename,
    blocked.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query,
    blocking.wait_event AS blocking_wait_event,
    blocking.wait_event_type AS blocking_wait_event_type
FROM pg_stat_activity AS blocked
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
where
blocked.wait_event = 'extend'
and blocked.wait_event_type = 'Lock';
 
   pid  | usename  |            query             | blocking_id |                         blocking_query                           | blocking_wait_event | blocking_wait_event_type
  ------+----------+------------------------------+-------------+------------------------------------------------------------------+---------------------+--------------------------
   7143 |  myuser  | insert into tab1 values (1); |        4600 | INSERT INTO tab1 (a) SELECT s FROM generate_series(1,1000000) s; | DataFileExtend      | IO
```

Después de identificar las relaciones que contribuyen a aumentar los eventos `Lock:extend`, utilice las siguientes técnicas para reducir la contención:
+ Compruebe si puede utilizar el particionamiento para reducir la contención para la misma tabla. Separar las tuplas insertadas o actualizadas en diferentes particiones puede reducir la contención. Para obtener información sobre las particiones, consulte [Administración de las particiones de PostgreSQL con la extensión pg\$1partman](PostgreSQL_Partitions.md).
+ Si el evento de espera se debe principalmente a la actividad de actualización, considere reducir el valor de fillfactor de la relación. Esto puede reducir las solicitudes de nuevos bloques durante la actualización. El fillfactor es un parámetro de almacenamiento para una tabla que determina la cantidad máxima de espacio para empaquetar una página de la tabla. Se expresa como un porcentaje del espacio total de una página. Para más información sobre el parámetro fillfactor, consulte [CREATE TABLE](https://www.postgresql.org/docs/13/sql-createtable.html) en la documentación de PostgreSQL. 
**importante**  
Recomendamos ampliamente que pruebe su sistema si cambia el fillfactor porque cambiar este valor puede impactar negativamente en el rendimiento, de acuerdo a su carga de trabajo.

### Aumentar el ancho de banda de la red
<a name="wait-event.lockextend.actions.increase-network-bandwidth"></a>

Para ver si hay un aumento en la latencia de escritura, verifique la métrica `WriteLatency` en CloudWatch. Si lo hay, utilice las métricas `WriteThroughput` y `ReadThroughput` de Amazon CloudWatch para monitorear el tráfico relacionado con el almacenamiento en la instancia de base de datos. Estas métricas pueden ayudarle a determinar si el ancho de banda de la red es suficiente para la actividad de almacenamiento de su carga de trabajo.

Si el ancho de banda de su red no es suficiente, auméntelo. Si la instancia de base de datos alcanza los límites del ancho de banda de la red, la única forma de aumentar el ancho de banda es aumentar el tamaño de la instancia de base de datos.

Para obtener más información acerca de las métricas de CloudWatch, consulte [Métricas de nivel de instancia de Amazon CloudWatch para Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). Para obtener información sobre el rendimiento de la red para cada clase de instancia de base de datos, consulte [Métricas de nivel de instancia de Amazon CloudWatch para Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). 

# Lock:Relation
<a name="wait-event.lockrelation"></a>

El evento `Lock:Relation` ocurre cuando una consulta espera adquirir un bloqueo en una tabla o vista (relación) que se encuentra bloqueada por otra transacción.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.lockrelation.context.supported)
+ [

## Contexto
](#wait-event.lockrelation.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.lockrelation.causes)
+ [

## Acciones
](#wait-event.lockrelation.actions)

## Versiones del motor admitidas
<a name="wait-event.lockrelation.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Contexto
<a name="wait-event.lockrelation.context"></a>

La mayoría de los comandos de PostgreSQL utilizan implícitamente bloqueos para controlar el acceso concurrente a los datos de las tablas. También puede utilizar estos bloqueos explícitamente en su código de aplicación con el comando `LOCK`. Muchos modos de bloqueo no son compatibles entre sí, y pueden bloquear las transacciones cuando intentan acceder al mismo objeto. Cuando esto sucede, RDS para PostgreSQL genera un evento `Lock:Relation`. Algunos ejemplos comunes son los siguientes:
+ Los bloqueos exclusivos como `ACCESS EXCLUSIVE` pueden bloquear todos los accesos concurrentes. Las operaciones del lenguaje de definición de datos (DDL) como `DROP TABLE`, `TRUNCATE`, `VACUUM FULL` y `CLUSTER` adquieren bloqueos `ACCESS EXCLUSIVE` implícitamente. `ACCESS EXCLUSIVE` es también el modo de bloqueo por defecto para las instrucciones `LOCK TABLE` que no especifican un modo explícitamente.
+ El uso de `CREATE INDEX (without CONCURRENT)` en una tabla entra en conflicto con las instrucciones de lenguaje de manipulación de datos (DML) `UPDATE`, `DELETE` e `INSERT`, que adquieren bloqueos `ROW EXCLUSIVE`.

Para más información sobre los bloqueos a nivel de tabla y los modos de bloqueo conflictivos, consulte [Explicit Locking](https://www.postgresql.org/docs/13/explicit-locking.html) en la documentación de PostgreSQL.

Las consultas y transacciones que se bloquean normalmente se desbloquean de una de las siguientes maneras:
+ Consulta de bloqueo: la aplicación puede cancelar la consulta o el usuario puede terminar el proceso. El motor también puede forzar la finalización de la consulta debido al tiempo de espera de una sesión o a un mecanismo de detección de bloqueos.
+ Transacción bloqueada: una transacción deja de bloquearse cuando se ejecuta una instrucción `ROLLBACK` o `COMMIT`. Las restauraciones también ocurren de forma automática cuando las sesiones se desconectan por un cliente o por problemas de red, o se terminan. Las sesiones se pueden terminar cuando el motor de base de datos se apaga, cuando el sistema se queda sin memoria, etc.

## Causas probables del aumento de las esperas
<a name="wait-event.lockrelation.causes"></a>

Cuando el evento `Lock:Relation` se produce con más frecuencia de lo normal, puede indicar un problema de rendimiento. Las causas típicas son las siguientes:

**Aumento de las sesiones concurrentes con bloqueos de tablas en conflicto**  
Puede haber un aumento en el número de sesiones concurrentes con consultas que bloquean la misma tabla con modos de bloqueo conflictivos.

**Operaciones de mantenimiento**  
Las operaciones de mantenimiento de estado como `VACUUM` y `ANALYZE` pueden aumentar significativamente el número de bloqueos conflictivos. `VACUUM FULL` adquiere un bloqueo `ACCESS EXCLUSIVE`, y `ANALYSE` adquiere un bloqueo `SHARE UPDATE EXCLUSIVE`. Ambos tipos de bloqueos pueden causar un evento de espera `Lock:Relation`. Las operaciones de mantenimiento de datos de la aplicación, como la actualización de una vista materializada, también pueden aumentar las consultas y transacciones bloqueadas.

**Bloqueos en instancias de lectura**  
Puede haber un conflicto entre los bloqueos de relaciones que mantienen el escritor y los lectores. En la actualidad, solo los bloqueos de relaciones de `ACCESS EXCLUSIVE` se replican en instancias de lector. Sin embargo, el bloqueo de relaciones `ACCESS EXCLUSIVE` entrará en conflicto con cualquier bloqueo de relaciones `ACCESS SHARE` que mantenga el lector. Esto puede provocar un aumento de los eventos de espera de las relaciones de bloqueo en el lector. 

## Acciones
<a name="wait-event.lockrelation.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Reducir el impacto de las instrucciones SQL que se bloquean
](#wait-event.lockrelation.actions.reduce-blocks)
+ [

### Minimizar el efecto de las operaciones de mantenimiento
](#wait-event.lockrelation.actions.maintenance)

### Reducir el impacto de las instrucciones SQL que se bloquean
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

Para reducir el impacto de las instrucciones SQL que se bloquean, modifique el código de su aplicación cuando sea posible. A continuación se presentan dos técnicas comunes para reducir los bloqueos:
+ Utilizar la opción `NOWAIT`: algunos comandos SQL, como las instrucciones `SELECT` y `LOCK`, admiten esta opción. La directiva `NOWAIT` cancela la consulta que solicita el bloqueo si éste no puede adquirirse inmediatamente. Esta técnica puede ayudar a evitar que una sesión bloqueada provoque una acumulación de sesiones bloqueadas detrás de ella.

  Por ejemplo: Supongamos que la transacción A espera un bloqueo que tiene la transacción B. Ahora, si B solicita un bloqueo en una tabla que está bloqueada por la transacción C, la transacción A podría quedar bloqueada hasta que la transacción C finalice. Pero si la transacción B utiliza un `NOWAIT` cuando solicita el bloqueo en C, puede fallar rápido y asegurar que la transacción A no tenga que esperar de forma indefinida.
+ Utilice `SET lock_timeout`: establezca un valor de `lock_timeout` para limitar el tiempo que una sentencia SQL espera para adquirir un bloqueo en una relación. Si el bloqueo no se adquiere dentro del tiempo de espera especificado, la transacción que solicita el bloqueo se cancela. Establezca este valor en la sesión.

### Minimizar el efecto de las operaciones de mantenimiento
<a name="wait-event.lockrelation.actions.maintenance"></a>

Las operaciones de mantenimiento como `VACUUM` y `ANALYZE` son importantes. Le recomendamos que no las desactive ya que encontrará eventos de espera `Lock:Relation` relacionados con estas operaciones de mantenimiento. Los siguientes enfoques pueden minimizar el efecto de estas operaciones:
+ Ejecute las operaciones de mantenimiento de forma manual durante las horas de menor actividad.
+ Para reducir las esperas de `Lock:Relation` causadas por las tareas de autovacuum, realice los ajustes de autovacuum necesarios. Para obtener información sobre el ajuste de autovacuum, consulte [Trabajo con Autovacuum de PostgreSQL en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) en la *Guía del usuario de Amazon RDS*.

# Lock:transactionid
<a name="wait-event.locktransactionid"></a>

El evento `Lock:transactionid` se produce cuando una transacción espera un bloqueo a nivel de fila.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.locktransactionid.context.supported)
+ [

## Contexto
](#wait-event.locktransactionid.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.locktransactionid.causes)
+ [

## Acciones
](#wait-event.locktransactionid.actions)

## Versiones del motor admitidas
<a name="wait-event.locktransactionid.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Contexto
<a name="wait-event.locktransactionid.context"></a>

El evento `Lock:transactionid` ocurre cuando una transacción intenta adquirir un bloqueo a nivel de fila que ya fue otorgado a una transacción que se está ejecutando al mismo tiempo. La sesión que muestra el evento de espera `Lock:transactionid` se encuentra bloqueada debido a este bloqueo. Después de que la transacción bloqueada termine con una instrucción `COMMIT` o `ROLLBACK`, la transacción bloqueada puede continuar.

La semántica de control de concurrencia multiversión de RDS para PostgreSQL garantiza que los lectores no bloqueen a los escritores y que los escritores no bloqueen a los lectores. ara que se produzcan conflictos en las filas, las transacciones bloqueantes y bloqueadas deben emitir instrucciones conflictivas de los siguientes tipos:
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

La instrucción `SELECT … FOR KEY SHARE` es un caso especial. La base de datos utiliza la cláusula `FOR KEY SHARE` para optimizar el rendimiento de la integridad referencial. Un bloqueo en una fila puede bloquear los comandos `INSERT`, `UPDATE` y `DELETE` en otras tablas que hacen referencia a la fila.

## Causas probables del aumento de las esperas
<a name="wait-event.locktransactionid.causes"></a>

Cuando este evento aparece más de lo normal, la causa suele ser instrucciones `UPDATE`, `SELECT … FOR UPDATE` o `SELECT … FOR KEY SHARE` combinadas con las siguientes condiciones.

**Topics**
+ [

### Gran concurrencia
](#wait-event.locktransactionid.concurrency)
+ [

### Inactividad en la transacción
](#wait-event.locktransactionid.idle)
+ [

### Transacciones de larga duración
](#wait-event.locktransactionid.long-running)

### Gran concurrencia
<a name="wait-event.locktransactionid.concurrency"></a>

RDS para PostgreSQL puede utilizar una semántica de bloqueo pormenorizada por filas. La probabilidad de conflictos entre filas aumenta cuando se cumplen las siguientes condiciones:
+ Una carga de trabajo de gran concurrencia compite por las mismas filas.
+ Aumenta la concurrencia.

### Inactividad en la transacción
<a name="wait-event.locktransactionid.idle"></a>

A veces la columna `pg_stat_activity.state` muestra el valor `idle in transaction`. Este valor aparece para las sesiones que iniciaron una transacción, pero aún no han emitido un `COMMIT` o `ROLLBACK`. Si el valor de `pg_stat_activity.state` no se encuentra `active`, la consulta mostrada en `pg_stat_activity` es la más reciente en terminar de ejecutarse. La sesión de bloqueo no se encuentra en proceso activo de una consulta porque una transacción abierta está manteniendo un bloqueo.

Si una transacción inactiva adquirió un bloqueo entre filas, puede impedir que otras sesiones lo adquieran. Esta condición conduce a la aparición frecuente del evento de espera `Lock:transactionid`. Para diagnosticar el problema, examine la salida de `pg_stat_activity` y `pg_locks`.

### Transacciones de larga duración
<a name="wait-event.locktransactionid.long-running"></a>

Las transacciones que se ejecutan durante mucho tiempo obtienen bloqueos durante mucho tiempo. Estos bloqueos de larga duración pueden bloquear la ejecución de otras transacciones.

## Acciones
<a name="wait-event.locktransactionid.actions"></a>

El bloqueo de filas es un conflicto entre las instrucciones `UPDATE`, `SELECT … FOR UPDATE`, o `SELECT … FOR KEY SHARE`. Antes de intentar una solución, averigüe cuándo se están ejecutando estas instrucciones en la misma fila. Utilice esta información para elegir una estrategia descrita en las siguientes secciones.

**Topics**
+ [

### Responder a la alta concurrencia
](#wait-event.locktransactionid.actions.problem)
+ [

### Responder a las transacciones inactivas
](#wait-event.locktransactionid.actions.find-blocker)
+ [

### Responder a las transacciones de larga duración
](#wait-event.locktransactionid.actions.concurrency)

### Responder a la alta concurrencia
<a name="wait-event.locktransactionid.actions.problem"></a>

Si el problema es la concurrencia, pruebe una de las siguientes técnicas:
+ Reduzca la concurrencia en la aplicación. Por ejemplo, disminuya el número de sesiones activas.
+ Implemente un grupo de conexiones. Para saber cómo agrupar conexiones con RDS Proxy, consulte [Amazon RDS Proxy ](rds-proxy.md).
+ Diseñe la aplicación o el modelo de datos para evitar las instrucciones `UPDATE` y `SELECT … FOR UPDATE` en conflicto. También puede disminuir el número de claves foráneas a las que se accede mediante instrucciones `SELECT … FOR KEY SHARE`.

### Responder a las transacciones inactivas
<a name="wait-event.locktransactionid.actions.find-blocker"></a>

Si `pg_stat_activity.state` muestra una transacción `idle in transaction`, utilice las siguientes estrategias:
+ Active la confirmación automática siempre que sea posible. Este enfoque evita que las transacciones bloqueen otras transacciones mientras esperan un `COMMIT` o `ROLLBACK`.
+ Busque rutas de código en las que falten `COMMIT`, `ROLLBACK` o `END`.
+ Asegúrese de que la lógica de manejo de excepciones en su aplicación siempre tiene una ruta hacia válido `end of transaction`.
+ Asegúrese de que su aplicación procesa los resultados de la consulta después de finalizar la transacción con `COMMIT` o `ROLLBACK`.

### Responder a las transacciones de larga duración
<a name="wait-event.locktransactionid.actions.concurrency"></a>

Si las transacciones de larga duración provocan la aparición frecuente de `Lock:transactionid`, pruebe las siguientes estrategias:
+ Mantenga los bloqueos de filas fuera de las transacciones de larga duración.
+ Limite la longitud de las consultas mediante la implementación de confirmación automática siempre que sea posible.

# Lock:tuple
<a name="wait-event.locktuple"></a>

El evento `Lock:tuple` se produce cuando un proceso backend espera adquirir un bloqueo sobre una tupla.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.locktuple.context.supported)
+ [

## Context
](#wait-event.locktuple.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.locktuple.causes)
+ [

## Acciones
](#wait-event.locktuple.actions)

## Versiones del motor admitidas
<a name="wait-event.locktuple.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Context
<a name="wait-event.locktuple.context"></a>

El evento `Lock:tuple` indica que un backend espera adquirir un bloqueo sobre una tupla mientras otro backend mantiene un bloqueo conflictivo sobre la misma tupla. La siguiente tabla ilustra un escenario en el que las sesiones generan el evento `Lock:tuple`.


|  Tiempo  |  Sesión 1  |  Sesión 2  |  Sesión 3  | 
| --- | --- | --- | --- | 
|  t1  |  Inicia una transacción.  |    |    | 
|  t2  |  Actualiza la fila 1.  |    |    | 
|  t3  |    |  Actualiza la fila 1. La sesión adquiere un bloqueo exclusivo sobre la tupla y luego espera a que la sesión 1 libere el bloqueo mediante la confirmación o reversión.  |    | 
|  t4  |    |    |  Actualiza la fila 1. La sesión espera a que la sesión 2 libere el bloqueo exclusivo en la tupla.  | 

También puede simular este evento de espera con la herramienta de punto de referencia `pgbench`. Configure un alto número de sesiones concurrentes para actualizar la misma fila en una tabla con un archivo SQL personalizado.

Para obtener más información sobre los modos de bloqueo conflictivos, consulte [E](https://www.postgresql.org/docs/current/explicit-locking.html) en la documentación de PostgreSQL. Para más información sobre `pgbench`, consulte [pgbench](https://www.postgresql.org/docs/current/pgbench.html) en la documentación de PostgreSQL.

## Causas probables del aumento de las esperas
<a name="wait-event.locktuple.causes"></a>

Cuando este evento aparece más de lo normal, lo que posiblemente indica un problema de rendimiento, las causas típicas son las siguientes:
+ Un gran número de sesiones concurrentes están intentando adquirir un bloqueo conflictivo para la misma tupla al ejecutar instrucciones `UPDATE` o `DELETE`.
+ Las sesiones altamente concurrentes se encuentran en ejecución con una instrucción `SELECT` que utiliza los modos de bloqueo `FOR UPDATE` o `FOR NO KEY UPDATE`.
+ Varios factores hacen que la aplicación o los grupos de conexión abran más sesiones para ejecutar las mismas operaciones. A medida que nuevas sesiones intentan modificar las mismas filas, la carga de la base de datos puede aumentar y puede aparecer `Lock:tuple`.

Para más información, consulte [Row-Level Locks](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS) en la documentación de PostgreSQL.

## Acciones
<a name="wait-event.locktuple.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Investigue la lógica de su aplicación
](#wait-event.locktuple.actions.problem)
+ [

### Encontrar la sesión bloqueadora
](#wait-event.locktuple.actions.find-blocker)
+ [

### Reducir la concurrencia cuando es alta
](#wait-event.locktuple.actions.concurrency)
+ [

### Solucionar los cuellos de botella
](#wait-event.locktuple.actions.bottlenecks)

### Investigue la lógica de su aplicación
<a name="wait-event.locktuple.actions.problem"></a>

Verifique si una sesión del bloqueador se encuentra en el estado `idle in transaction` por mucho tiempo. Si es así, considere la posibilidad de finalizar la sesión del bloqueador como una solución a corto plazo. Puede utilizar la función `pg_terminate_backend`. Para más información sobre esta función, consulte [Server Signaling Functions](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL) en la documentación de PostgreSQL.

Para una solución a largo plazo, haga lo siguiente:
+ Ajuste la lógica de la aplicación.
+ Utilice el parámetro `idle_in_transaction_session_timeout`. Este parámetro finaliza cualquier sesión con una transacción abierta que haya estado inactiva durante más tiempo del especificado. Para más información, consulte [Client Connection Defaults](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT) en la documentación de PostgreSQL.
+ Utilice la confirmación automática en la medida de lo posible. Para más información, consulte [SET AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html) en la documentación de PostgreSQL.

### Encontrar la sesión bloqueadora
<a name="wait-event.locktuple.actions.find-blocker"></a>

Mientras se produce el evento de espera `Lock:tuple`, identifique el bloqueador y la sesión bloqueada mediante la búsqueda de los bloqueos que dependen unos de otros. Para más información, consulte la [Información sobre dependencia de bloqueos](https://wiki.postgresql.org/wiki/Lock_dependency_information) en el wiki de PostgreSQL. 

El siguiente ejemplo muestra todas las sesiones, con un filtro `tuple` y ordenadas por `wait_time`.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

### Reducir la concurrencia cuando es alta
<a name="wait-event.locktuple.actions.concurrency"></a>

El evento `Lock:tuple` puede producirse de manera frecuente, especialmente en un momento de carga de trabajo elevada. En esta situación, considere reducir la alta concurrencia para las filas muy ocupadas. A menudo, solo unas pocas filas controlan una cola o la lógica booleana, lo que hace que estas filas estén muy ocupadas.

Puede reducir la concurrencia mediante el uso de diferentes enfoques basados en los requisitos de la empresa, lógica de la aplicación y tipo de carga de trabajo. Por ejemplo, puede hacer lo siguiente:
+ Rediseñar la lógica de la tabla y los datos para reducir la alta concurrencia.
+ Cambiar la lógica de la aplicación para reducir la alta concurrencia entre filas.
+ Aprovechar y rediseñar las consultas con bloqueos entre filas.
+ Utilizar la cláusula `NOWAIT` con operaciones de reintento.
+ Considerar el uso de control de concurrencia optimista y de lógica de bloqueo híbrida.
+ Considerar la posibilidad de cambiar el nivel de aislamiento de la base de datos.

### Solucionar los cuellos de botella
<a name="wait-event.locktuple.actions.bottlenecks"></a>

La `Lock:tuple` producirse con cuellos de botella, como el agotamiento de la CPU o el uso máximo del ancho de banda de Amazon EBS. Para reducir los cuellos de botella, considere los siguientes enfoques:
+ Escalar verticalmente el tipo de clase de instancia.
+ Optimizar las consultas que consumen muchos recursos.
+ Cambiar la lógica de la aplicación.
+ Archivar los datos a los que rara vez se accede.

# LWLock:BufferMapping (LWLock:buffer\$1mapping)
<a name="wait-event.lwl-buffer-mapping"></a>

Este evento se produce cuando una sesión espera asociar un bloque de datos con un búfer en el grupo de búferes compartidos.

**nota**  
Para la versión 13 y posteriores de RDS para PostgreSQL, el nombre de este evento es `LWLock:BufferMapping`. Para la versión 12 y posteriores de RDS para PostgreSQL, el nombre de este evento es `LWLock:buffer_mapping`. 

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.lwl-buffer-mapping.context.supported)
+ [

## Contexto
](#wait-event.lwl-buffer-mapping.context)
+ [

## Causas
](#wait-event.lwl-buffer-mapping.causes)
+ [

## Acciones
](#wait-event.lwl-buffer-mapping.actions)

## Versiones del motor admitidas
<a name="wait-event.lwl-buffer-mapping.context.supported"></a>

La información del evento de espera es relevante para RDS para PostgreSQL versión 9.6 y posteriores.

## Contexto
<a name="wait-event.lwl-buffer-mapping.context"></a>

El *grupo de búferes compartidos* es un área de memoria de PostgreSQL que contiene todas las páginas que utilizan o utilizaban los procesos. Cuando un proceso necesita una página, lee la página en el grupo de búferes compartidos. El parámetro `shared_buffers` establece el tamaño del búfer compartido y reserva un área de memoria para almacenar las páginas de tablas e índices. Si cambia este parámetro, asegúrese de reiniciar la base de datos.

El evento de espera `LWLock:buffer_mapping` ocurre en los siguientes escenarios:
+ Un proceso busca una página en la tabla de búferes y adquiere un bloqueo de asignación de búferes compartidos.
+ Un proceso carga una página en el grupo de búferes y adquiere un bloqueo de asignación de búferes exclusivo.
+ Un proceso elimina una página del grupo y adquiere un bloqueo de asignación de búferes exclusivo.

## Causas
<a name="wait-event.lwl-buffer-mapping.causes"></a>

Cuando este evento aparece más de lo normal, lo que puede indicar un problema de rendimiento, la base de datos entra y sale del grupo de búferes compartidos. Las causas típicas son las siguientes:
+ Consultas grandes
+ Índices y tablas sobrecargados
+ Escaneos completos de tablas
+ Un tamaño del grupo compartido menor que el conjunto de trabajo

## Acciones
<a name="wait-event.lwl-buffer-mapping.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [

### Monitorear las métricas relacionadas con el buffer
](#wait-event.lwl-buffer-mapping.actions.monitor-metrics)
+ [

### Evaluar la estrategia de indexación
](#wait-event.lwl-buffer-mapping.actions.indexes)
+ [

### Reducir el número de búferes que deben ser asignados rápidamente
](#wait-event.lwl-buffer-mapping.actions.buffers)

### Monitorear las métricas relacionadas con el buffer
<a name="wait-event.lwl-buffer-mapping.actions.monitor-metrics"></a>

Cuando las esperas de `LWLock:buffer_mapping` se disparan, hay que investigar la tasa de aciertos del búfer. Puede utilizar estas métricas para comprender mejor lo que ocurre en la caché del búfer. Examina las siguientes métricas:

`blks_hit`  
Esta métrica del contador de Información sobre rendimiento indica el número de bloques que se recuperaron del grupo de búferes compartidos. Después de que aparezca el evento de espera `LWLock:buffer_mapping`, se puede observar un pico en `blks_hit`.

`blks_read`  
Esta métrica del contador de Información sobre rendimiento indica el número de bloques que requirieron E/S para leerse en el grupo de búferes compartidos. Puede observar un pico en `blks_read` en el periodo previo al evento de espera `LWLock:buffer_mapping`.

### Evaluar la estrategia de indexación
<a name="wait-event.lwl-buffer-mapping.actions.indexes"></a>

Para confirmar que la estrategia de indexación no disminuye el rendimiento, verifique lo siguiente:

Sobrecarga del índice  
Asegúrese de que el índice y la sobrecarga de la tabla no provocan la lectura de páginas innecesarias en el búfer compartido. Si las tablas contienen filas que no se utilizan, considere la posibilidad de archivar los datos y eliminar las filas de las tablas. A continuación, puede reconstruir los índices para las tablas redimensionadas.

Índices para consultas de uso frecuente  
Para determinar si cuenta con los índices óptimos, monitoree las métricas del motor de base de datos en Información sobre rendimiento. La métrica `tup_returned` muestra el número de filas leídas. La métrica `tup_fetched` muestra el número de filas devueltas al cliente. Si `tup_returned` es mucho mayor que `tup_fetched`, es posible que los datos no estén bien indexados. Además, es posible que las estadísticas de la tabla no se encuentren actualizadas.

### Reducir el número de búferes que deben ser asignados rápidamente
<a name="wait-event.lwl-buffer-mapping.actions.buffers"></a>

Para reducir los eventos de espera de `LWLock:buffer_mapping`, intente reducir el número de búferes que se deben asignar de forma rápida. Una estrategia es hacer operaciones por lotes más pequeños. Se pueden conseguir lotes más pequeños por medio de la partición de las tablas.

# LWLock:BufferIO (IPC:BufferIO)
<a name="wait-event.lwlockbufferio"></a>

El evento `LWLock:BufferIO` ocurre cuando RDS para PostgreSQL espera que otros procesos terminen sus operaciones de entrada/salida (E/S) cuando intentan acceder a una página de forma simultánea. Su propósito es que la misma página se lea en el búfer compartido.

**Topics**
+ [

## Versiones del motor relevantes
](#wait-event.lwlockbufferio.context.supported)
+ [

## Context
](#wait-event.lwlockbufferio.context)
+ [

## Causas
](#wait-event.lwlockbufferio.causes)
+ [

## Acciones
](#wait-event.lwlockbufferio.actions)

## Versiones del motor relevantes
<a name="wait-event.lwlockbufferio.context.supported"></a>

Esta información de eventos de espera es relevante para todas las versiones de RDS para PostgreSQL. Para RDS para PostgreSQL 12 y versiones anteriores, este evento de espera se denomina lwlock:buffer\$1io, mientras que en la versión 13 de RDS para PostgreSQL se denomina lwlock:bufferio. A partir de la versión 14 de RDS para PostgreSQL, el evento de espera BufferIO se movió de tipo de evento de espera `LWLock` a `IPC` (IPC:bufferIO). 

## Context
<a name="wait-event.lwlockbufferio.context"></a>

Cada búfer compartido tiene un bloqueo de E/S que está asociado con el evento de espera `LWLock:BufferIO`, cada vez que un bloque (o una página) se tiene que recuperar fuera del grupo de búferes compartidos.

Este bloqueo se utiliza para manejar múltiples sesiones que requieren acceso al mismo bloque. Este bloque se tiene que leer desde fuera del grupo de búferes compartidos, que se define con el parámetro `shared_buffers`.

Tan pronto como la página se lee dentro del grupo de búferes compartidos, el bloqueo `LWLock:BufferIO` se libera.

**nota**  
El evento de espera `LWLock:BufferIO` precede al evento de espera [IO:DataFileRead](wait-event.iodatafileread.md). El evento de espera `IO:DataFileRead` se produce mientras se leen datos del almacenamiento.

Para obtener más información sobre los bloqueos ligeros, consulte [Información general sobre los bloqueos](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20).

## Causas
<a name="wait-event.lwlockbufferio.causes"></a>

Las causas más comunes para que el evento `LWLock:BufferIO` aparezca en el máximo de esperas son las siguientes:
+ Varios backends o conexiones que intentan acceder a la misma página que también tiene pendiente una operación de E/S
+ La relación entre el tamaño del grupo de búferes compartidos (definido por el parámetro `shared_buffers`) y el número de búferes que necesita la carga de trabajo actual
+ El tamaño del grupo de búferes compartidos no está bien equilibrado con el número de páginas que se desalojan por otras operaciones
+ Índices grandes o sobrecargados que requieren que el motor lea más páginas de las necesarias en el grupo de búferes compartidos
+ La falta de índices obliga al motor de la base de datos a leer más páginas de las necesarias en las tablas
+ Puntos de control que se producen con demasiada frecuencia o que necesitan vaciar demasiadas páginas modificadas
+ Picos repentinos de conexiones a la base de datos que intentan hacer operaciones en la misma página

## Acciones
<a name="wait-event.lwlockbufferio.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera:
+ Observe las métricas de Amazon CloudWatch en busca de una correlación entre los descensos bruscos de los eventos de espera `BufferCacheHitRatio` y `LWLock:BufferIO`. Este efecto a veces significa que tiene una configuración de búferes compartidos pequeña. Puede que tenga que aumentarla o escalar verticalmente la clase de instancia de base de datos. Puede dividir su carga de trabajo en más nodos de lectura.
+ Ajuste `max_wal_size` y `checkpoint_timeout` en función del tiempo de pico de su carga de trabajo si ve que `LWLock:BufferIO` coincide con las caídas de la métrica `BufferCacheHitRatio`. A continuación, identifique qué consulta puede ser la causa.
+ Verifique si tiene índices sin utilizar y elimínelos.
+ Utilice tablas particionadas (que también tengan índices particionados). Esto ayuda a mantener un bajo nivel de reordenación de índices y reduce su impacto.
+ Evite indexar columnas innecesariamente.
+ Evite los picos repentinos de conexión a la base de datos, utilice un grupo de conexiones.
+ Limite el número máximo de conexiones a la base de datos como práctica recomendada.

# LWLock:buffer\$1content (BufferContent)
<a name="wait-event.lwlockbuffercontent"></a>

El evento `LWLock:buffer_content` ocurre cuando una sesión espera para leer o escribir una página de datos en memoria mientras otra sesión tiene esa página bloqueada para escribir. En RDS para PostgreSQL 13 y versiones posteriores, este evento de espera se llama `BufferContent`.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.lwlockbuffercontent.context.supported)
+ [

## Context
](#wait-event.lwlockbuffercontent.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.lwlockbuffercontent.causes)
+ [

## Acciones
](#wait-event.lwlockbuffercontent.actions)

## Versiones del motor admitidas
<a name="wait-event.lwlockbuffercontent.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Context
<a name="wait-event.lwlockbuffercontent.context"></a>

Para leer o manipular datos, PostgreSQL accede a ellos a través de búferes de memoria compartida. Para leer del búfer, un proceso obtiene un bloqueo ligero (LWLock) sobre el contenido del búfer en modo compartido. Para escribir en el búfer, obtiene ese bloqueo en modo exclusivo. Los bloqueos compartidos permiten a otros procesos adquirir simultáneamente bloqueos compartidos sobre ese contenido. Los bloqueos exclusivos impiden que otros procesos obtengan cualquier tipo de bloqueo sobre él.

El evento `LWLock:buffer_content` (`BufferContent`) indica que varios procesos intentan obtener un bloqueo sobre el contenido de un búfer específico.

## Causas probables del aumento de las esperas
<a name="wait-event.lwlockbuffercontent.causes"></a>

Cuando el evento `LWLock:buffer_content` (`BufferContent`) aparece más de lo normal, lo que posiblemente indica un problema de rendimiento, las causas típicas son las siguientes:

**Aumento de las actualizaciones simultáneas de los mismos datos**  
Puede haber un aumento en el número de sesiones concurrentes con consultas que actualizan el mismo contenido del búfer. Esta contención puede ser más pronunciada en tablas con muchos índices.

**Los datos de carga de trabajo no están en la memoria**  
Cuando los datos que la carga de trabajo activa está procesando no están en memoria, estos eventos de espera pueden aumentar. Este efecto se debe a que los procesos que mantienen bloqueos pueden mantenerlos durante más tiempo mientras hacen operaciones de E/S en disco.

**Uso excesivo de restricciones de clave externa**  
Las restricciones de clave externa pueden aumentar el tiempo que un proceso mantiene un bloqueo de contenido de búfer. Este efecto se debe a que las operaciones de lectura requieren un bloqueo de contenido de búfer compartido en la clave referenciada mientras se actualiza dicha clave.

## Acciones
<a name="wait-event.lwlockbuffercontent.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera. Puede identificar los eventos `LWLock:buffer_content` (`BufferContent`) mediante Información sobre rendimiento de Amazon RDS o consultar la vista `pg_stat_activity`.

**Topics**
+ [

### Mejorar la eficiencia en memoria
](#wait-event.lwlockbuffercontent.actions.in-memory)
+ [

### Reducir el uso de restricciones de clave externa
](#wait-event.lwlockbuffercontent.actions.foreignkey)
+ [

### Eliminar los índices que no se utilizan
](#wait-event.lwlockbuffercontent.actions.indexes)
+ [

### Aumentar el tamaño de la memoria caché al utilizar secuencias
](#wait-event.lwlockbuffercontent.actions.sequences)

### Mejorar la eficiencia en memoria
<a name="wait-event.lwlockbuffercontent.actions.in-memory"></a>

Para aumentar la posibilidad de que los datos de la carga de trabajo activa estén en memoria, particione las tablas o escale verticalmente su clase de instancia. Para obtener información acerca de las clases de instancia de base de datos, consulte [Clases de instancia de base de datos de ](Concepts.DBInstanceClass.md).

### Reducir el uso de restricciones de clave externa
<a name="wait-event.lwlockbuffercontent.actions.foreignkey"></a>

Examine las cargas de trabajo que experimentan un elevado número de eventos de espera `LWLock:buffer_content` (`BufferContent`) para comprobar el uso de las restricciones de clave externa. Elimine las restricciones de clave externa innecesarias.

### Eliminar los índices que no se utilizan
<a name="wait-event.lwlockbuffercontent.actions.indexes"></a>

Para las cargas de trabajo que experimentan un gran número de eventos de espera `LWLock:buffer_content` (`BufferContent`), identifique los índices que no se utilizan y elimínelos.

### Aumentar el tamaño de la memoria caché al utilizar secuencias
<a name="wait-event.lwlockbuffercontent.actions.sequences"></a>

Si las tablas usan secuencias, aumente el tamaño de la memoria caché para eliminar la contención en las páginas de secuencias y las páginas de índice. Cada secuencia es una página individual en la memoria compartida. La memoria caché predefinida es por conexión. Es posible que esto no sea suficiente para gestionar la carga de trabajo cuando muchas sesiones simultáneas reciben un valor de secuencia. 

# LWLock:lock\$1manager (LWLock:lockmanager)
<a name="wait-event.lw-lock-manager"></a>

Este evento ocurre cuando el motor de RDS para PostgreSQL mantiene el área de memoria del bloqueo compartido para asignar, verificar y desasignar un bloqueo cuando no es posible un bloqueo de ruta rápida.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.lw-lock-manager.context.supported)
+ [

## Contexto
](#wait-event.lw-lock-manager.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.lw-lock-manager.causes)
+ [

## Acciones
](#wait-event.lw-lock-manager.actions)

## Versiones del motor admitidas
<a name="wait-event.lw-lock-manager.context.supported"></a>

La información del evento de espera es relevante para RDS para PostgreSQL versión 9.6 y posteriores. Para las versiones de RDS para PostgreSQL anteriores a la 13, el nombre de este evento de espera es `LWLock:lock_manager`. Para la versión 13 de RDS para PostgreSQL y posteriores, el nombre de este evento de espera es `LWLock:lockmanager`. 

## Contexto
<a name="wait-event.lw-lock-manager.context"></a>

Cuando se emite una instrucción SQL, RDS para PostgreSQL registra bloqueos para proteger la estructura, los datos y la integridad de la base de datos durante las operaciones simultáneas. El motor puede lograr este objetivo con un bloqueo de ruta rápido o con un bloqueo de ruta que no es rápido. Un bloqueo de ruta que no es rápido es más caro y crea más sobrecarga que un bloqueo de ruta rápido.

### Bloqueo rápido de la ruta
<a name="wait-event.lw-lock-manager.context.fast-path"></a>

Para reducir la sobrecarga de los bloqueos que se toman y liberan con frecuencia, pero que rara vez entran en conflicto, los procesos del backend pueden utilizar el bloqueo de ruta rápido. La base de datos utiliza este mecanismo para los bloqueos que cumplen los siguientes criterios:
+ Utilizan el método de bloqueo DEFAULT.
+ Representan un bloqueo en una relación de la base de datos y no en una relación compartida.
+ Son bloqueos débiles que probablemente no entren en conflicto.
+ El motor puede verificar rápidamente que no pueden existir bloqueos conflictivos.

El motor no puede utilizar el bloqueo de ruta rápida cuando se cumple alguna de las siguientes condiciones:
+ El bloqueo no cumple los criterios anteriores.
+ No hay más ranuras disponibles para el proceso de backend.

Para ajustar las consultas para que se bloqueen rápidamente, puede utilizar la siguiente consulta.

```
SELECT count(*), pid, mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 4,3,2
 ORDER BY pid, mode;
 count | pid  |      mode       | fastpath
-------+------+-----------------+----------
16 | 9185 | AccessShareLock | t
336 | 9185 | AccessShareLock | f
1 | 9185 | ExclusiveLock   | t
```

La siguiente consulta muestra solo el total de la base de datos.

```
SELECT count(*), mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 3,2
 ORDER BY mode,1;
count |      mode       | fastpath
-------+-----------------+----------
16 | AccessShareLock | t
337 | AccessShareLock | f
1 | ExclusiveLock   | t
(3 rows)
```

Para más información sobre el bloqueo de ruta rápida, consulte [fast path](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76) en el README del administrador de bloqueos de PostgreSQL y [pg-locks](https://www.postgresql.org/docs/9.3/view-pg-locks.html#AEN98195) en la documentación de PostgreSQL. 

### Ejemplo de un problema de escalado para el administrador de bloqueos
<a name="wait-event.lw-lock-manager.context.lock-manager"></a>

En este ejemplo, una tabla con el nombre `purchases` almacena cinco años de datos, particionados por día. Cada partición tiene dos índices. Se produce la siguiente secuencia de eventos:

1. Se consultan los datos de muchos días, lo que requiere que la base de datos lea muchas particiones.

1. La base de datos crea una entrada de bloqueo para cada partición. Si los índices de las particiones forman parte de la ruta de acceso del optimizador, la base de datos también crea una entrada de bloqueo para ellos.

1. Cuando el número de entradas de bloqueo solicitadas para el mismo proceso backend es superior a 16, que es el valor `FP_LOCK_SLOTS_PER_BACKEND`, el administrador de bloqueos utiliza el método de bloqueo de ruta no rápida.

Las aplicaciones modernas pueden tener cientos de sesiones. Si las sesiones simultáneas consultan la base de datos principal sin una poda adecuada de las particiones, la base de datos puede crear cientos o incluso miles de bloqueos de ruta no rápida. Normalmente, cuando esta simultaneidad es mayor que el número de vCPU, aparece el evento de espera `LWLock:lock_manager`.

**nota**  
El evento de espera `LWLock:lock_manager` no está relacionado con el número de particiones o índices en un esquema de base de datos. En cambio, está relacionado con el número de bloqueos de rutas no rápidas que la base de datos debe controlar.

## Causas probables del aumento de las esperas
<a name="wait-event.lw-lock-manager.causes"></a>

Cuando el evento de espera `LWLock:lock_manager` ocurre más de lo normal, lo que posiblemente indica un problema de rendimiento, las causas más probables de los picos repentinos son las siguientes:
+ Las sesiones activas simultáneas ejecutan consultas que no utilizan bloqueos de ruta rápida. Estas sesiones también exceden el máximo de vCPU.
+ Un gran número de sesiones activas simultáneas acceden a una tabla con muchas particiones. Cada partición tiene múltiples índices.
+ La base de datos está experimentando una tormenta de conexiones. De forma predeterminada, algunas aplicaciones y software de grupo de conexiones crean más conexiones cuando la base de datos es lenta. Esta práctica empeora el problema. Ajuste el software de grupo de conexiones para que no se produzcan tormentas de conexiones.
+ Un gran número de sesiones consultan una tabla principal sin borrar particiones.
+ Un lenguaje de definición de datos (DDL), un lenguaje de manipulación de datos (DML) o un comando de mantenimiento bloquea exclusivamente una relación ocupada o tuplas a las que se accede o modifica con frecuencia.

## Acciones
<a name="wait-event.lw-lock-manager.actions"></a>

Si se produce el evento de espera `CPU`, no indica necesariamente un problema de rendimiento. Responda a este evento solo cuando el rendimiento disminuya y este evento de espera domine la carga de la base de datos.

**Topics**
+ [

### Utilizar la poda de particiones
](#wait-event.lw-lock-manager.actions.pruning)
+ [

### Eliminar índices innecesarios
](#wait-event.lw-lock-manager.actions.indexes)
+ [

### Ajustar sus consultas para el bloqueo rápido de rutas
](#wait-event.lw-lock-manager.actions.tuning)
+ [

### Ajustar otros eventos de espera
](#wait-event.lw-lock-manager.actions.other-waits)
+ [

### Reducir los cuellos de botella del hardware
](#wait-event.lw-lock-manager.actions.hw-bottlenecks)
+ [

### Utilizar un grupo de conexiones
](#wait-event.lw-lock-manager.actions.pooler)
+ [

### Actualización de la versión de RDS para PostgreSQL
](#wait-event.lw-lock-manager.actions.pg-version)

### Utilizar la poda de particiones
<a name="wait-event.lw-lock-manager.actions.pruning"></a>

La *poda de particiones* es una estrategia de optimización de consultas para tablas partidas de forma declarativa que excluye las particiones innecesarias de los escaneos de tablas, lo que mejora el rendimiento. La poda de particiones está activada de forma predeterminada. Si está desactivada, actívela de la siguiente manera.

```
SET enable_partition_pruning = on;
```

Las consultas pueden aprovechar la poda de particiones cuando la cláusula `WHERE` contiene la columna que se utiliza para la partición. Para más información, consulte [Partition Pruningc](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING) en la documentación de PostgreSQL.

### Eliminar índices innecesarios
<a name="wait-event.lw-lock-manager.actions.indexes"></a>

Es posible que la base de datos contenga índices que no se utilicen o que se utilicen muy poco. Si es así, considere eliminarlos. Haga una de estas dos operaciones:
+ Aprenda a encontrar índices innecesarios al leer [Índices no utilizados](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes) en el wiki de PostgreSQL.
+ Ejecute PG Collector. Este script SQL recopila información de la base de datos y la presenta en un informe HTML consolidado. Verifique la sección “Índices no utilizados”. Para más información, consulte [pg-collector](https://github.com/awslabs/pg-collector) en el repositorio GitHub de AWS Labs.

### Ajustar sus consultas para el bloqueo rápido de rutas
<a name="wait-event.lw-lock-manager.actions.tuning"></a>

Para averiguar si las consultas utilizan el bloqueo de ruta rápida, consulte la columna `fastpath` en la tabla `pg_locks`. Si las consultas no utilizan el bloqueo de ruta rápida, intente reducir el número de relaciones por consulta a menos de 16.

### Ajustar otros eventos de espera
<a name="wait-event.lw-lock-manager.actions.other-waits"></a>

Si `LWLock:lock_manager` es el primero o el segundo en la lista de esperas principales, verifique si los siguientes eventos de espera también aparecen en la lista:
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

Si los eventos anteriores aparecen en primer lugar en la lista, considere la posibilidad de ajustar estos eventos de espera en primer lugar. Estos eventos pueden ser un controlador para `LWLock:lock_manager`.

### Reducir los cuellos de botella del hardware
<a name="wait-event.lw-lock-manager.actions.hw-bottlenecks"></a>

Es posible que tenga un cuello de botella en el hardware, como el agotamiento de la CPU o el uso máximo de su ancho de banda de Amazon EBS. En estos casos, considere la posibilidad de reducir los cuellos de botella de hardware. Considere las siguientes acciones:
+ Escalar verticalmente la clase de instancia.
+ Optimizar las consultas que consumen grandes cantidades de CPU y memoria.
+ Cambiar la lógica de su aplicación.
+ Archivar los datos.

Para más información sobre la CPU, memoria y ancho de banda de red de EBS, consulte [Tipos de instancias de Amazon RDS](https://aws.amazon.com/rds/instance-types/).

### Utilizar un grupo de conexiones
<a name="wait-event.lw-lock-manager.actions.pooler"></a>

Si el número total de conexiones activas supera el máximo de vCPU, más procesos del sistema operativo requieren CPU de lo que su tipo de instancia puede admitir. En este caso, considere la posibilidad de utilizar o ajustar un grupo de conexiones. Para más información sobre las vCPU de su tipo de instancia, consulte [Tipos de instancias de Amazon RDS](https://aws.amazon.com/rds/instance-types/).

Para más información sobre la agrupación de conexiones, consulte los siguientes recursos:
+ [Amazon RDS Proxy ](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ [Connection Pools and Data Sources](https://www.postgresql.org/docs/7.4/jdbc-datasource.html) en la *documentación de PostgreSQL*

### Actualización de la versión de RDS para PostgreSQL
<a name="wait-event.lw-lock-manager.actions.pg-version"></a>

Si la versión actual de RDS para PostgreSQL es inferior a la 12, actualice a la versión 12 o posterior. Las versiones 12 y posteriores de PostgreSQL tienen un mecanismo de partición mejorado. Para más información sobre la versión 12, consulte las [Notas de la versión 12.0 de PostgreSQL]( https://www.postgresql.org/docs/release/12.0/). Para más información sobre la actualización de RDS para PostgreSQL, consulte [Actualizaciones del motor de base de datos de RDS para PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.md).

# LWLock:pg\$1stat\$1statements
<a name="apg-rpg-lwlockpgstat"></a>

El evento de espera LWLock:pg\$1stat\$1statements se produce cuando la extensión `pg_stat_statements` toma un bloqueo exclusivo en la tabla hash que rastrea las instrucciones SQL. Esto ocurre en las siguientes situaciones:
+ Cuando el número de instrucciones rastreadas alcanza el valor del parámetro `pg_stat_statements.max` configurado y es necesario dejar espacio para más entradas, la extensión realiza una clasificación del número de llamadas, elimina el 5 % de las instrucciones menos ejecutadas y vuelve a rellenar el hash con las entradas restantes.
+ Cuando `pg_stat_statements` realiza una operación de `garbage collection` en el archivo `pgss_query_texts.stat` del disco y lo vuelve a escribir.

**Topics**
+ [

## Versiones del motor admitidas
](#apg-rpg-lwlockpgstat.supported)
+ [

## Contexto
](#apg-rpg-lwlockpgstat.context)
+ [

## Causas probables del aumento de las esperas
](#apg-rpg-lwlockpgstat.causes)
+ [

## Acciones
](#apg-rpg-lwlockpgstat.actions)

## Versiones del motor admitidas
<a name="apg-rpg-lwlockpgstat.supported"></a>

 Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL. 

## Contexto
<a name="apg-rpg-lwlockpgstat.context"></a>

**Descripción de la extensión pg\$1stat\$1statements**: la extensión pg\$1stat\$1statements rastrea las estadísticas de ejecución de instrucción SQL en una tabla hash. La extensión rastrea las instrucciones SQL hasta el límite definido por el parámetro `pg_stat_statements.max`. Este parámetro determina el número máximo de instrucciones que se pueden rastrear, lo que corresponde al número máximo de filas en la vista de pg\$1stat\$1statements.

**Persistencia de las estadísticas de las instrucciones**: la extensión mantiene las estadísticas de las instrucciones a través de reinicios de instancia mediante:
+ Escritura de datos en un archivo llamado pg\$1stat\$1statements.stat
+ Uso del parámetro pg\$1stat\$1statements.save para controlar el comportamiento de persistencia

Cuando pg\$1stat\$1statements.save se establece en:
+ activado (predeterminado): las estadísticas se guardan al apagar el servidor y se vuelven a cargar al iniciar el servidor
+ desactivado (predeterminado): las estadísticas no se guardan al apagar el servidor ni se vuelven a cargar al iniciar el servidor

**Almacenamiento de texto de consulta**: la extensión almacena el texto de las consultas rastreadas en un archivo denominado `pgss_query_texts.stat`. Este archivo puede crecer hasta duplicar el tamaño medio de todas las instrucciones SQL rastreadas antes de que se produzca la recopilación de elementos no utilizados. La extensión requiere un bloqueo exclusivo en la tabla de hash durante las operaciones de limpieza y reescritura del archivo `pgss_query_texts.stat`.

**Proceso de desasignación de instrucciones**: cuando el número de instrucciones rastreadas alcanza el límite `pg_stat_statements.max` y es necesario realizar un seguimiento de las nuevas, la extensión:
+ Toma un bloqueo exclusivo (LWLock:pg\$1stat\$1statements) en la tabla de hash.
+ Carga los datos existentes en la memoria local.
+ Realiza una clasificación rápida en función del número de llamadas.
+ Elimina las instrucciones menos solicitadas (el 5 % inferior).
+ Vuelve a rellenar la tabla hash con las entradas restantes.

**Supervisión de la desasignación de instrucciones**: en PostgreSQL 14 y versiones posteriores, puede supervisar la desasignación de las instrucciones mediante la vista pg\$1stat\$1statements\$1info. Esta vista incluye una columna dealloc que muestra cuántas veces se desasignaron las instrucciones para dejar espacio a otras nuevas

Si la desasignación de las instrucciones se produce con frecuencia, se realizará con más frecuencia la recopilación de elementos no utilizados del archivo `pgss_query_texts.stat` en el disco.

## Causas probables del aumento de las esperas
<a name="apg-rpg-lwlockpgstat.causes"></a>

Entre las causas típicas del aumento de las esperas de `LWLock:pg_stat_statements` se incluyen las siguientes:
+ Un aumento en el número de consultas únicas utilizadas por la aplicación.
+ El valor del parámetro `pg_stat_statements.max` es pequeño en comparación con el número de consultas únicas que se utilizan.

## Acciones
<a name="apg-rpg-lwlockpgstat.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera. Puede identificar los eventos de `LWLock:pg_stat_statements` mediante Información de rendimiento de Amazon RDS o consultando la vista de `pg_stat_activity`.

Ajuste los siguientes parámetros `pg_stat_statements` para controlar el comportamiento de seguimiento y reducir los eventos de espera de las instrucciones LWLock:pg\$1stat\$1statements.

**Topics**
+ [

### Desactivación del parámetro pg\$1stat\$1statements.track
](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [

### Aumento del parámetro pg\$1stat\$1statements.max
](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [

### Desactivación del parámetro pg\$1stat\$1statements.track\$1utility
](#apg-rpg-lwlockpgstat.actions.disableutility)

### Desactivación del parámetro pg\$1stat\$1statements.track
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

Si el evento de espera de LWLock:pg\$1stat\$1statements está afectando negativamente al rendimiento de la base de datos y se requiere una solución rápida antes de continuar con el análisis de la vista de `pg_stat_statements` para identificar la causa raíz, el parámetro `pg_stat_statements.track` se puede desactivar configurándolo en `none`. Esto desactivará la recopilación de estadísticas de instrucciones.

### Aumento del parámetro pg\$1stat\$1statements.max
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

Para reducir la desasignación y minimizar la recopilación de elementos no utilizados del archivo `pgss_query_texts.stat` en el disco, aumente el valor del parámetro `pg_stat_statements.max`. El valor predeterminado es `5,000`.

**nota**  
El parámetro `pg_stat_statements.max` está estático. Debe reiniciar la instancia de base de datos para aplicar los cambios a este parámetro. 

### Desactivación del parámetro pg\$1stat\$1statements.track\$1utility
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

Puede analizar la vista de pg\$1stat\$1statements para determinar qué comandos de utilidad consumen la mayor cantidad de recursos rastreados por `pg_stat_statements`.

El parámetro `pg_stat_statements.track_utility` controla si el módulo realiza un seguimiento de los comandos de utilidad, que incluyen todos los comandos excepto SELECT, INSERT, UPDATE, DELETE y MERGE. Este parámetro está establecido en de forma predeterminada `on`.

Por ejemplo, cuando la aplicación utiliza muchas consultas de puntos de guardado, que son intrínsecamente únicas, puede aumentar la desasignación de instrucciones. Para abordar este problema, puede desactivar el parámetro `pg_stat_statements.track_utility` para impedir que `pg_stat_statements` realice un seguimiento de las consultas de puntos de guardado.

**nota**  
El parámetro `pg_stat_statements.track_utility` es un parámetro dinámico. Puede cambiar su valor sin necesidad de reiniciar la instancia de la base de datos.

**Example Ejemplo de consultas de punto de guardado únicas en pg\$1stat\$1statements**  <a name="savepoint-queries"></a>

```
                     query                       |       queryid       
-------------------------------------------------+---------------------
 SAVEPOINT JDBC_SAVEPOINT_495701                 | -7249565344517699703
 SAVEPOINT JDBC_SAVEPOINT_1320                   | -1572997038849006629
 SAVEPOINT JDBC_SAVEPOINT_26739                  |  54791337410474486
 SAVEPOINT JDBC_SAVEPOINT_1294466                |  8170064357463507593
 ROLLBACK TO SAVEPOINT JDBC_SAVEPOINT_65016      | -33608214779996400
 SAVEPOINT JDBC_SAVEPOINT_14185                  | -2175035613806809562
 SAVEPOINT JDBC_SAVEPOINT_45837                  | -6201592986750645383
 SAVEPOINT JDBC_SAVEPOINT_1324                   |  6388797791882029332
```

PostgreSQL 17 presenta varias mejoras para el seguimiento de comandos de utilidades:
+ Los nombres de los puntos de guardado ahora se muestran como constantes.
+ Los ID de transacción globales (GID) de los comandos de confirmación de dos fases ahora se muestran como constantes.
+ Los nombres de las instrucciones DEALLOCATE se muestran como constantes.
+ Los parámetros CALL ahora se muestran como constantes.

# LWLock:SubtransSLRU (LWLock:SubtransControlLock)
<a name="wait-event.lwlocksubtransslru"></a>

Los eventos de espera `LWLock:SubtransSLRU` y `LWLock:SubtransBuffer` indican que una sesión está esperando para acceder a la caché simple de uso menos reciente (SLRU) para la información de subtransacciones. Esto ocurre al determinar la visibilidad de las transacciones y las relaciones entre principales y secundarios.
+ `LWLock:SubtransSLRU`: un proceso está esperando para acceder a la caché simple de uso menos reciente (SLRU) para una subtransacción. En RDS para PostgreSQL anterior a la versión 13, este evento de espera se llama `SubtransControlLock`.
+ `LWLock:SubtransBuffer`: un proceso está esperando la E/S en un búfer simple de uso menos reciente (SLRU) para una subtransacción. En RDS para PostgreSQL anterior a la versión 13, este evento de espera se llama `subtrans`.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.lwlocksubtransslru.supported)
+ [

## Contexto
](#wait-event.lwlocksubtransslru.context)
+ [

## Causas probables del aumento de las esperas
](#wait-event.lwlocksubtransslru.causes)
+ [

## Acciones
](#wait-event.lwlocksubtransslru.actions)

## Versiones del motor admitidas
<a name="wait-event.lwlocksubtransslru.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Contexto
<a name="wait-event.lwlocksubtransslru.context"></a>

**Descripción de las subtransacciones**: una subtransacción es una transacción dentro de una transacción en PostgreSQL. También se conoce como transacción anidada.

Por lo general, las subtransacciones se crean cuando se utiliza:
+ `SAVEPOINT`Comandos de 
+ Bloques de excepciones (`BEGIN/EXCEPTION/END`)

Las subtransacciones le permiten revertir partes de una transacción sin que ello afecte a toda la transacción. Esto le brinda un control minucioso sobre la administración de transacciones.

**Detalles de implementación**: PostgreSQL implementa subtransacciones como estructuras anidadas dentro de las transacciones principales. Cada subtransacción recibe su propio ID de transacción.

Aspectos de implementación claves:
+ Los ID de las transacciones se rastrean en `pg_xact`
+ Las relaciones principal-secundario se almacenan en el subdirectorio `pg_subtrans` en `PGDATA`
+ Cada sesión de base de datos puede mantener hasta `64` subtransacciones activas
+ Si se supera este límite se produce un desbordamiento de subtransacciones, lo que requiere acceder a la caché simple de uso menos reciente (SLRU) para la información de subtransacciones

## Causas probables del aumento de las esperas
<a name="wait-event.lwlocksubtransslru.causes"></a>

Entre las causas más comunes de la contención de SLRU en las subtransacciones se incluyen:
+ **Uso excesivo del manejo de SAVEPOINT y EXCEPTION**: los procedimientos PL/pgSQL con controladores `EXCEPTION` crean automáticamente puntos de almacenamiento implícitos, independientemente de si se producen o no excepciones. Cada `SAVEPOINT` inicia una nueva subtransacción. Cuando una sola transacción acumula más de 64 subtransacciones, desencadena un desbordamiento de SLRU de subtransacciones.
+ **Configuraciones de controladores y ORM**: el uso de `SAVEPOINT` puede ser explícito en el código de la aplicación o implícito en las configuraciones de los controladores. Muchas de las herramientas ORM y los marcos de aplicaciones más utilizados admiten transacciones anidadas de forma nativa. Estos son algunos ejemplos comunes:
  + El parámetro del controlador JDBC `autosave`, si está establecido en `always` o `conservative`, genera puntos de almacenamiento antes de cada consulta.
  + Definiciones de transacciones de Spring Framework cuando se establece en `propagation_nested`.
  + Registros de seguimiento cuando `requires_new: true` está configurado.
  + SQLAlchemy cuando `session.begin_nested` se usa.
  + Django cuando se usan bloques de `atomic()` anidados.
  + GORM cuando se usa `Savepoint`.
  + psqlODBC cuando la configuración por reversión se establece en la reversión por instrucción (por ejemplo, `PROTOCOL=7.4-2`).
+ **Cargas de trabajo simultáneas altas con transacciones y subtransacciones de larga duración**: cuando se produce un desbordamiento de la SLRU de subtransacciones durante cargas de trabajo simultáneas altas y transacciones y subtransacciones de larga duración, PostgreSQL experimenta una mayor contención. Esto se manifiesta como eventos de espera elevados para bloqueos `LWLock:SubtransBuffer` y `LWLock:SubtransSLRU`.

## Acciones
<a name="wait-event.lwlocksubtransslru.actions"></a>

Recomendamos diferentes acciones en función de las causas del evento de espera. Algunas acciones proporcionan un alivio inmediato, mientras que otras requieren una investigación y una corrección a largo plazo.

**Topics**
+ [

### Supervisión del uso de subtransacciones
](#wait-event.lwlocksubtransslru.actions.monitor)
+ [

### Configuración de los parámetros de memoria
](#wait-event.lwlocksubtransslru.actions.memory)
+ [

### Acciones a largo plazo
](#wait-event.lwlocksubtransslru.actions.longterm)

### Supervisión del uso de subtransacciones
<a name="wait-event.lwlocksubtransslru.actions.monitor"></a>

Para las versiones 16.1 y posteriores de PostgreSQL, utilice la siguiente consulta para supervisar los recuentos de subtransacciones y el estado de desbordamiento por backend. Esta consulta combina las estadísticas del backend con la información de la actividad para mostrar qué procesos utilizan subtransacciones:

```
SELECT a.pid, usename, query, state, wait_event_type,
       wait_event, subxact_count, subxact_overflowed
FROM (SELECT id, pg_stat_get_backend_pid(id) pid, subxact_count, subxact_overflowed
      FROM pg_stat_get_backend_idset() id
           JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON true
     ) a
JOIN pg_stat_activity b ON a.pid = b.pid;
```

Para las versiones 13.3 y posteriores de PostgreSQL, supervise la vista `pg_stat_slru` para comprobar la presión de la caché de las subtransacciones. La siguiente consulta SQL recupera las estadísticas de la caché de la SLRU para el componente Subtrans:

```
SELECT * FROM pg_stat_slru WHERE name = 'Subtrans';
```

Un valor `blks_read` que aumenta de forma coherente indica el acceso frecuente al disco para las subtransacciones no almacenadas en caché, lo que indica una posible presión en la memoria caché de la SLRU.

### Configuración de los parámetros de memoria
<a name="wait-event.lwlocksubtransslru.actions.memory"></a>

Para PostgreSQL 17.1 y versiones posteriores, puede configurar el tamaño de la caché de SLRU de la subtransacción mediante el parámetro `subtransaction_buffers`. En el siguiente ejemplo de configuración, se muestra cómo establecer el parámetro de búfer de subtransacciones:

```
subtransaction_buffers = 128
```

Este parámetro especifica la cantidad de memoria compartida que se utiliza para almacenar en caché el contenido de las subtransacciones (`pg_subtrans`). Si se especifica sin unidades, el valor representa bloques de `BLCKSZ` bytes, normalmente de 8 KB cada uno. Por ejemplo, si se establece el valor en 128, se asigna 1 MB (128 \$1 8 KB) de memoria para la caché de subtransacciones.

**nota**  
Puede establecer este parámetro por clúster para que todas las instancias se mantengan coherentes. Pruebe y ajuste el valor para que se adapte a los requisitos de carga de trabajo específicos y a la clase de instancia. Debe reiniciar la instancia de escritor para que los cambios de parámetro tengan efecto.

### Acciones a largo plazo
<a name="wait-event.lwlocksubtransslru.actions.longterm"></a>
+ **Examine el código y las configuraciones de la aplicación**: revise las configuraciones del código de la aplicación y del controlador de la base de datos para ver el uso explícito e implícito de `SAVEPOINT` y el uso de subtransacciones en general. Identifique las transacciones que podrían generar más de 64 subtransacciones.
+ **Reduzca el uso de puntos de almacenamiento**: minimice el uso de puntos de almacenamiento en las transacciones:
  + Revise los procedimientos y las funciones de PL/pgSQL con bloques EXCEPTION. Los bloques EXCEPTION crean automáticamente puntos de almacenamiento implícitos, que pueden contribuir al desbordamiento de las subtransacciones. Cada cláusula EXCEPTION crea una subtransacción, independientemente de si realmente se produce una excepción durante la ejecución.  
**Example**  

    Ejemplo 1: Uso problemático del bloque EXCEPTION

    En el siguiente ejemplo de código, se muestra el uso problemático del bloque EXCEPTION que crea varias subtransacciones:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            BEGIN
                -- This creates a subtransaction for each iteration
                INSERT INTO user_audit (user_id, action, timestamp)
                VALUES (user_record.id, 'processed', NOW());
                
                UPDATE users 
                SET last_processed = NOW() 
                WHERE id = user_record.id;
                
            EXCEPTION
                WHEN unique_violation THEN
                    -- Handle duplicate audit entries
                    UPDATE user_audit 
                    SET timestamp = NOW() 
                    WHERE user_id = user_record.id AND action = 'processed';
            END;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```

    El ejemplo de código mejorado siguiente reduce el uso de subtransacciones mediante el uso de UPSERT en lugar del manejo de excepciones:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            -- Use UPSERT to avoid exception handling
            INSERT INTO user_audit (user_id, action, timestamp)
            VALUES (user_record.id, 'processed', NOW())
            ON CONFLICT (user_id, action) 
            DO UPDATE SET timestamp = NOW();
            
            UPDATE users 
            SET last_processed = NOW() 
            WHERE id = user_record.id;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```  
**Example**  

    Ejemplo 2: Controlador de excepciones STRICT

    En el ejemplo de código siguiente, se muestra un manejo problemático de EXCEPTION con NO\$1DATA\$1FOUND:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
        BEGIN
            -- STRICT causes an exception if no rows or multiple rows found
            SELECT email INTO STRICT user_email 
            FROM users 
            WHERE id = p_user_id;
            
            RETURN user_email;
            
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RETURN 'Email not found';
        END;
    END;
    $$ LANGUAGE plpgsql;
    ```

    El ejemplo de código mejorado siguiente evita subtransacciones mediante el uso de IF NOT FOUND en lugar del manejo de excepciones:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
         SELECT email INTO user_email 
         FROM users 
         WHERE id = p_user_id;
            
         IF NOT FOUND THEN
             RETURN 'Email not found';
         ELSE
             RETURN user_email;
         END IF;
    END;
    $$ LANGUAGE plpgsql;
    ```
  + Controlador JDBC: el parámetro `autosave`, si está establecido en `always` o `conservative`, genera puntos de almacenamiento antes de cada consulta. Evalúe si la configuración de `never` sería aceptable para la aplicación.
  + Controlador ODBC de PostgreSQL (psqlODBC): la configuración del nivel de reversión (para la reversión por instrucción) crea puntos de almacenamiento implícitos para habilitar la funcionalidad de reversión de instrucciones. Evalúe si el nivel de la transacción o sin reversión sería aceptable para la aplicación. 
  + Examen de las configuraciones de transacciones de ORM
  + Consideración de estrategias alternativas de manejo de errores que no requieran puntos de almacenamiento
+ **Optimización del diseño de las transacciones**: reestructure las transacciones para evitar el anidamiento excesivo y reducir la probabilidad de que se produzcan desbordamientos de las subtransacciones.
+ **Reduzca las transacciones de larga duración**: las transacciones de larga duración pueden agravar los problemas relacionados con las subtransacciones al conservar la información de las subtransacciones durante más tiempo. Supervise las métricas de información de rendimiento y configure el parámetro `idle_in_transaction_session_timeout` para terminar automáticamente las transacciones inactivas.
+ Supervise las métricas de información de rendimiento: realice un seguimiento de las métricas, incluido `idle_in_transaction_count` (número de sesiones inactivas en estado de transacción) y `idle_in_transaction_max_time` (duración de la transacción inactiva más prolongada) para detectar transacciones de larga duración.
+ Configure `idle_in_transaction_session_timeout`: defina este parámetro en el grupo de parámetros para terminar automáticamente las transacciones inactivas después de un periodo especificado.
+ Supervisión proactiva: supervise los eventos de espera de alta frecuencia `LWLock:SubtransBuffer` y `LWLock:SubtransSLRU` para detectar conflictos relacionados con las subtransacciones antes de que se conviertan en críticos.

# Timeout:PgSleep
<a name="wait-event.timeoutpgsleep"></a>

El evento `Timeout:PgSleep` ocurre cuando un proceso del servidor llama a la función `pg_sleep` y espera a que el tiempo de espera expire.

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.timeoutpgsleep.context.supported)
+ [

## Causas probables del aumento del tiempo de espera
](#wait-event.timeoutpgsleep.causes)
+ [

## Acciones
](#wait-event.timeoutpgsleep.actions)

## Versiones del motor admitidas
<a name="wait-event.timeoutpgsleep.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Causas probables del aumento del tiempo de espera
<a name="wait-event.timeoutpgsleep.causes"></a>

Este evento de espera ocurre cuando una aplicación, función almacenada o usuario emite una sentencia SQL que llama a una de las siguientes funciones:
+ `pg_sleep`
+ `pg_sleep_for`
+ `pg_sleep_until`

Las funciones anteriores retrasan la ejecución hasta que transcurra el número de segundos especificado. Por ejemplo, `SELECT pg_sleep(1)` hace una pausa de 1 segundo. Para más información, consulte [Delaying Execution](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-DELAY) en la documentación de PostgreSQL.

## Acciones
<a name="wait-event.timeoutpgsleep.actions"></a>

Identifique la sentencia que estaba ejecutando la función `pg_sleep`. Determine si el uso de la función es adecuado.

# Timeout:VacuumDelay
<a name="wait-event.timeoutvacuumdelay"></a>

El evento `Timeout:VacuumDelay` indica que se ha superado el límite de costo de las E/S de vacío y que el proceso de vacío está en reposo. Las operaciones de aspiración se detienen durante el tiempo especificado en el parámetro de retraso de coste correspondiente y, a continuación, reanudan su trabajo. Para el comando de limpieza manual, el retraso se especifica en el parámetro `vacuum_cost_delay`. Para el deamon autovacuum, el retraso se especifica en `autovacuum_vacuum_cost_delay parameter.`. 

**Topics**
+ [

## Versiones del motor admitidas
](#wait-event.timeoutvacuumdelay.context.supported)
+ [

## Context
](#wait-event.timeoutvacuumdelay.context)
+ [

## Causas probables del aumento del tiempo de espera
](#wait-event.timeoutvacuumdelay.causes)
+ [

## Acciones
](#wait-event.timeoutvacuumdelay.actions)

## Versiones del motor admitidas
<a name="wait-event.timeoutvacuumdelay.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

## Context
<a name="wait-event.timeoutvacuumdelay.context"></a>

PostgreSQL tiene un daemon autovaccum y un comando de limpieza manual. El proceso de autovacuum está “activado” de forma predeterminada para las instancias de base de datos de RDS para PostgreSQL. El comando de limpieza manual se usa según sea necesario, por ejemplo, para purgar tablas de tuplas muertas o para generar nuevas estadísticas.

Cuando se realiza la limpieza, PostgreSQL utiliza un contador interno para realizar un seguimiento de los costos estimados a medida que el sistema realiza diversas operaciones de E/S. Cuando el contador alcanza el valor especificado en el parámetro de límite de costo, el proceso que realiza la operación permanece en reposo durante el breve período especificado en el parámetro de retraso de costo. A continuación, reinicia el contador y continúa con las operaciones. 

El proceso de vacío tiene parámetros que se pueden utilizar para regular el consumo de recursos. El vacío automático y el comando de vacío manual tienen sus propios parámetros para establecer el valor de límite de costo. También tienen sus propios parámetros para especificar un retraso en el costo, una cantidad de tiempo para poner la limpieza en reposo cuando se alcanza el límite. De esta manera, el parámetro de retraso de costos funciona como un mecanismo de limitación del consumo de recursos. En las siguientes listas encontrará las descripciones de estos parámetros. 

**Parámetros que afectan a la limitación del daemon autovacuum**
+ `[autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)`: especifica el valor límite de costo que se utilizará en las operaciones de vacío automático. El aumento de la configuración de este parámetro permite que el proceso de vacío utilice más recursos y reduce el evento de espera `Timeout:VacuumDelay`. 
+ `[autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)`: especifica el valor retardo de costo que se utilizará en las operaciones de vacío automático. El valor predeterminado es de 2 milisegundos. Al establecer el parámetro de retardo en 0, se desactiva el mecanismo de limitación y, por lo tanto, el evento de espera `Timeout:VacuumDelay` no aparecerá. 

Para más información, visite [Automatic Vacuuming](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY) (Vacío automático) en la documentación de PostgreSQL.

**Parámetros que afectan a la limitación del proceso de vacío manual**
+ `vacuum_cost_limit`: umbral en el que el proceso de limitación está en reposo. El límite predeterminado de es de 200. Este número representa las estimaciones de costos acumulados para las E/S adicionales que necesitan varios recursos. Al aumentar este valor, se reduce el número del evento de espera `Timeout:VacuumDelay`. 
+ `vacuum_cost_delay`: cantidad de tiempo que el proceso de vacío está en reposo cuando se ha alcanzado el límite de costo de vacío. La configuración predeterminada es 0, lo que significa que esta función está desactivada. Puede configurarla con un valor entero para especificar el número de milisegundos necesarios para activar esta función, pero le recomendamos que la deje como configuración predeterminada.

Para obtener más información acerca del parámetro `vacuum_cost_delay`, consulte el punto [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST) (Consumo de recursos) en la documentación de PostgreSQL. 

Para obtener más información acerca del uso del vacío automático con RDS para PostgreSQL, consulte [Uso de autovacuum de PostgreSQL en Amazon RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

## Causas probables del aumento del tiempo de espera
<a name="wait-event.timeoutvacuumdelay.causes"></a>

`Timeout:VacuumDelay` se ve afectado por el equilibrio entre la configuración de los parámetros del límite de costo (`vacuum_cost_limit`, `autovacuum_vacuum_cost_limit`) y los parámetros de retraso de costo (`vacuum_cost_delay`, `autovacuum_vacuum_cost_delay`) que controlan la duración del reposo del vacío. Al aumentar el valor de un parámetro de límite de costo, el vacío puede utilizar más recursos antes de que entre en reposo. Esto se traduce en menos eventos de espera `Timeout:VacuumDelay`. El aumento de cualquiera de los parámetros de retraso hace que el evento de espera `Timeout:VacuumDelay` se produzca con más frecuencia y durante períodos de tiempo más prolongados. 

La configuración del parámetro `autovacuum_max_workers` también puede aumentar el número de `Timeout:VacuumDelay`. Cada proceso adicional de trabajo de autovacuum contribuye al mecanismo de contador interno y, por lo tanto, se puede alcanzar el límite más rápidamente que con un solo proceso de trabajo de autovacuum. A medida que se alcanza el límite de costo más rápidamente, el retraso en el costo se hace efectivo con más frecuencia, lo que resulta en más eventos de espera `Timeout:VacuumDelay`. Para más información, consulte [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS) en la documentación de PostgreSQL.

Los objetos grandes, como de 500 GB o más, también aumentan este evento de espera, ya que el vacío puede tardar algún tiempo en completar el procesamiento de objetos grandes.

## Acciones
<a name="wait-event.timeoutvacuumdelay.actions"></a>

Si las operaciones de vacío se completan según lo previsto, no es necesario realizar ninguna corrección. En otras palabras, este evento de espera no significa necesariamente que se trate de un problema. Indica que el vacío está en reposo durante el período de tiempo especificado en el parámetro de retraso, de modo que los recursos se puedan aplicar a otros procesos que deben completarse. 

Si desea que las operaciones de vacío se completen más rápido, puede reducir los parámetros de retardo. Esto acorta el tiempo que el vacío permanece inactivo. 