Práticas recomendadas para gerenciar o uso de memória

Nesta página, descrevemos como configurar o uso de memória em 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. As instâncias que consomem muita memória podem criar um gargalo de desempenho que, às vezes, pode levar a problemas de memória insuficiente.

Quando uma instância do Cloud SQL fica sem memória devido ao aumento da demanda, o banco de dados pode ficar inativo. Portanto, é importante configurar a memória da instância e os sinalizadores de banco de dados relacionados à memória corretamente e monitorar o uso da memória para que a instância opere em um estado íntegro.

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

  • Memória global: é compartilhada em 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 sobre configuração, consulte Práticas recomendadas gerais e Diretrizes operacionais.

Sinalizações e uso da memória

Sempre que houver alta utilização de memória pelas instâncias do Cloud SQL, as seguintes perguntas poderão 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: é a memória compartilhada que o PostgreSQL aloca para manter os dados da tabela das operações read e write. Para a operação read, todos os 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 o shared_buffers para armazenamento em cache e depois 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 de atividades de banco de dados, como armazenamento de dados em cache, cache de conexão e operações de Linguagem de manipulação de dados (DML, na sigla em inglês). O máximo que essa área pode alocar é especificado pela sinalização 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 será alto.

  • Memória de trabalho de consulta: à medida que uma consulta é executada, o PostgreSQL aloca memória local para cada operação, como classificação e hash. O máximo que ele pode alocar para cada operação de uma consulta antes de gravar em arquivos de disco temporários é configurado pela sinalização work_mem, e o valor padrão é 4 MB. Se o valor de work_mem for alto, a quantidade de dados que pode ser classificada na memória 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 que o PostgreSQL aloca. A quantidade máxima para o processo de back-end usada por essas operações pode ser configurada pela sinalização maintenance_work_mem, e o valor padrão é de 64 MB. Os workers do autovacuum também usam a memória de trabalho de manutenção, e o máximo pode ser substituído pela sinalização 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 do banco de dados, o PostgreSQL aloca buffers temporários para manter a tabela temporária local da sessão. O valor máximo pode ser especificado pela sinalização temp_buffers, e o valor padrão é de 8 MB.
  • Conexão de banco de dados: quando um cliente se conecta ao banco de dados, o PostgreSQL cria um processo de back-end para veicular a sessão do cliente. Além da memória para executar a consulta, o PostgreSQL aloca mais memória para manter informações como o cache de catálogo do sistema e os planos de consulta preparados. A quantidade máxima de conexões simultâneas permitidas para o servidor de banco de dados pode ser configurada pela sinalização max_connections. Cada conexão inativa 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 à custa da memória.

Para ver a lista completa de componentes de memória no PostgreSQL, consulte a documentação do PostgreSQL. Para alterar ou modificar as sinalizações listadas nesta seção, consulte Configurar sinalizações do banco de dados.

Monitorar o uso da memória

Monitore a memória da 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 alertar quando o uso exceder 90% do limite por seis horas. Esse alerta pode avisar quando o uso de memória estiver próximo do limite constantemente.

Além disso, monitore incidentes de falta de memória. Para fazer isso, configure uma métrica com base em registros para a mensagem server process .* was terminated by signal 9: Killed no Cloud Monitoring para contar os eventos de memória insuficiente e alerta sempre que ocorre um evento.

Se a instância opera constantemente acima de 90% do limite de memória ou se ocorre um evento sem memória, é possível aumentar a memória da instância. Como alternativa, é possível reduzir o uso de memória limitando o número de conexões de banco de dados ou diminuindo as sinalizações do banco de dados, como shared_buffers, work_mem ou max_connections. A redução dessas sinalizações pode limitar o desempenho da instância.

Memória insuficiente

Quando não houver memória suficiente para processar a carga de trabalho do banco de dados, como último recurso, o sistema operacional Linux subjacente usará o out-of-memory (OOM) killer para encerrar um processo de liberação de memória. O Cloud SQL é configurado para que OOM killer seja direcionado apenas aos processos de worker do PostgreSQL. O processo postmaster é preservado nessa situação, de modo que ele precise apenas encerrar todas as conexões de banco de dados existentes e executar uma recuperação para proteger a integridade do banco de dados. Se isso acontecer, há momentos de interrupção de serviço e inatividade no banco de dados. No registro do banco de dados PostgreSQL, são exibidas mensagens como as seguintes:

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

A seguir