Otimize o alto uso da CPU em instâncias

A alta utilização da CPU afeta negativamente o desempenho da sua instância. Qualquer atividade realizada na instância consome CPU. Portanto, se houver um aviso de alta utilização da CPU, você deve primeiro identificar a causa raiz do problema, sejam consultas mal escritas, transações demoradas ou qualquer outra atividade do banco de dados.

Este documento descreve as maneiras de identificar gargalos de CPU em uma instância e mitigar os problemas de utilização de CPU na instância.

Identificar os gargalos da CPU

As seções a seguir discutem diferentes cenários de CPU.

Use insights de consulta para identificar consultas com alto consumo de CPU

O Query Insights ajuda você a detectar, diagnosticar e prevenir problemas de desempenho de consultas em bancos de dados do Cloud SQL.

Use a extensão pg_proctab

Use a extensão pg_proctab com a combinação do utilitário pg_top para obter saídas do sistema operacional que fornecem informações de utilização da CPU por processo.

Usar consultas

As seções a seguir discutem diferentes consultas que você pode usar.

Identifique as conexões ativas por estado

Cada conexão ativa com o banco de dados consome uma certa quantidade de CPU; portanto, se a instância tiver um número alto de conexões, a utilização cumulativa poderá ser alta. Use a consulta a seguir para obter informações sobre o número de conexões por estado.

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

A saída é semelhante à seguinte:


        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)

Se a contagem de conexões ativas for alta, verifique se há consultas de longa execução ou eventos de espera que estejam bloqueando a execução das consultas.

Se a contagem de conexões ociosas for alta, execute a seguinte consulta para encerrar as conexões, após obter as aprovações necessárias.

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

Você também pode encerrar as conexões individualmente com pg_terminate_backend usando a seguinte consulta:

SELECT pg_terminate_backend (<pid>);

Aqui, você pode obter o PID de pg_stat_activity .

Identifique as conexões de longa duração

Aqui está um exemplo de uma consulta que retorna consultas de longa duração. Nesse caso, você pode identificar as consultas que estão ativas há mais 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;

Revise o plano explicativo para identificar consultas mal escritas

Use o EXPLAIN PLAN para investigar uma consulta mal escrita e reescrevê-la, se necessário. Opcionalmente, considere cancelar a consulta de longa duração com o seguinte comando, com as aprovações necessárias.

SELECT pg_cancel_backend(<pid>);

Monitorar a atividade do VACUUM

A atividade AUTOVACUUM que limpa as tuplas inativas é uma operação que exige muita CPU. Se sua instância usa o PostgreSQL versão 11 ou posterior, use a consulta a seguir para verificar se há alguma atividade AUTOVACUUM ou VACUUM em andamento.

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;

Verifique se há uma atividade VACUUM em andamento em uma instância usando a seguinte consulta:

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

Além disso, você pode otimizar e solucionar problemas de operações VACUUM no PostgreSQL .

Adicionar extensão pg_stat_statements

Configure a extensão pg_stat_statements para obter informações de dicionário aprimoradas sobre a atividade da instância.

Pontos de verificação frequentes

Pontos de verificação frequentes prejudicam o desempenho. Considere ajustar o sinalizador checkpoint_timeout se o log de alerta do PostgreSQL relatar o aviso de que o checkpoint occurring too frequently .

Reúna estatísticas

Certifique-se de que o planejador de consultas tenha as estatísticas mais recentes sobre as tabelas para escolher o melhor plano de consultas. A operação ANALYZE coleta estatísticas sobre o conteúdo das tabelas no banco de dados e armazena os resultados no catálogo do sistema pg_statistic. Posteriormente, o planejador de consultas usa essas estatísticas para ajudar a determinar os planos de execução mais eficientes para as consultas. O processo AUTOVACUUM analisa as tabelas automaticamente e periodicamente. Portanto, execute o seguinte comando para verificar se todas as tabelas foram analisadas e se os metadados mais recentes estão disponíveis para o planejador.

SELECT 
  relname, 
  last_autovacuum, 
  last_autoanalyze 
FROM 
  pg_stat_user_tables;

Configurações inadequadas do sistema

Existem outros fatores e configurações de sinalizadores ou fatores do sistema que influenciam o desempenho da sua consulta. Execute a consulta a seguir para verificar os eventos de espera e o tipo de evento de espera para obter insights sobre o desempenho de outras configurações do 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;

A saída é semelhante a esta:

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

Monitorar varreduras sequenciais

Varreduras sequenciais frequentes em tabelas com mais de algumas dezenas de linhas geralmente indicam um índice ausente. Quando as varreduras atingem milhares ou até centenas de milhares de linhas, podem causar uso excessivo da CPU.

Varreduras sequenciais frequentes em tabelas com centenas de milhares de linhas podem causar uso excessivo da CPU. Evite varreduras sequenciais nessas tabelas criando índices necessários.

Execute a seguinte consulta para verificar o número de vezes que as varreduras sequenciais são iniciadas em qualquer tabela.

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 fim, se a CPU ainda estiver alta e você achar que essas consultas são tráfego legítimo, considere aumentar os recursos da CPU na sua instância para evitar falhas ou tempo de inatividade do banco de dados.

O que vem a seguir