Best practice per la gestione dell'utilizzo della memoria

Questa pagina descrive come configurare l'utilizzo della memoria per un'istanza Cloud SQL.

Introduzione

Quando crei un'istanza Cloud SQL, selezioni una quantità di memoria per l'istanza. All'aumentare del carico di lavoro di un database PostgreSQL, aumenta anche l'utilizzo della memoria dell'istanza. Le istanze che consumano molta memoria possono creare un collo di bottiglia delle prestazioni che a volte può portare a problemi di esaurimento della memoria.

Quando un'istanza Cloud SQL esaurisce la memoria a causa di un aumento della domanda, può causare tempi di inattività del database. Di conseguenza, è importante configurare correttamente la memoria dell'istanza e i flag di database relativi alla memoria e monitorare l'utilizzo della memoria in modo che l'istanza funzioni in uno stato integro.

I componenti di memoria PostgreSQL sono generalmente suddivisi in due sezioni:

  • Memoria globale: viene condivisa con tutti i processi per l'esecuzione di query, ad esempio shared_buffers e max_connections.
  • Memoria locale:è la memoria dedicata assegnata a ogni connessione, ad esempio work_mem, maintenance_work_mem e temp_buffers.

Per altre considerazioni sulla configurazione, consulta le best practice generali e le linee guida operative.

Utilizzo della memoria e flag

Ogni volta che si verifica un elevato utilizzo della memoria da parte delle istanze Cloud SQL, potrebbero sorgere le seguenti domande:

  • Quale query o processo utilizza un'elevata memoria?
  • Le impostazioni della memoria sono adeguate per l'attività del database?
  • Come si modificano le impostazioni della memoria?

Quando funziona un database PostgreSQL, la maggior parte dell'utilizzo della memoria avviene in alcune aree:

  • Buffer condiviso: si tratta della memoria condivisa che PostgreSQL alloca ai dati della tabella per le operazioni read e write. Per l'operazione read, tutti i dati richiesti dal disco vengono prima recuperati sulla RAM e poi forniti al client. Allo stesso modo, in PostgreSQL, quando i dati vengono richiesti (ad esempio SELECT * from emp), vengono prima recuperati dal disco a shared_buffers per la memorizzazione nella cache e poi forniti al client. Lo stesso accade con l'operazione write.

    Il buffer condiviso è anche l'area di memoria condivisa per tutti i processi e le connessioni per le attività di database come la memorizzazione nella cache dei dati, la memorizzazione nella cache delle connessioni e le operazioni DML (Data Manipulation Language). Il limite massimo che questa area può allocare è specificato dal flag shared_buffers e il valore predefinito è il 33% della memoria dell'istanza. Se il valore di shared_buffers è elevato, la dimensione dei dati memorizzati nella cache è elevata.

  • Memoria di lavoro delle query: man mano che viene eseguita una query, PostgreSQL alloca la memoria locale per ogni operazione, ad esempio ordinamento e hashing. Il limite massimo che è possibile allocare per ogni operazione di una query prima di scrivere nei file del disco temporaneo viene configurato dal flag work_mem e il valore predefinito è 4 MB. Se il valore di work_mem è elevato, la quantità di dati che possono essere ordinati in memoria è elevata.
  • Memoria di lavoro di manutenzione: alcune operazioni di manutenzione come VACUUM, CREATE INDEX, ALTER TABLE e ADD FOREIGN KEY richiedono memoria locale separata allocata da PostgreSQL. La quantità massima per il processo di backend utilizzato da queste operazioni può essere configurata dal flag maintenance_work_mem e il valore predefinito è 64 MB. Tieni presente che anche i lavoratori di autoaspirapolvere utilizzano la memoria di lavoro di manutenzione e il numero massimo può essere sostituito dal flag autovacuum_work_mem. Se il valore di maintenance_work_mem è elevato, la velocità dell'operazione VACUUM è elevata.
  • Buffer temporanei: quando viene utilizzata una tabella temporanea in una sessione di database, PostgreSQL alloca buffer temporanei per contenere la tabella temporanea locale della sessione. La quantità massima può essere specificata dal flag temp_buffers e il valore predefinito è 8 MB.
  • Connessione database: quando un client si connette al database, PostgreSQL crea un processo di backend per gestire la sessione client. Oltre alla memoria per eseguire la query, PostgreSQL alloca memoria aggiuntiva per gestire informazioni quali la cache del catalogo di sistema e i piani di query preparati. Il numero massimo di connessioni simultanee consentite al server di database può essere configurato con il flag max_connections. Ogni connessione inattiva utilizza circa 2-3 MB di memoria condivisa. Se il valore di max_connections è elevato, l'istanza può effettuare più connessioni, ma a scapito della memoria.

Per l'elenco completo dei componenti di memoria in PostgreSQL, consulta la documentazione di PostgreSQL. Per cambiare o modificare i flag elencati in questa sezione, vedi Configurare i flag di database.

Monitoraggio dell'utilizzo della memoria

Monitora la memoria della tua istanza in Cloud Monitoring regolarmente e mantienila al di sotto del limite di memoria. È buona norma impostare un avviso in Cloud Monitoring per avvisare quando l'utilizzo supera il 90% del limite per 6 ore. Questo avviso può avvisarti quando l'utilizzo della memoria è costantemente vicino al limite.

Inoltre, monitora gli incidenti per esaurimento memoria. Per farlo, configura una metrica basata su log per il messaggio server process .* was terminated by signal 9: Killed in Cloud Monitoring in modo da conteggiare gli eventi di esaurimento della memoria e avvisare ogni volta che si verifica un evento di questo tipo.

Se l'istanza opera costantemente al di sopra del 90% del limite di memoria o si verifica un evento di esaurimento della memoria, puoi aumentare la memoria dell'istanza. In alternativa, puoi ridurre l'utilizzo della memoria limitando il numero di connessioni al database o riducendo i flag di database come shared_buffers, work_mem o max_connections. L'abbassamento di questi flag può limitare le prestazioni dell'istanza.

Memoria esaurita

Se la memoria è insufficiente per gestire il carico di lavoro del database, come ultima alternativa possibile, il sistema operativo Linux sottostante utilizza out-of-memory (OOM) killer per terminare un processo per rilasciare memoria. Cloud SQL è configurato in modo che OOM killer abbia come target solo i processi worker PostgreSQL. In questa situazione, il processo postmaster viene conservato, in modo da dover terminare tutte le connessioni al database esistenti ed eseguire un ripristino per proteggere l'integrità del database. In questo caso, si verificano momenti di interruzione del servizio e tempo di inattività del database. Nel log del database PostgreSQL, vengono visualizzati messaggi come quelli che seguono:

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

Passaggi successivi