Database OCI con best practice di storage PostgreSQL

Scopri le best practice per identificare, monitorare e risolvere i problemi relativi allo storage quando utilizzi OCI Database con PostgreSQL.

OCI Database con PostgreSQL è un servizio completamente gestito che gestisce automaticamente lo storage. A differenza del tradizionale PostgreSQL che richiede l'allocazione manuale dello spazio su disco, OCI PostgreSQL utilizza lo storage ottimizzato per il database che si ridimensiona in modo indipendente dalle risorse di computazione.

OCI Database with PostgreSQL è basato sullo standard PostgreSQL e segue le linee guida della community per la sicurezza e il layout del disco, garantendo un'esperienza familiare agli utenti PostgreSQL. Per ulteriori informazioni, consulta il seguente blog: Presentazione di OCI Database con PostgreSQL: Completing Our Cloud Database Suite for Every Need.

Tipi di memoria

OCI Database con PostgreSQL utilizza le seguenti categorie di storage primario con caratteristiche e requisiti di gestione diversi:

Scalabilità automatica dello storage condiviso

Lo storage condiviso su scala automatica gestisce i dati del database e i file WAL (Write-Ahead Log). Questo tipo di storage fornisce alta disponibilità tramite la replica tra i domini di disponibilità.

Di seguito sono riportate le caratteristiche chiave dello storage condiviso su scala automatica.

  • Scalabilità dinamica: lo storage si ridimensiona automaticamente quando crei ed elimini gli oggetti di database. Non è richiesto alcun pre-provisioning e non si verificano tempi di inattività durante il ridimensionamento.
  • Architettura disaccoppiata: computazione e storage sono separati, consentendo a ciascuno di ridimensionarsi in modo indipendente in base alle tue esigenze.
  • Alta disponibilità: i dati vengono replicati tra i domini di disponibilità, consentendo un failover rapido senza perdita di dati.
  • Limite rigido: la capacità massima è di 32 TB per sistema di database.

La memorizzazione condivisa su scala automatica memorizza i tipi di contenuto riportati di seguito.

  • Dati di database quali tabelle, indici e altri oggetti di database.
  • File WAL per durabilità e replica delle transazioni.

Stoccaggio temporaneo

Lo storage temporaneo viene allocato per ogni nodo e gestisce i file operativi che non richiedono persistenza a lungo termine. Questo storage non viene ridimensionato automaticamente e viene dimensionato in base alla forma di computazione. La formula per questa dimensione di storage si basa su Max (50 GB, 2 GB + numOCPU × 32 GB).

Di seguito sono riportate le caratteristiche principali dello storage temporaneo.

  • Non esegue la scala automatica: per aumentare la capacità, è necessario eseguire l'upgrade a una forma di computazione più grande.
  • Isolato da dati critici: se lo storage temporaneo si riempie, i dati del database e WAL rimangono inalterati.

Lo storage temporaneo memorizza i seguenti tipi di contenuto:

  • File temporanei/di versamento da pgsql_tmp/pg_tempdir e pg_replslot, creati quando le query superano la memoria disponibile.
  • File di log PostgreSQL per il monitoraggio e il debug.
  • File di distribuzione dello slot di replica (per la replica logica).

Il resto di questo argomento riguarda le best practice per la gestione dei problemi di esaurimento dello storage per questi tipi di storage.

Esaurimento dello storage condiviso

Gli slot di replica garantiscono che i file WAL vengano conservati fino a quando non vengono utilizzati dai sottoscrittori. Quando uno slot di replica diventa inattivo o è in ritardo, PostgreSQL continua ad accumulare file WAL, che alla fine possono esaurire lo storage condiviso.

Di seguito sono riportati gli scenari comuni in cui può verificarsi l'esaurimento dello storage condiviso.

  • Slot abbandonati: un sottoscrittore è stato disattivato, ma lo slot di replica non è stato eliminato
  • Problemi di rete: problemi di latenza elevata o di connettività tra primario e standby causano il ritardo dello standby
  • Slow subscribers: strumenti CDC di terze parti o abbonati federati che non possono stare al passo con l'attività di scrittura
  • Transazioni con tempi di esecuzione lunghi: le sessioni inattive bloccano il buffer di riordino, causando l'accumulo di WAL

La tabella seguente mostra i parametri di conservazione WAL chiave. L'uso del disco WAL dipende da questi parametri, in combinazione con gli slot di replica attivi o inattivi.

Parametri di conservazione WAL
Parametro Descrizione
max_slot_wal_keep_size

Limite di conservazione WAL per gli slot di replica (-1 = illimitato, che rischia di riempire il disco). Ad esempio:

max_slot_wal_keep_size = 20GB

Conserva sempre 20 GB di WAL dall'indirizzo replay_lsn di ogni slot.

max_wal_size

Dimensione massima WAL prima di forzare un CHECKPOINT. Ad esempio:

max_wal_size = 5GB

forza CHECKPOINT quando WAL raggiunge i 5 GB.

wal_keep_size

Numero minimo di file WAL da conservare per la sicurezza in standby (senza slot di replica). Ad esempio:

wal_keep_size = 10GB

mantiene sempre 10 GB di WAL dall'attuale LSN.

Nella tabella seguente sono elencati i vantaggi e i rischi delle configurazioni WAL.

Vantaggi e rischi della configurazione dei parametri
Configurazione parametri Vantaggio Rischio
max_slot_wal_keep_size = -1 La replica non si interrompe a causa della rimozione WAL. Il disco principale può riempirsi.
max_slot_wal_keep_size = 50GB Primario è protetto dall'esaurimento del disco. La replica potrebbe interrompersi se il standby è troppo in ritardo.

Monitoraggio e avvisi

Utilizzare la query seguente per identificare la conservazione WAL in base agli slot di replica:

SELECT 
    slot_name,
    active,
    pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS wal_retained,
    pg_size_pretty(safe_wal_size) AS safe_wal_remaining
FROM pg_replication_slots;

In questo esempio di restituzione, vengono conservati 15 GB di WAL e solo 5 GB in più possono essere conservati prima che lo slot venga invalidato (se è configurato max_slot_wal_keep_size). Se max_slot_wal_keep_size = -1, safe_wal_remaining mostra NULL.

 slot_name | active | wal_retained | safe_wal_remaining
-----------+--------+--------------+--------------------
 replica_1 | t      | 15 GB        | 5 GB

Per istruzioni sull'impostazione di allarmi personalizzati, vedere Creare allarmi e dashboard di monitoraggio OCI personalizzati PostgreSQL utilizzando le istanze contenitore

Si consiglia di impostare avvisi se si verifica una delle seguenti condizioni:

  • wal_retained supera il 50% della capacità disponibile.
  • Qualsiasi slot contiene active = false per più di un'ora.

Mitigazione e prevenzione

Utilizzare le seguenti misure di attenuazione in base alle esigenze:

  • Eliminare gli slot abbandonati: se un sottoscrittore non è più necessario o può essere ricreato, eliminare lo slot di replica:
    SELECT pg_drop_replication_slot('slot_name');
  • Impostare il limite di conservazione finito: configurare max_slot_wal_keep_size in un valore che bilancia la stabilità della replica con la protezione primaria.
Ti consigliamo di seguire queste misure di prevenzione:
  • Selezionare il file max_slot_wal_keep_size appropriato in base ai seguenti requisiti:
    • Per la replica critica: impostare un valore superiore o -1, ma monitorare attentamente l'uso del disco.
    • Per la protezione primaria: impostare un valore finito e accettare l'interruzione della replica durante le interruzioni estese.
    • Per i sottoscrittori ricreabili: utilizzare valori inferiori perché il sottoscrittore può essere ricreato, se necessario.
  • Implementare il monitoraggio degli slot: impostare gli avvisi automatici prima che gli slot causino problemi di storage.
  • Proprietà slot documento: consente di gestire un record di cui l'applicazione o il team possiede ogni slot di replica.
  • Pianificare i problemi di rete: garantire larghezza di banda adeguata e bassa latenza tra primaria e replica.

Esaurimento stoccaggio temporaneo

L'archiviazione temporanea può essere esaurita da log eccessivi, impostazioni di memoria inadeguate che causano file di fuoriuscita o file di fuoriuscita dello slot di replica. Questa sezione copre ogni scenario con linee guida di monitoraggio e risoluzione.

Eccessivo log PostgreSQL

PostgreSQL fornisce parametri di log estesi utili per il debug. Tuttavia, le impostazioni di registrazione aggressive possono generare un numero eccessivo di I/O su disco durante il traffico di picco e riempire rapidamente il volume di storage temporaneo.

Di seguito sono riportate le configurazioni problematiche comuni.

  • log_statement = 'all': registra ogni istruzione SQL, generando enormi volumi di log sui sistemi occupati.
  • log_min_duration_statement = 0: registra ogni istruzione con la relativa durata.
  • log_connections/log_disconnections = on: nei sistemi con traffico elevato vengono generate voci per ogni connessione.
  • Log a livello di debug abilitato a sinistra: parametri quali log_executor_stats, log_parser_stats, log_planner_stats generano output descrittivo.

I sintomi di log eccessivo di PostgreSQL includono:

  • L'uso temporaneo dello stoccaggio aumenta rapidamente.
  • I/O su disco elevato sul volume di log.

Mitigazione e prevenzione

Attenersi alle linee guida riportate di seguito per mitigare e prevenire i problemi correlati alla registrazione eccessiva.

  • Rivede e ottimizza i parametri di log in base ai requisiti dell'applicazione.
  • Disabilitare il log dettagliato al termine del debug.
  • Evitare di lasciare abilitato il log a livello di debug in produzione poiché aggiunge un carico non necessario al database server.
  • Se le esigenze di log legittimo richiedono più spazio, aumentare la forma del nodo o ridimensionare verticalmente il sistema di database.

Nella tabella seguente sono elencati i parametri di log e le informazioni correlate.

Parametri di log
Parametro Descrizione Valore problematico Valore consigliato
log_statement Controlla le istruzioni SQL registrate tutto nessuno o ddl o mod
log_min_duration_statement Istruzioni di log che superano i millisecondi specificati 0 -1 o ≥1000
log_connections Registra ogni connessione riuscita su (traffico elevato) disattivato
log_disconnections Registra le cessazioni delle sessioni, inclusa la durata su (traffico elevato) disattivato
log_autovacuum_min_duration Registra le azioni di autovuoto che superano i millisecondi specificati 0 -1 o ≥60000
log_error_verbosity Controlla il livello di dettaglio dei messaggi di errore descrittivo predefinito
log_executor_stats Registra le statistiche delle prestazioni dell'esecutore attivo disattivato
log_parser_stats Statistiche delle prestazioni del parser dei log attivo disattivato
log_planner_stats Statistiche prestazioni planner log attivo disattivato
log_statement_stats Registra le statistiche sulle prestazioni totali delle istruzioni attivo disattivato
log_duration Registra la durata di ogni istruzione completata su (traffico elevato) disattivato

Impostazioni di memoria inadeguate (file temporanei/di fuoriuscita)

PostgreSQL utilizza memoria aggiuntiva oltre shared_buffers per l'elaborazione delle query. Mentre shared_buffers gestisce l'inserimento dei dati nella cache e le operazioni DML in memoria, work_mem viene utilizzato per le operazioni di query quali l'ordinamento, il join e l'aggregazione.

Quando una query coinvolge operazioni JOIN, AGGREGATE o SORT, PostgreSQL controlla prima se le colonne pertinenti hanno indici presortiti. Se gli indici non sono disponibili, PostgreSQL tenta di eseguire queste operazioni in memoria.

Se l'impostazione work_mem non è sufficiente per i dati elaborati, PostgreSQL genera file temporanei e utilizza il disco anziché la memoria.

Di seguito sono riportati gli scenari comuni in cui possono verificarsi impostazioni di memoria inadeguate.

  • Query analitiche complesse: query con più JOIN, ordinamenti di grandi dimensioni o aggregazioni su set di dati di grandi dimensioni.
  • L'impostazione predefinita work_mem è troppo bassa: il valore predefinito di 4 MB potrebbe essere insufficiente per le query complesse.
  • Concorrenza elevata con query a uso intensivo di memoria: molte query simultanee ciascuna che utilizza work_mem.
  • Operazioni di manutenzione: operazioni quali CREATE INDEX, REINDEX, CLUSTER o REFRESH MATERIALIZED VIEW utilizzano maintenance_work_mem e possono generare file temporanei se la dimensione è insufficiente.

L'esempio seguente mostra una voce di log di esempio quando il disco diventa pieno.

2025-12-03 10:55:25.650 UTC [249610] ERROR: could not write block 196800198 of temporary file: No space left on device

I sintomi di impostazioni di memoria inadeguate eccessive includono:

  • Storage temporaneo durante l'esecuzione di query complesse.
  • Prestazioni di query lente sulle operazioni JOIN, SORT o AGGREGATE.
  • Aumento dell'I/O su disco durante l'elaborazione delle query.

Monitoraggio e avvisi

Utilizzare la query seguente per identificare l'uso temporaneo del file per database:

SELECT 
    datname,
    temp_files,
    pg_size_pretty(temp_bytes) AS temp_size
FROM pg_stat_database
WHERE temp_bytes > 0
ORDER BY temp_bytes DESC;

Ecco un esempio di ciò che viene restituito:

 datname  | temp_files | temp_size  
----------+------------+------------
 app      |       1523 | 45 GB      
 postgres |         12 | 120 MB  
Nota

Questi valori sono cumulativi. Mentre il database continua a generare file temporanei, questi valori aumentano nel tempo.

Utilizzare la query seguente per controllare l'uso del file temporaneo attivo:

SELECT * FROM pg_ls_tmpdir();

Ecco un esempio di ciò che viene restituito:

       name        |   size   |      modification      
-------------------+----------+------------------------
 pgsql_tmp249610.3 | 14000000 | 2025-12-03 10:20:16+00
 pgsql_tmp249696.0 | 12394496 | 2025-12-03 10:20:16+00
 pgsql_tmp249610.2 | 13860864 | 2025-12-03 10:20:16+00
 pgsql_tmp249697.0 | 12910592 | 2025-12-03 10:20:16+00

Inserire i seguenti comandi per controllare le impostazioni di memoria correnti:

SHOW work_mem;
SHOW hash_mem_multiplier;
SHOW maintenance_work_mem;

Per istruzioni sull'impostazione di allarmi personalizzati, vedere Creare allarmi e dashboard di monitoraggio OCI personalizzati PostgreSQL utilizzando le istanze contenitore

Si consiglia di impostare avvisi se si verifica una delle seguenti condizioni:

  • TempStorageUsedPercent supera le soglie definite.
  • L'utilizzo dei file temporanei (da pg_ls_tmpdir()) mostra una crescita sostenuta.

Mitigazione e prevenzione

Attenersi alle procedure riportate di seguito per mitigare e prevenire i problemi associati a impostazioni di memoria inadeguate.

  • Identifica query che generano file temporanei

    Abilitare il log per acquisire le query che generano file temporanei:

    • Impostare log_temp_files = 0 per registrare tutta la creazione di file temporanei
    • Impostare log_min_error_statement = log per includere il testo della query SQL

    Di seguito è riportata una voce di file di log temporaneo di esempio.

    2025-12-03 10:45:17.650 UTC [249610] LOG: temporary file: path "pg_tempdir/pgsql_tmp/pgsql_tmp249610.5", size 14000000
    
  • Ottimizza query

    Esaminare le query registrate e ottimizzare, ove possibile. Il tuning delle query dovrebbe essere il primo approccio prima di aumentare le impostazioni di memoria. Prendere in considerazione l'aggiunta di indici appropriati per evitare gli ordinamenti in memoria.

  • Adegua work_mem (se l'ottimizzazione delle query non è possibile)

    Se le query non possono essere migliorate, considerare l'aumento di work_mem. Utilizzare la formula seguente come punto di partenza:

    work_mem <= (Available Memory) / (max_connections + max_parallel_workers)

    Dove Available Memory è la memoria di sistema totale meno shared_buffers e oci.pagecache_size.

    Nota

    Negli scenari peggiori, ogni sessione potrebbe utilizzare questa quantità di memoria. Se tutte le sessioni richiedono work_mem contemporaneamente, potrebbe esaurire la memoria di sistema disponibile.

    Ridurre la generazione di file temporanei, ma non eliminarli completamente. L'eliminazione di tutti i file temporanei potrebbe richiedere una forma di computazione più grande o il consumo di tutta la memoria disponibile.

  • Rettifica hash_mem_multiplier (per operazioni hash)

    Se le query continuano a generare file temporanei e coinvolgono operazioni hash (non SORT), aumentare hash_mem_multiplier:

    SHOW hash_mem_multiplier;
     hash_mem_multiplier 
    ---------------------
     1
    (1 row)
    

    L'aumento di questo valore alloca più memoria per le operazioni hash. La memoria hash effettiva è work_mem × hash_mem_multiplier.

  • Adeguare maintenance_work_mem per le operazioni di manutenzione

    Le normali query dell'applicazione non sono l'unica origine dei file temporanei. Le operazioni di manutenzione generano anche file temporanei:

    • REFRESH MATERIALIZED VIEW
    • CREATE INDEX
    • CLUSTER
    • REINDEX

    Queste operazioni utilizzano maintenance_work_mem anziché work_mem:

SHOW maintenance_work_mem;

Se le operazioni di manutenzione vengono eseguite su set di dati di grandi dimensioni e maintenance_work_mem è insufficiente, vengono generati file temporanei.

Nella tabella seguente sono elencati i parametri di memoria e le informazioni correlate.

Riferimento parametri memoria
Parametro Descrizione Rischio in caso di configurazione errata Valore consigliato
work_mem Memoria di base per operazione di ordinamento/hash prima della fuoriuscita su disco Troppo alto con concorrenza elevata Più basso per OLTP, più alto per gli analytics
hash_mem_multiplier Moltiplicatore per operazioni hash: hash_mem = work_mem × questo valore Troppo alto (≥8,0) con concorrenza elevata 2.0 (predefinito)
maintenance_work_mem Memoria per operazioni VACUUM, CREATE INDEX, REFRESH MATERIALIZED VIEW Troppo alto con molti lavoratori di autovuoto Saldo con autovacuum_max_workers

File di perdita slot di replica (replica logica)

La replica logica PostgreSQL utilizza la decodifica logica per trasformare i record WAL grezzi in modifiche significative e strutturate a livello di riga. A differenza della replica fisica che copia blocchi di dischi byte-for-byte, la decodifica logica interpreta i dati transazionali e li converte in modifiche logiche (INSERT, UPDATE, DELETE) con valori di colonna effettivi.

Ogni slot di replica logica dispone di un processo mittente WAL associato responsabile delle modifiche di streaming ai sottoscrittori di destinazione. Le transazioni vengono inviate in ordine di commit e l'abbonato riceve, decodifica e applica queste modifiche al sistema di destinazione.

PostgreSQL supporta la replica logica nativa in cui il sottoscrittore è un'altra istanza PostgreSQL. A partire da PostgreSQL 14, gli abbonati possono gestire grandi transazioni in corso in modo efficiente con la modalità streaming=on abilitata:

  • Le transazioni in corso (non ancora sottoposte a commit) vengono trasmesse in modo incrementale al sottoscrittore.
  • Il sottoscrittore applica immediatamente le modifiche a uno stato temporaneo/in sospeso.
  • Dopo il commit della transazione sul publisher, il sottoscrittore esegue il commit di tali modifiche.
  • Se viene eseguito il rollback della transazione, il sottoscrittore ignora le modifiche in sospeso.

Questo approccio impedisce al publisher di accumulare grandi quantità di dati decodificati nei file di memoria o di fuoriuscita in attesa del completamento di transazioni con tempi di esecuzione lunghi.

Gli iscritti federati o di terze parti possono utilizzare anche gli slot di replica logica PostgreSQL utilizzando il protocollo di replica PostgreSQL. Tuttavia, a differenza dei sottoscrittori nativi PostgreSQL, i sottoscrittori federati in genere non supportano la modalità streaming=on perché non possono controllare il funzionamento del sistema di destinazione di base.

Quando un sottoscrittore non supporta streaming=on, il mittente WAL PostgreSQL mantiene le modifiche decodificate per le transazioni in corso nei file di fuoriuscita all'indirizzo:

pg_replslot/<slot_name>/xid-<xid>-lsn-<lsn>.spill

Questi file di fuoriuscita possono crescere a causa della rigorosa garanzia di commit-order di PostgreSQL. Ad esempio:

  • La transazione TRX1 rimane aperta per molto tempo (inattivo nella transazione o durante l'esecuzione di operazioni di massa).
  • Altre transazioni indipendenti (TRX2, TRX3, TRX4 e così via) continuano a essere impegnate.
  • Il mittente WAL accumula i dati di transazione impegnati nei file di fuoriuscita.
  • Queste transazioni vengono inviate all'abbonato solo dopo che TRX1 ha emesso COMMIT o ROLLBACK.

Questo comportamento è previsto quando si lavora con sottoscrittori federati che non supportano la modalità streaming=on.

L'esempio seguente mostra i dettagli del file di fuoriuscita (registrato a livello DEBUG2) nel log:

2025-12-03 10:28:14.650 UTC [249610] DEBUG: spill 4096 changes in XID 750 to disk

Se il disco diventa pieno, le voci di log vengono modificate come indicato di seguito.

2025-12-03 10:32:15.550 UTC [249610] ERROR: could not write to data file for XID <xid>: No space left on device
2025-12-03 10:32:15.554 UTC [249610] ERROR: could not read from reorderbuffer spill file: No space left on device

I sintomi dei file di fuoriuscita degli slot di replica includono:

  • L'utilizzo temporaneo dello storage aumenta rapidamente.
  • Molti file .spill sono presenti nella cartella pg_replslot.

Monitoraggio e avvisi

Utilizzare la query seguente per identificare le statistiche dei file di distribuzione per gli slot di replica:

SELECT 
    slot_name,
    spill_txns,
    spill_count,
    pg_size_pretty(spill_bytes) AS spill_size,
    stream_txns,
    stream_count,
    pg_size_pretty(stream_bytes) AS stream_size
FROM pg_stat_replication_slots;

Nell'esempio seguente viene restituito:

    slot_name     | spill_txns | spill_count | spill_size | stream_txns | stream_count | stream_size 
------------------+------------+-------------+------------+-------------+--------------+-------------
 federated_sub_1  |        847 |       15234 | 2458 MB    |           0 |            0 | 0 bytes
  • spill_size di 2458 MB indica un uso significativo del disco dai file di fuoriuscita.
  • stream_size di 0 byte conferma che l'abbonato non è nativo e non supporta la modalità di streaming.
  • Il processo del mittente WAL sta tenendo o versando transazioni su disco.

Utilizzare il comando seguente per controllare l'impostazione corrente di logical_decoding_work_mem:

SHOW logical_decoding_work_mem;
 logical_decoding_work_mem 
---------------------------
 64MB

Per istruzioni sull'impostazione di allarmi personalizzati, vedere Creare allarmi e dashboard di monitoraggio OCI personalizzati PostgreSQL utilizzando le istanze contenitore

Si consiglia di impostare avvisi se si verifica una delle seguenti condizioni:

  • spill_bytes per slot supera le soglie definite.
  • L'uso del file di fuoriuscita mostra una crescita rapida.

Mitigazione e prevenzione

Le transazioni di versamento sono inevitabili quando sono coinvolti sottoscrittori non nativi. Tuttavia, è possibile ridurre la frequenza e le dimensioni dei file di fuoriuscita seguendo queste procedure:

  • Gestire transazioni di grandi dimensioni con attenzione: eseguire operazioni di massa in batch più piccoli.
  • Evitare transazioni inattive con tempi di esecuzione lunghi: blocca il buffer di riordino e causa l'accumulo del file di fuoriuscita.
  • Aumenta logical_decoding_work_mem: ritarda la fuoriuscita consentendo un maggior numero di dati decodificati in memoria.
  • Imposta idle_in_transaction_session_timeout: termina le sessioni che rimangono inattive nella transazione per troppo tempo.

Nella tabella seguente sono elencati i parametri di decodifica logica e le informazioni correlate.

Riferimento parametri di decodifica logica
Parametro Descrizione Rischio in caso di configurazione errata Valore consigliato
logical_decoding_work_mem Soglia di memoria prima dello spilling delle modifiche decodificate in pg_replslot/<slot>/. Questo valore si applica a ciascuno slot di replica logica. Troppo basso con transazioni di grandi dimensioni/lunghe 256 MB-1 GB
idle_in_transaction_session_timeout Termina le sessioni inattive nella transazione che bloccano la distribuzione del buffer di riordino 0 (disabilitato) 10-30 min