Questa pagina è stata tradotta automaticamente. Leggi l'originale in inglese. English

Libreria IBSurgeon

23 altri modi per velocizzare Firebird

Alexey Kovyazin, IBSurgeon, [email protected], 08-Gen-2019

Traduzioni: Portoghese

Perché “23 in più”?

Alcuni di voi ricordano l’articolo « 45 Modi Per Accelerare Firebird», pubblicato a maggio 2016. Ora è il momento di pubblicare la prossima serie di suggerimenti e trucchi, basati principalmente sull’esperienza di ottimizzazione e manutenzione dei database e server Firebird con un numero elevato di connessioni (1000+).

1. Impostare le Opzioni di Risparmio Energia su Prestazioni elevate in Windows Server 2016 e 2019

Per impostazione predefinita, Windows Server ha un piano di alimentazione impostato su “Bilanciato”, che non è adatto per i server di database. Impostarlo su “Prestazioni elevate” e ottenere circa +20% delle prestazioni per le operazioni ad alta intensità di CPU. Può essere impostato online, senza riavvio o reboot. L’immagine qui sotto mostra il grafico della CPU, che dimostra il vantaggio del piano di alimentazione “Prestazioni elevate”:

Maggiori dettagli sui nostri test con i piani di alimentazione di Windows possono essere trovati qui.

2. Abilitare «Interagisci con il desktop» su Classic per Windows

Se si utilizza Firebird con architettura Classic su Windows, abilitare la spunta «Consenti al servizio di interagire con il desktop». Senza questa impostazione, la risorsa «desktop heap» è limitata da Windows, e Firebird non può aprire più di 250-300 connessioni (dipende dai metadati del database e dal relativo consumo di memoria) - ci sarà un errore di memoria esaurita.

3. Attenzione: Domain Controller

Il problema che Windows con ruolo Domain Controller disabilita la cache di scrittura sul disco con il database Active Directory.

Questo influisce su Firebird in vari modi (così come su altre applicazioni, ovviamente), e dimostra prestazioni significativamente peggiori rispetto ai server senza ruoli Active Directory.

Si prega di notare che questo problema riguarda versioni popolari di Windows come Windows Small Business Server 2011, così come altre versioni con DC.

4. Aumentare il limite «max open files» su Linux

Se si utilizza Linux come server di database, non dimenticare di regolare i limiti per Firebird. Controllare i limiti per il processo Firebird (SuperServer o SuperClassic) con il seguente comando:

Code
cat /proc//limits

e prestare attenzione alla riga con il numero massimo di file aperti.

Firebird può utilizzare fino a 4 handle per connessione, e se si ha qualcosa come questo:

Code
Max open files 4096 4096 files

significa che il numero totale di connessioni servite dal processo Firebird sarà limitato a circa 1000.

Si prega di notare - se si hanno 4 database sul server, la connessione per ogni database viene conteggiata.

Impostare di più - consiglio 65535.

Non dimenticare di controllare di nuovo dopo il riavvio del processo Firebird: se è stato applicato o no.

Per l’architettura Classic, è necessario controllare e aumentare i limiti per l’utente «firebird».

5. Utilizzare Linux moderno

Sì, capisco che questo consiglio è banale, ma ho visto molte volte un buon miglioramento delle prestazioni dopo la migrazione da CentOS 6 a 7, Ubuntu 12 a 16 (sullo stesso hardware!), quindi ora è una raccomandazione indispensabile per i server di database con più di 250-300 connessioni. Il Linux moderno è un prerequisito prima di ulteriori passaggi di ottimizzazione.

Versioni consigliate di Linux: CentOS 7.x e Ubuntu 16, 18.

6. Riservare il 40% di RAM per la cache dei file su Windows

Il Memory Manager del sistema operativo ha implicazioni riguardo all’allocazione della memoria e, per impostazione predefinita, Windows richiede il 40% di RAM per la cache dei file.

Sfortunatamente, il povero strumento Windows Task Manager mostra la memoria, che viene utilizzata per la cache dei file come «libera», e alcuni amministratori cercano di far consumare a Firebird tutta questa memoria libera, quindi impostano il parametro DefaultDBCachePage in firebird.conf a valori molto alti, e questo di solito porta allo swapping.

Utilizzare sempre lo strumento RAMMap per vedere l’utilizzo effettivo della memoria su Windows.

La regola empirica per Windows Server (dedicato all’uso come server Firebird) è la seguente: la memoria di Firebird (Working Set) dovrebbe essere inferiore al 40% della RAM totale. Se la dimensione totale dei working set per tutti i processi è superiore al 50%, lo swap può essere avviato da Windows.

Si prega di notare: “riservare” qui significa non solo “non impostare troppi page buffers in Firebird” ma, anche importante, limitare l’uso della memoria di altri software. Ad esempio, se si ha MS Exchange o MSSQL sullo stesso server con Firebird, assicurarsi di limitare i loro appetiti di memoria.

Se siete interessati a conoscere i dettagli, ho registrato il webinar dedicato alla gestione della memoria in Firebird:

7. Riservare il 30% di RAM per la cache dei file su Linux

Linux funziona con la cache dei file in modo diverso da Windows e, in generale, la quantità di RAM utilizzata per la cache dei file può essere significativamente inferiore rispetto a Windows, senza un degrado evidente delle prestazioni di Firebird. Tuttavia, per garantire alte prestazioni del sistema con un numero elevato di connessioni, soprattutto su Classic e SuperClassic, una buona idea sarà riservare il 30% di RAM per la cache dei file.

8. Utilizzare irqbalance su Linux

irqbalance spesso migliora le prestazioni di Firebird e il bilanciamento del carico della CPU sui server con un numero elevato di core.

9. Per le Macchine Virtuali - attenzione al Memory Overcommit

Una Macchina Virtuale può essere configurata per avere più memoria di quella fisicamente esistente sulla macchina host - con una funzionalità nota come Memory Overcommit (il nome può essere diverso sui diversi sistemi di virtualizzazione). Ciò significa che in caso di picco di consumo di memoria (sulla VM con il server di database o sulla VM vicina) lo swap può iniziare, il che porterà a ritardi significativi. Per una VM ad alte prestazioni destinata a un server di database, tutta la memoria dovrebbe essere statica.

10. Per le Macchine Virtuali - controllare i limiti della VM

Spesso le VM vengono create con limiti predefiniti di CPU e IO, che possono essere molto bassi, come 50 IOPS e 10% di CPU. Controllare le impostazioni della VM del server e rimuovere eventuali limiti - un server di database ad alte prestazioni dovrebbe avere tutta la CPU, la larghezza di banda e l’IO possibili.

11. Pulire i file temporanei di Firebird

Firebird crea molti file temporanei per varie operazioni: ordinamento, elaborazione BLOB, tracciamento. Questi file sono memorizzati nelle seguenti posizioni: su Windows C:\ProgramData\firebird, su Linux / tmp / firebird

Normalmente questi file dovrebbero essere puliti automaticamente, tuttavia, a volte non accade (ad esempio, in caso di riavvio del server).

Controllare periodicamente queste cartelle e pulire i file vecchi - potrebbero esserci molti GB di file obsoleti fb_NNN, e pulirli libererà spazio sull’unità di sistema.

12. Non dimenticare di abilitare la cache dei file con una grande cache di Firebird

Come sapete, la cache di Firebird (chiamata anche «page buffers») è specificata dal parametro DefaultDBCachePages in firebird.conf/databases.conf, o direttamente nell’intestazione del database.

In Firebird 3 SuperServer la dimensione di questa cache può essere impostata molto alta, ma è importante ricordare un altro parametro: FileSystemCacheThreshold.

Se FileSystemCacheThreshold è inferiore a DefaultDBCachePages o ai page buffers, la cache dei file del sistema operativo non verrà utilizzata, il che può portare a problemi di prestazioni.

Nel 99% dei casi, è meglio avere la cache dei file abilitata.

Per garantire ciò, impostare sempre i parametri secondo la seguente regola:

  • DefaultDBCachePages = X
  • FileSystemCacheThreshold = X+ N, N>1

Ci sono rari casi in cui la disabilitazione della cache dei file migliora le prestazioni - se avete un esempio del genere, contattatemi - [email protected]!

13. Accelerare il database di sicurezza

Ogni connessione al database Firebird stabilisce la connessione al database di sicurezza (security3.fdb nel caso di Firebird 3) ed esegue diverse letture e scritture (pagine di transazione, pagina di intestazione). Se si hanno connessioni frequenti, le prestazioni del database di sicurezza possono diventare un problema.

Come minimo, si può fare quanto segue:

  • Aumentare i page buffers per securityN.fdb (l’ottimo empirico è 256 buffer)
  • Spostare security3.fdb su un’unità veloce (è una funzionalità standard in Firebird 3, in 2.5 richiederà la reinstallazione)

Quindi, si può impostare Forced Writes OFF per il database di sicurezza - la piccola possibilità di corruzione non è un problema in questo caso.

Il modo più radicale è rendere il database di sicurezza di sola lettura - eliminerà tutte le scritture su di esso.

Se non si cambiano spesso gli utenti nel database di sicurezza, è la soluzione migliore.

14. Provare SuperClassic su Firebird 3

In Firebird 3 l’architettura SuperServer è stata fortemente pubblicizzata come la soluzione di prestazioni definitive, ma ci sono alcuni tipi di carico che dimostrano prestazioni migliori con SuperClassic (ma non Classic - funziona sempre più lentamente di SuperServer/SuperClassic).

Come eseguire questo esperimento in modo sicuro? Seguire i passaggi seguenti:

Per provare SuperClassic

  1. Impostare in firebird.conf
  2. ServerMode=SuperClassic
  3. DefaultDbCachePages=1024
  4. gfix -buff 0
  5. Riavviare Firebird

Per tornare a SuperServer

  1. Impostare in firebird.conf
  2. ServerMode=SuperServer
  3. DefaultDbCachePages=N # N*page size*databases_count < 25% RAM
  4. FileSystemCacheThreshold = N+1
  5. gfix -buff 0
  6. Riavviare Firebird

Per favore scrivetemi ([email protected]) sui risultati dell’esperimento, sono interessato a vedere i risultati.

15. Database grande? Aumentare la dimensione della pagina

Per impostazione predefinita, i database Firebird hanno le seguenti dimensioni di pagina:

  • 2.5 - 4096 byte
  • 3.0 - 8192 byte

Tuttavia, la dimensione massima della pagina è 16K (in 4.0 - 32K).

Per database superiori a 100Gb nel 95% dei casi, è meglio avere la dimensione di pagina più alta disponibile, al fine di:

  • Diminuire la profondità degli indici. Si raccomanda di avere indici con profondità minore o uguale a 3. Gli indici con profondità 4 e 5 saranno molto più lenti
  • Aumentare l’utilizzo della RAM. La cache di Firebird è specificata in pagine, 1000 pagine con dimensione di pagina 8K saranno 8Mb di memoria effettiva, e con 16K - 16Mb.
  • Diminuire il numero di pagine di sistema. Accelererà l’accesso ai record delle tabelle grandi (meno salti puntatore-puntatore-pagina dati) e aiuta con la preparazione di grandi query SQL. Per aumentare la dimensione della pagina del database, il database deve essere sottoposto a backup con lo strumento gbak e poi ripristinato con il parametro -page ( gbak -c -page 16384).

Si prega di notare: se si ha un database con molti piccoli blob, l’aumento della dimensione della pagina può diminuire la frammentazione o aumentarla, ed è difficile prevedere se aumenterà o diminuirà le prestazioni.

16. Non utilizzare il flag no_reserve

Il flag no_reserve fa sì che Firebird non riservi spazio libero (30%) sulle pagine dati per le possibili versioni di record, che si verificano dopo UPDATE o DELETE. Questo flag consente ai dati di essere memorizzati in modo più compatto (e anche la dimensione del database è minore), ma in caso di UPDATE/DELETE tutte le modifiche vanno alla nuova pagina dati. Di conseguenza, nel database con flag no_reserve le operazioni UPDATE/DELETE sono più lente.

Quindi, se il database non è di sola lettura, consiglio di rimuovere il flag no_reserve.

Come verificare se è impostato o no - vedere la riga Attributes nell’output di

Code
gstat -h database

Come disabilitare:

Code
gfix -use reserve database

Dopo questo comando, le nuove pagine dati saranno create con spazio riservato.

Tuttavia, per ottenere l’effetto completo, è necessario eseguire il backup del database con gbak e poi ripristinarlo, in questo caso, tutte le pagine dati saranno con spazio riservato.

Si prega di notare: la dimensione del database crescerà dopo la rimozione del flag no_reserve e il backup/ripristino.

17. Impostare una dimensione iniziale alta per la tabella di lock di Firebird

La tabella di lock è il meccanismo di Firebird, che viene utilizzato per sincronizzare l’accesso agli oggetti interni del motore.

La tabella dei lock di Firebird può crescere automaticamente, ma il suo aumento è un’operazione lenta, che può portare a micro-freeze. La tabella dei lock può solo crescere, partendo dalla dimensione iniziale (impostata in firebird.conf).

Per prevenire più cicli di aumento della tabella dei lock, una buona idea è monitorare la dimensione della tabella dei lock alla fine del periodo di lavoro (giorno, settimana, ecc.), e poi impostarla come dimensione iniziale in firebird.conf.

LockMemSize=99999999

Per tua riferimento: LockMemSize su sistemi ad alto carico con ~1000 utenti è di solito inferiore a 200Mb.

18. Usare fb_lock_print per contare il numero di connessioni al database

Ottenere il numero di connessioni al database è un compito frequente per gli sviluppatori di database: può essere necessario per scopi di licenza, ad esempio.

Spesso gli sviluppatori usano la query SELECT count(*) FROM MON$ATTACHMENTS per ottenere questo valore, ma non è il modo ottimale: query frequenti sulle tabelle MON$ possono essere un peso per il database, quindi è meglio usare l’alternativa:

Esegui

fb_lock_print -d nome_database | alias

e controlla il valore Owners - mostrerà il numero corrente di connessioni al database.

19. Evitare LEFT JOIN non necessari

Spesso vedo query con una costruzione come questa:

T1 LEFT JOIN T2 ON (…) WHERE T2.Field_condition

In sostanza, la condizione su T2 esclude i NULL dall’output di LEFT JOIN T2, quindi è possibile cambiare LEFT JOIN in INNER JOIN - non influenzerà il risultato della query.

INNER JOIN dà più libertà all’ottimizzatore di Firebird, e nelle versioni moderne di Firebird, è ottimizzato molto meglio di LEFT.

Ha senso soprattutto nei seguenti casi:

  • Nessuna condizione per T1 nella clausola WHERE
  • T2 è una tabella piccola

20. Evitare conteggi di record non necessari

Un altro errore comune nelle query complesse del database e nelle stored procedure è usare select count() solo per verificare l’esistenza del record.

La seguente query leggerà tutti i record secondo condition1:

Code
(select count(*)…. where condition11) >0

Meglio usare invece questa costruzione

Code
Exists(select first 1 id where condition1)

Se condition1 restituisce più di 1 record, l’opzione proposta sarà molto più veloce, perché non legge tutti i record, si ferma dopo il primo record recuperato.

21. Evitare ordinamenti non necessari nelle stored procedure

L’ordinamento dei risultati della query all’interno della stored procedure dovrebbe essere giustificato dalla logica di business.

Ad esempio, nell’esempio di stored procedure qui sotto, la clausola ORDER BY è inutile dal punto di vista della logica di business, ma aggiunge un’operazione di ordinamento non necessaria.

Code
create or alter procedure NEW_PROCEDURE
returns (
    SUMX double precision)
as
declare variable _amount double precision;
begin
for select T1.amount from Table1 t1 where ....
    order by id
    into :_amount
    do
    begin
     sumx=sumx+_amount
    end;
  suspend;
end

Controlla il tuo codice PSQL per situazioni simili e rimuovi ORDER BY inutili (così come distinct e UNION).

22. Non mantenere le query in stato preparato senza necessità

Spesso vediamo 500-1000 statement preparati in ogni connessione (può essere verificato con query MON$).

La stragrande maggioranza di essi viene eseguita solo una volta, e poi restano semplicemente in RAM, aumentando il working set di Firebird e rallentando le query MON$.

La raccomandazione è di mantenere le query SQL in stato preparato solo se sono destinate a essere avviate molte volte, o se il loro tempo di preparazione è elevato (può esserlo per query molto grandi con molti join e accesso a tabelle enormi).

23. Chiudere sempre le query con grandi ordinamenti

Fino a quando una query SQL con ordinamento (ORDER BY, GROUP BY, UNION, distinct) non viene chiusa, Firebird mantiene i record ordinati in memoria. La dimensione della memoria allocata per l’ordinamento è impostata dal parametro TempCacheLimit in firebird.conf, di default è 64Mb.

Anche con TempCacheLimit aumentato, le query a lunga esecuzione con un grande numero di record ordinati consumeranno prima o poi tutta la quantità allocata, e di conseguenza, l’ordinamento andrà ai file temporanei (cioè, disco). Di conseguenza, può portare a un rallentamento significativo.

La raccomandazione è di chiudere tutte queste query in modo tempestivo.

Domande?

Non esitare a contattarmi per qualsiasi domanda: [email protected]!