Melhores práticas para gerenciar o uso de memória

Esta página descreve como configurar o uso de memória para uma instância do Cloud SQL.

Introdução

Ao criar uma instância do Cloud SQL, você seleciona uma quantidade de memória para ela. À medida que a carga de trabalho de um banco de dados PostgreSQL aumenta, o uso de memória da instância aumenta. Instâncias que consomem muita memória podem criar um gargalo de desempenho que, às vezes, pode levar a problemas de falta de memória.

Quando uma instância do Cloud SQL fica sem memória devido ao aumento da demanda, isso pode causar tempo de inatividade do banco de dados. Portanto, é importante configurar a memória da instância e os sinalizadores do banco de dados relacionados à memória corretamente, além de monitorar o uso da memória para que a instância opere em um estado saudável.

Os componentes de memória do PostgreSQL são amplamente divididos em duas seções:

  • Memória global: é compartilhada entre todos os processos para executar consultas; por exemplo, shared_buffers e max_connections .
  • Memória local: é memória dedicada atribuída a cada conexão; por exemplo, work_mem , maintenance_work_mem e temp_buffers .

Para outras considerações de configuração, consulte Práticas recomendadas gerais e Diretrizes operacionais .

Uso de memória e sinalizadores

Sempre que houver alto uso de memória por instâncias do Cloud SQL, as seguintes perguntas podem surgir:

  • Qual consulta ou processo está usando muita memória?
  • As configurações de memória são adequadas para a atividade do banco de dados?
  • Como você altera as configurações de memória?

Quando um banco de dados PostgreSQL opera, a maior parte do uso de memória ocorre em algumas áreas:

  • Buffer compartilhado: esta é a memória compartilhada que o PostgreSQL aloca para armazenar os dados da tabela para operações read e write . Para a operação read , quaisquer dados solicitados do disco são primeiro buscados na RAM e, em seguida, fornecidos ao cliente. Da mesma forma, no PostgreSQL, quando os dados são solicitados (por exemplo, SELECT * from emp ), eles são primeiro buscados do disco para shared_buffers para armazenamento em cache e, em seguida, fornecidos ao cliente. O mesmo acontece com a operação write .

    O buffer compartilhado também é a área de memória compartilhada para todos os processos e conexões para atividades de banco de dados, como cache de dados, cache de conexões e operações de Linguagem de Manipulação de Dados (DML). O máximo que essa área pode alocar é especificado pelo sinalizador shared_buffers e o padrão é 33% da memória da instância. Se o valor de shared_buffers for alto, o tamanho dos dados armazenados em cache na memória também será alto.

  • Memória de trabalho da consulta: conforme uma consulta é executada, o PostgreSQL aloca memória local para cada operação, como ordenação e hashing. O máximo que ele pode alocar para cada operação de uma consulta antes de gravar em arquivos temporários do disco é configurado pelo sinalizador work_mem , e o valor padrão é 4 MB. Se o valor de work_mem for alto, a quantidade de dados que podem ser ordenados na memória também será alta.
  • Memória de trabalho de manutenção: algumas operações de manutenção, como VACUUM , CREATE INDEX , ALTER TABLE e ADD FOREIGN KEY exigem memória local separada alocada pelo PostgreSQL. A quantidade máxima de memória utilizada por essas operações para o processo de back-end pode ser configurada pelo sinalizador maintenance_work_mem , e o valor padrão é 64 MB. Observe que os workers de autovacuum também utilizam memória de trabalho de manutenção, e o máximo pode ser substituído pelo sinalizador autovacuum_work_mem . Se o valor de maintenance_work_mem for alto, a velocidade de desempenho da operação VACUUM será alta.
  • Buffers temporários: quando uma tabela temporária é usada em uma sessão de banco de dados, o PostgreSQL aloca buffers temporários para armazenar a tabela temporária local da sessão. A quantidade máxima pode ser especificada pelo sinalizador temp_buffers e o valor padrão é 8 MB.
  • Conexão com o banco de dados: quando um cliente se conecta ao banco de dados, o PostgreSQL cria um processo de back-end para atender à sessão do cliente. Além da memória para executar a consulta, o PostgreSQL aloca memória adicional para manter informações como o cache do catálogo do sistema e os planos de consulta preparados. O número máximo de conexões simultâneas permitidas ao servidor de banco de dados pode ser configurado pelo sinalizador max_connections . Cada conexão ociosa usa aproximadamente 2 MB a 3 MB de memória compartilhada. Se o valor de max_connections for alto, a instância poderá fazer mais conexões, mas ao custo da memória.

Para obter a lista completa de componentes de memória no PostgreSQL, consulte a documentação do PostgreSQL . Para alterar ou modificar os sinalizadores listados nesta seção, consulte Configurar sinalizadores do banco de dados .

Monitorar o uso da memória

Monitore a memória da sua instância no Cloud Monitoring regularmente e mantenha-a abaixo do limite de memória. Uma boa prática é definir um alerta no Cloud Monitoring para avisar quando o uso exceder 90% do limite por 6 horas. Este alerta pode alertá-lo quando o uso da memória estiver constantemente próximo do limite.

Além disso, monitore incidentes de falta de memória. Para isso, configure uma métrica baseada em log para a server process .* was terminated by signal 9: Killed " no Cloud Monitoring para contabilizar os eventos de falta de memória e, em seguida, emitir um alerta sempre que tal evento ocorrer.

Se a sua instância operar constantemente acima de 90% do limite de memória ou ocorrer um evento de falta de memória, você poderá aumentar a memória da instância. Como alternativa, você pode reduzir o uso de memória limitando o número de conexões com o banco de dados ou diminuindo os sinalizadores de banco de dados, como shared_buffers , work_mem ou max_connections . Reduzir esses sinalizadores pode limitar o desempenho da sua instância.

Sem memória

Quando não há memória suficiente para lidar com a carga de trabalho do banco de dados, como último recurso, o sistema operacional Linux subjacente usa o out-of-memory (OOM) killer para encerrar um processo e liberar memória. O Cloud SQL é configurado para que o OOM killer tenha como alvo apenas os processos de trabalho do PostgreSQL. O processo postmaster é preservado nessa situação, de modo que ele só precisa encerrar todas as conexões existentes com o banco de dados e executar uma recuperação para proteger a integridade do banco de dados. Se isso acontecer, haverá momentos de interrupção do serviço e tempo de inatividade do banco de dados. No log do banco de dados PostgreSQL, mensagens como as seguintes são exibidas:

2021-10-24 23:34:22.265 UTC [7]: [663-1] db=,user= LOG: server process (PID 1255039) was terminated by signal 9: Killed
2021-10-24 23:34:22.265 UTC [7]: [664-1] db=,user= DETAIL: Failed process was running: SELECT * FROM tab ORDER BY col
2021-10-24 23:34:22.277 UTC [7]: [665-1] db=,user= LOG: terminating any other active server processes
2021-10-24 23:34:22.278 UTC [1255458]: [1-1] db=postgres,user=postgres WARNING: terminating connection because of crash of another server process
2021-10-24 23:34:22.278 UTC [1255458]: [2-1] db=postgres,user=postgres DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
2021-10-24 23:34:22.278 UTC [1255458]: [3-1] db=postgres,user=postgres HINT: In a moment you should be able to reconnect to the database and repeat your command.
2021-10-24 23:34:22.278 UTC [1255458]: [4-1] db=postgres,user=postgres CONTEXT: while updating tuple (27,18) in relation "tab"
...
2021-10-24 23:34:22.558 UTC [1255477]: [1-1] db=postgres,user=postgres FATAL: the database system is in recovery mode
...
2021-10-24 23:34:25.579 UTC [7]: [666-1] db=,user= LOG: all server processes terminated; reinitializing
...
2021-10-24 23:34:25.691 UTC [1255482]: [1-1] db=,user= LOG: database system was interrupted; last known up at 2021-10-24 23:31:53 UTC
2021-10-24 23:34:25.776 UTC [1255482]: [2-1] db=,user= LOG: database system was not properly shut down; automatic recovery in progress
2021-10-24 23:34:25.789 UTC [1255482]: [3-1] db=,user= LOG: redo starts at 227/AB359400
2021-10-24 23:34:38.957 UTC [1255482]: [4-1] db=,user= LOG: redo done at 229/4621F508
2021-10-24 23:34:38.959 UTC [1255482]: [5-1] db=,user= LOG: last completed transaction was at log time 2021-10-24 23:34:18.5535+00
2021-10-24 23:34:39.290 UTC [7]: [667-1] db=,user= LOG: database system is ready to accept connections

O que vem a seguir