Otimize a elevada utilização de memória em instâncias

Este documento aborda a forma de identificar a utilização elevada de memória para instâncias do Cloud SQL e fornece recomendações sobre como resolver problemas relacionados com a memória.

Para saber como configurar a utilização de memória para uma instância do Cloud SQL, consulte o artigo Práticas recomendadas para gerir a utilização de memória.

Identifique a utilização elevada de memória

As secções seguintes abordam cenários de utilização elevada de memória.

Use o Explorador de métricas para identificar a utilização de memória

Pode rever a utilização de memória da instância com a métrica database/memory/components.usage no Explorador de métricas.

Use as estatísticas de consultas para analisar o plano de explicação de consultas que estão a consumir muitos recursos

As estatísticas de consultas ajudam a detetar, diagnosticar e evitar problemas de desempenho de consultas para bases de dados do Cloud SQL. As estatísticas de consultas oferecem-lhe uma lista de consultas de execução prolongada, juntamente com o respetivo plano de explicação (documentação do PostgreSQL). Reveja o plano de explicação e identifique a parte da consulta que tem um método de análise de utilização de memória elevado. Independentemente do tempo de execução da consulta, as estatísticas de consultas fornecem o plano de explicação para todas as consultas. Identifique as consultas complexas que estão a demorar mais tempo para saber que consultas estão a bloquear a memória durante mais tempo.

Os métodos de análise do PostgreSQL comuns que usam muita memória incluem o seguinte:

  • Análise de memória de mapa de bits
  • Ordenação rápida
  • Junção hash ou hash

Utilização elevada de memória e registos relevantes para instâncias com o Gemini ativado

Se tiver o Gemini ativado, em vez de uma falha de OOM que leva a um tempo de inatividade da base de dados, uma ligação que execute uma consulta com uma utilização elevada de memória é terminada, o que evita o tempo de inatividade da base de dados. Para identificar a consulta predefinida, pode verificar as seguintes entradas nos registos da base de dados:

  (...timestamp….) db=postgres, user=customer FATAL: terminating connection due to administrator command

É apresentado o seguinte registo da base de dados do Cloud SQL para PostgreSQL, que capta a consulta de utilização elevada de memória que foi terminada para evitar o erro de falta de memória. A consulta é uma versão normalizada da consulta original:

  db=postgres,user=customer LOG:  postgres process with PID 1734 for the query "SELECT COUNT(product) AS item_count FROM test_table WHERE product_type = $1 AND product LIKE $2 AND c6_2 IN ($3,$4,$5,$6,$7)" has been cancelled.

As notificações também são apresentadas na página Instâncias do Cloud SQL para os seguintes eventos:

  • Utilização da memória da instância nas últimas 24 horas.
  • Lista de consultas normalizadas que foram canceladas nas últimas 24 horas.
  • Um link para a documentação da Google sobre a otimização da utilização da memória.

Utilização elevada da memória – Recomendações

As seguintes recomendações abordam os problemas comuns relacionados com a memória. Se a instância continuar a usar uma grande quantidade de memória, é provável que acabe por ter um problema de out of memory. Se as exigências de memória do PostgreSQL ou de outro processo fizerem com que o sistema fique sem memória, é apresentada uma mensagem do kernel Out of Memory nos registos do PostgreSQL e a instância do PostgreSQL é eventualmente interrompida. Por exemplo:

Out of Memory: Killed process 12345 (postgres)

A instância mais comum em que vê um problema de OOM é com um valor mais elevado de work_mem com um número elevado de ligações ativas. Por conseguinte, se estiver a receber erros de falta de memória com frequência ou para os evitar na sua instância do Cloud SQL para PostgreSQL, deve considerar seguir estas recomendações:

  • Definir work_mem

    As consultas que usam a ordenação rápida são mais rápidas do que as que usam a ordenação por intercalação externa. No entanto, a primeira pode levar à exaustão da memória. Para resolver este problema, defina o valor work_mem como razoável o suficiente para equilibrar as operações de ordenação que ocorrem na memória e no disco. Também pode considerar definir work_mem ao nível da sessão, em vez de o definir para uma instância inteira.

  • Monitorize as sessões ativas

    Cada ligação usa uma determinada quantidade de memória. Use a seguinte consulta para verificar a quantidade de associações ativas:

      SELECT
        state,
        usename,
        count(1)
      FROM
        pg_stat_activity
      WHERE
        pid <> pg_backend_pid()
      GROUP BY
        state,
        usename
      ORDER BY
        1;
    

    Se tiver um grande número de sessões ativas, analise a causa principal de um número elevado de sessões ativas, por exemplo, bloqueios de transações.

  • Definir shared_buffers

    Se shared_buffers estiver definido com um valor mais elevado, considere diminuir o valor de shared_buffers para que a memória possa ser usada para outras operações, como work_mem, ou para estabelecer novas ligações.

    Relação de resultados da cache

    Geralmente, o PostgreSQL tenta manter na cache os dados aos quais acede com mais frequência. Quando os dados são pedidos por um cliente, se já estiverem em cache nos buffers partilhados, são fornecidos diretamente ao cliente. Isto chama-se acesso à cache. Se os dados não estiverem presentes em buffers partilhados, os dados são primeiro obtidos para buffers partilhados a partir de um disco e, em seguida, fornecidos ao cliente. Isto chama-se falha de cache. A taxa de acertos da cache mede quantos pedidos de conteúdo a cache processou em comparação com os pedidos recebidos. Execute a seguinte consulta para verificar a taxa de acertos da cache para os pedidos de tabelas na instância do PostgreSQL:

    SELECT
      sum(heap_blks_read) as heap_read,
      sum(heap_blks_hit)  as heap_hit,
      sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio
    FROM
      pg_statio_user_tables;
    

    Execute a seguinte consulta para verificar a taxa de acertos da cache para os pedidos de índice na instância do PostgreSQL:

      SELECT
        sum(idx_blks_read) as idx_read,
        sum(idx_blks_hit)  as idx_hit,
        (sum(idx_blks_hit) - sum(idx_blks_read)) / sum(idx_blks_hit) as ratio
      FROM
        pg_statio_user_indexes;
    

    Geralmente, uma taxa de acertos da cache de 95 a 99% é considerada um bom valor.

  • No Cloud SQL para PostgreSQL, a flag huge_pages está ativada por predefinição para uma melhor gestão de memória. Para saber mais sobre o huge_pages, consulte a documentação do PostgreSQL.

  • Definir max_locks_per_transaction

    O valor max_locks_per_transaction indica o número de objetos da base de dados que podem ser bloqueados em simultâneo. Na maioria dos casos, o valor predefinido de 64 é suficiente. No entanto, se estiver a trabalhar com um conjunto de dados grande, pode acabar por ter OOMs. Considere aumentar o valor de max_locks_per_transaction o suficiente para evitar erros de falta de memória.

    max_prepared_transactions

    O valor de max_locks_per_transaction deve ser max_locks_per_transaction * (max_connections + max_prepared_transactions) objetos. Isto significa que, se tiver 300 mil objetos e o valor de max_connections for 200, max_locks_per_transaction deve ser 1500.

  • Definir max_pred_locks_per_transaction

    A transação pode falhar se tiver clientes que interajam com muitas tabelas diferentes numa única transação serializável. Nesse cenário, considere aumentar max_pred_locks_per_transaction para um valor razoavelmente elevado. Tal como max_locks_per_transaction, max_pred_locks_per_transaction também usa memória partilhada, por isso, não defina um valor excessivamente elevado.

  • Se a utilização de memória continuar elevada e considerar que essas consultas são tráfego legítimo, pondere aumentar o número de recursos de memória na sua instância para evitar falhas ou tempo de inatividade da base de dados.

O que se segue?