Optimizar el uso elevado de CPU en las instancias

Un uso elevado de la CPU afecta negativamente el rendimiento de la instancia. Cualquier actividad realizada en la instancia consume CPU. Por lo tanto, si aparece un aviso de uso elevado de la CPU, primero debe identificar la causa raíz del problema, ya sean consultas mal escritas, transacciones de larga duración o cualquier otra actividad de la base de datos.

Este documento describe las formas de identificar cuellos de botella de CPU en una instancia y mitigar los problemas de utilización de CPU en la instancia.

Identificar los cuellos de botella de la CPU

Las siguientes secciones analizan diferentes escenarios de CPU.

Utilice información de consultas para identificar consultas que tienen un alto consumo de CPU

Query Insights le ayuda a detectar, diagnosticar y prevenir problemas de rendimiento de consultas para bases de datos de Cloud SQL.

Utilice la extensión pg_proctab

Utilice la extensión pg_proctab con la combinación de la utilidad pg_top para obtener salidas del sistema operativo que brindan información de utilización de CPU por proceso.

Utilizar consultas

Las siguientes secciones analizan diferentes consultas que puedes utilizar.

Identificar las conexiones activas por estado

Cada conexión activa a la base de datos consume cierta cantidad de CPU, por lo que si la instancia tiene un gran número de conexiones, la utilización acumulada podría ser alta. Utilice la siguiente consulta para obtener información sobre el número de conexiones por estado.

SELECT 
  state, 
  usename, 
  count(1) 
FROM 
  pg_stat_activity 
WHERE 
  pid <> pg_backend_pid() 
group by 
  state, 
  usename 
order by 
  1;

El resultado será similar al siguiente:


        state        |    usename    | count 
---------------------+---------------+-------
 active              | ltest         |   318
 active              | sbtest        |    95
 active              |               |     2
 idle                | cloudsqladmin |     2
 idle in transaction | ltest         |    32
 idle in transaction | sbtest        |     5
                     | cloudsqladmin |     3
                     |               |     4
(8 rows)

Si el número de conexiones activas es alto, verifique si hay consultas de ejecución prolongada o eventos de espera que estén bloqueando la ejecución de las consultas.

Si el número de conexiones inactivas es alto, ejecute la siguiente consulta para finalizar las conexiones, después de obtener las aprobaciones necesarias.

SELECT 
  pg_terminate_backend(pid) 
FROM 
  pg_stat_activity 
WHERE 
  usename = 'sbtest' 
  and pid <> pg_backend_pid() 
  and state in ('idle');

También puede finalizar las conexiones individualmente con pg_terminate_backend utilizando la siguiente consulta:

SELECT pg_terminate_backend (<pid>);

Aquí puedes obtener el PID de pg_stat_activity .

Identificar las conexiones de larga duración

A continuación, se muestra un ejemplo de una consulta que devuelve consultas de larga duración. En este caso, se pueden identificar las consultas que han estado activas durante más de 5 minutos.

SELECT 
  pid, 
  query_start, 
  xact_start, 
  now() - pg_stat_activity.query_start AS duration, 
  query, 
  state 
FROM 
  pg_stat_activity 
WHERE 
  (
    now() - pg_stat_activity.query_start
  ) > interval '5 minutes' order by 4 desc;

Revisar el plan de explicación para identificar consultas mal redactadas

Utilice el PLAN EXPLICAR para investigar una consulta mal escrita y reescribirla si es necesario. Opcionalmente, considere cancelar la consulta de larga duración con el siguiente comando, con las aprobaciones necesarias.

SELECT pg_cancel_backend(<pid>);

Monitorizar la actividad de VACÍO

La actividad AUTOVACUUM, que borra las tuplas inactivas, consume mucha CPU. Si su instancia usa PostgreSQL versión 11 o posterior, utilice la siguiente consulta para comprobar si hay alguna actividad AUTOVACUUM o VACUUM activa.

SELECT 
  relid :: regclass, 
  pid, 
  phase, 
  heap_blks_total, 
  heap_blks_scanned, 
  heap_blks_vacuumed, 
  index_vacuum_count, 
  max_dead_tuples, 
  num_dead_tuples 
FROM 
  pg_stat_progress_vacuum;

Compruebe si hay una actividad VACUUM en curso en una instancia utilizando la siguiente consulta:

SELECT 
  pid, 
  datname,
  usename, 
  query 
FROM 
  pg_stat_activity 
WHERE 
  query like '%vacuum%';

Además, puede optimizar y solucionar problemas de operaciones VACUUM en PostgreSQL .

Añadir la extensión pg_stat_statements

Configure la extensión pg_stat_statements para obtener información mejorada del diccionario sobre la actividad de la instancia.

Puntos de control frecuentes

Los puntos de control frecuentes reducen el rendimiento. Considere ajustar el indicador checkpoint_timeout si el registro de alertas de PostgreSQL indica que el checkpoint occurring too frequently .

Recopilar estadísticas

Asegúrese de que el planificador de consultas cuente con las estadísticas más recientes sobre las tablas para elegir el mejor plan de consulta. La operación ANALYZE recopila estadísticas sobre el contenido de las tablas en la base de datos y almacena los resultados en el catálogo del sistema pg_statistic. Posteriormente, el planificador de consultas utiliza estas estadísticas para determinar los planes de ejecución más eficientes. El proceso AUTOVACUUM analiza automáticamente las tablas periódicamente; por lo tanto, ejecute el siguiente comando para comprobar si todas las tablas se han analizado y si el planificador dispone de los metadatos más recientes.

SELECT 
  relname, 
  last_autovacuum, 
  last_autoanalyze 
FROM 
  pg_stat_user_tables;

Configuraciones del sistema inadecuadas

Existen otros factores, como la configuración de indicadores o factores del sistema, que influyen en el rendimiento de la consulta. Ejecute la siguiente consulta para comprobar los eventos de espera y su tipo y obtener información sobre el rendimiento de otras configuraciones del sistema.

SELECT 
  datname, 
  usename, 
  (
    case when usename is not null then state else query end
  ) AS what, 
  wait_event_type, 
  wait_event, 
  backend_type, 
  count(*) 
FROM 
  pg_stat_activity 
GROUP BY 
  1, 
  2, 
  3, 
  4, 
  5, 
  6 
ORDER BY 
  1, 
  2, 
  3, 
  4 nulls first, 
  5, 
  6;

El resultado se parece a esto:

  
 ..  | .. | what           | wait_event_type |      wait_event      | ..    | count
-..--+-..-+----------------+-----------------+----------------------+-..----+------
 ..
 ..  | .. | active         | IO              | CommitWaitFlush      | ..    |   750
 ..  | .. | idle           | IO              | CommitWaitFlush      | ..    |   360
 ..  | .. | active         | LWLock          | BufferMapping        | ..    |   191
  

Monitorizar escaneos secuenciales

Los escaneos secuenciales frecuentes en tablas con más de unas pocas decenas de filas suelen indicar la ausencia de un índice. Cuando los escaneos alcanzan miles o incluso cientos de miles de filas, pueden causar un uso excesivo de la CPU.

Los escaneos secuenciales frecuentes en tablas con cientos de miles de filas pueden causar un uso excesivo de la CPU. Evite los escaneos secuenciales en dichas tablas creando los índices necesarios.

Ejecute la siguiente consulta para comprobar la cantidad de veces que se inician exploraciones secuenciales en cualquier tabla.

SELECT 
  relname, 
  idx_scan,  
  seq_scan, 
  n_live_tup 
FROM 
  pg_stat_user_tables 
WHERE 
  seq_scan > 0 
ORDER BY 
  n_live_tup desc;

Por último, si el uso de la CPU aún es alto y usted considera que esas consultas son tráfico legítimo, considere aumentar los recursos de la CPU en su instancia para evitar caídas o tiempos de inactividad de la base de datos.

¿Qué sigue?