23 extra manieren om Firebird te versnellen
Alexey Kovyazin, IBSurgeon, [email protected], 08-Jan-2019
Vertalingen: Portugees
Waarom “nog 23”?
Sommigen van jullie herinneren zich het artikel « 45 manieren om Firebird te versnellen», dat in mei 2016 werd gepubliceerd. Nu is het tijd om de volgende reeks tips en trucs te publiceren, grotendeels gebaseerd op de ervaring met optimalisatie en onderhoud van Firebird-databases en -servers met een hoog aantal verbindingen (1000+).
1. Stel Energiebeheer in op Hoge prestaties in Windows Server 2016 en 2019
Standaard heeft Windows Server een energieplan ingesteld op “Gebalanceerd”, wat niet geschikt is voor databaseservers. Stel het in op “Hoge prestaties” en win ongeveer +20% prestatie voor CPU-intensieve bewerkingen. Het kan online worden ingesteld, zonder herstart of reboot. De onderstaande afbeelding toont de CPU-grafiek, die het voordeel van het energieplan “Hoge prestaties” demonstreert:

Meer details over onze tests met Windows-energieplannen vindt u hier.
2. Schakel «Interact with desktop» in op Classic voor Windows
Als u Firebird met de Classic-architectuur op Windows gebruikt, schakel dan het vinkje «Allow service to interact with desktop» in. Zonder deze instelling wordt de resource «desktop heap» beperkt door Windows, en Firebird kan niet meer dan 250-300 verbindingen openen (afhankelijk van de metadata van de database en het bijbehorende geheugengebruik) - er zal een Out Of Memory-fout optreden.

3. Let op: Domain Controller
Het probleem is dat Windows met de rol Domain Controller de schrijfcache uitschakelt op de schijf met de Active Directory-database.
Dit beïnvloedt Firebird op verschillende manieren (evenals andere applicaties, natuurlijk), en het vertoont aanzienlijk slechtere prestaties dan op servers zonder Active Directory-rollen.
Houd er rekening mee dat dit probleem van invloed is op populaire Windows-versies zoals Windows Small Business Server 2011, evenals op andere versies met DC.
4. Verhoog de limiet «max open files» op Linux
Als u Linux als databaseserver gebruikt, vergeet dan niet de limieten voor Firebird af te stemmen. Controleer de limieten voor uw Firebird-proces (SuperServer of SuperClassic) met het volgende commando:
cat /proc//limits
en let op de regel met het maximale aantal geopende bestanden.
Firebird kan tot 4 handles per verbinding gebruiken, en als u zoiets heeft als:
Max open files 4096 4096 files
betekent dit dat het totale aantal verbindingen dat door het Firebird-proces wordt bediend, beperkt zal zijn tot ongeveer 1000.
Let op - als u 4 databases op de server heeft, wordt de verbinding voor elke database meegeteld.
Stel meer in - ik raad 65535 aan.
Vergeet niet opnieuw te controleren na het herstarten van het Firebird-proces: is het toegepast of niet.
Voor de Classic-architectuur is het noodzakelijk de limieten voor de gebruiker «firebird» te controleren en te verhogen.
5. Gebruik modern Linux
Ja, ik begrijp dat dit advies triviaal is, maar ik heb vaak een goede prestatieverbetering gezien na de migratie van CentOS 6 naar 7, Ubuntu 12 naar 16 (op dezelfde hardware!), dus nu is het de must-have aanbeveling voor databaseservers met meer dan 250-300 verbindingen. Het moderne Linux is een voorwaarde voor verdere optimalisatiestappen.
Aanbevolen versies van Linux: CentOS 7.x en Ubuntu 16, 18.
6. Reserveer 40% RAM voor bestandscache op Windows
De OS Memory Manager heeft implicaties met betrekking tot de geheugentoewijzing, en standaard vereist Windows 40% van het RAM voor bestandscache.
Helaas toont het gebrekkige hulpmiddel Windows Taakbeheer geheugen dat voor bestandscache wordt gebruikt als «vrij», en sommige beheerders proberen Firebird al dit vrije geheugen te laten verbruiken, dus stellen ze de parameter DefaultDBCachePage in firebird.conf in op zeer hoge waarden, wat meestal tot swapping leidt.
Gebruik altijd het RAMMap-hulpmiddel om het werkelijke geheugengebruik op Windows te zien.
De empirische regel voor Windows Server (toegewijd aan gebruik als Firebird-server) is de volgende: Firebird-geheugen (Working Set) moet minder zijn dan 40% van het totale RAM. Als de totale grootte van working sets voor alle processen meer dan 50% is, kan swapping door Windows worden gestart.
Houd er rekening mee: “reserveren” betekent hier niet alleen “stel niet te veel paginabuffers in Firebird in” maar, ook belangrijk, beperk het geheugengebruik van andere software. Bijvoorbeeld, als u MS Exchange of MSSQL op dezelfde server als Firebird heeft, zorg er dan voor dat u hun geheugenhonger beperkt.
Als u geïnteresseerd bent in details hierover, heb ik de webinar opgenomen die gewijd is aan geheugenbeheer in Firebird:
- Deel 1. https://www.youtube.com/watch?v=ZBmLgbYt4aM
- Deel 2, https://www.youtube.com/watch?v=-1.DF2FnU-A
7. Reserveer 30% van RAM voor bestandscache op Linux
Linux werkt op een andere manier met bestandscache dan Windows, en over het algemeen kan de hoeveelheid RAM die voor bestandscache wordt gebruikt aanzienlijk minder zijn dan op Windows, zonder merkbare verslechtering van de Firebird-prestaties. Om echter hoge prestaties van het systeem met een hoog aantal verbindingen te garanderen, vooral op Classic en SuperClassic, is het een goed idee om 30% van RAM te reserveren voor bestandscache.
8. Gebruik irqbalance op Linux
irqblalnce verbetert vaak de Firebird-prestaties en CPU-belastingverdeling op servers met een hoog aantal cores.
9. Voor virtuele machines - let op Memory Overcommit
Een virtuele machine kan worden geconfigureerd met meer geheugen dan fysiek aanwezig is op de hostmachine - met een functie die bekend staat als Memory Overcommit (de naam kan verschillen op de verschillende virtualisatiesystemen). Dit betekent dat in het geval van een piek in geheugengebruik (op de VM met de databaseserver of op de naburige VM) swapping kan beginnen, wat tot aanzienlijke vertragingen zal leiden. Voor een hoogwaardige VM bedoeld voor een databaseserver, moet al het geheugen statisch zijn.
10. Voor virtuele machines - controleer VM-limieten
Vaak worden VM’s aangemaakt met standaard CPU- en IO-limieten, die zeer laag kunnen zijn, zoals 50 IOPS en 10% CPU. Controleer de instellingen van uw server-VM en verwijder alle limieten - een hoogwaardige databaseserver moet alle mogelijke CPU, bandbreedte en IO hebben.
11. Ruim tijdelijke Firebird-bestanden op
Firebird maakt veel tijdelijke bestanden aan voor verschillende bewerkingen: sorteren, BLOB-verwerking, tracing. Deze bestanden worden opgeslagen op de volgende locaties: op Windows C:\ProgramData\firebird, op Linux / tmp / firebird
Normaal gesproken moeten deze bestanden automatisch worden opgeruimd, maar soms gebeurt dat niet (bijvoorbeeld bij een herstart van de server).
Controleer deze mappen periodiek en ruim oude bestanden op - er kunnen vele GB’s verouderde bestanden fb_NNN zijn, en het opruimen ervan maakt ruimte vrij op de systeemschijf.
12. Vergeet niet bestandscache in te schakelen bij een grote Firebird-cache
Zoals u weet wordt de Firebird-cache (ook wel «page buffers» genoemd) gespecificeerd door de parameter DefaultDBCachePages in firebird.conf/databases.conf, of rechtstreeks in de header van de database.
In Firebird 3 SuperServer kan de grootte van deze cache zeer hoog worden ingesteld, maar het is belangrijk om aan een andere parameter te denken: FileSystemCacheThreshold.
Als FileSystemCacheThreshold kleiner is dan DefaultDBCachePages of page buffers, zal de bestandscache van het besturingssysteem niet worden gebruikt, wat tot prestatieproblemen kan leiden.
In 99% van de gevallen is het beter om bestandscache ingeschakeld te hebben.
Om dit te garanderen, stel de parameters altijd in volgens de volgende regel:
- DefaultDBCachePages = X
- FileSystemCacheThreshold = X+ N, N>1
Er zijn zeldzame gevallen waarin het uitschakelen van bestandscache de prestaties verbetert - als u zo’n voorbeeld heeft, neem dan contact met mij op - [email protected]!
13. Versnel de beveiligingsdatabase
Elke verbinding met de Firebird-database brengt de verbinding met de beveiligingsdatabase tot stand (security3.fdb in het geval van Firebird 3), en voert verschillende lees- en schrijfbewerkingen uit (transactiepagina’s, headerpagina). Als u frequente verbindingen heeft, kan de prestatie van uw beveiligingsdatabase een probleem worden.
Als minimum kunt u het volgende doen:
- Verhoog page buffers voor securityN.fdb (empirisch optimum is 256 buffers)
- Verplaats security3.fdb naar de snelle schijf (het is een standaardfunctie in Firebird 3, in 2.5 vereist het herinstallatie)
Vervolgens kunt u Forced Writes OFF instellen voor de beveiligingsdatabase - de kleine kans op corruptie is in dit geval geen probleem.
De meest radicale manier is om de beveiligingsdatabase alleen-lezen te maken - het elimineert alle schrijfbewerkingen ernaar.
Als u niet vaak gebruikers in de beveiligingsdatabase wijzigt, is het de beste oplossing.
14. Probeer SuperClassic op Firebird 3
In Firebird 3 werd de SuperServer-architectuur sterk gepromoot als de ultieme prestatieoplossing, maar er zijn sommige belastingstypes die betere prestaties vertonen met SuperClassic (maar niet Classic - dat werkt altijd langzamer dan SuperServer/SuperClassic).
Hoe voert u dit experiment op een veilige manier uit? Volg de onderstaande stappen:
Om SuperClassic te proberen
- Stel in firebird.conf in
- ServerMode=SuperClassic
- DefaultDbCachePages=1024
- gfix -buff 0
- Herstart Firebird
Om terug te keren naar SuperServer
- Stel in firebird.conf in
- ServerMode=SuperServer
- DefaultDbCachePages=N # N*page size*databases_count < 25% RAM
- FileSystemCacheThreshold = N+1
- gfix -buff 0
- Herstart Firebird
Schrijf mij alstublieft ([email protected]) over de resultaten van het experiment, ik ben geïnteresseerd om de resultaten te zien.
15. Grote database? Verhoog de paginagrootte
Standaard hebben Firebird-databases de volgende paginagroottes:
- 2.5 - 4096 bytes
- 3.0 - 8192 bytes
De maximale paginagrootte is echter 16K (in 4.0 - 32K).
Voor databases groter dan 100Gb is het in 95% van de gevallen beter om de hoogst beschikbare paginagrootte te hebben, om:
- De diepte van indices te verkleinen. Het wordt aanbevolen indices te hebben met een diepte kleiner dan of gelijk aan 3. Indices met diepte 4 en 5 zullen veel langzamer zijn
- Het gebruik van RAM te verhogen. Firebird-cache wordt gespecificeerd in pagina’s, 1000 pagina’s met 8K paginagrootte zal 8Mb werkelijk geheugen zijn, en met 16K - 16Mb.
- Het aantal systeempagina’s te verkleinen. Het versnelt de toegang tot de records van de grote tabellen (minder sprongen pointer-pointer-datapagina), en helpt bij de voorbereiding van de grote SQL-query’s. Om de paginagrootte van de database te verhogen, moet de database worden geback-upt met het gbak-hulpmiddel en vervolgens worden hersteld met parameter -page ( gbak -c -page 16384).
Houd er rekening mee: als u een database heeft met veel kleine blobs, kan het verhogen van de paginagrootte de fragmentatie verminderen of verhogen, en het is moeilijk te voorspellen of het de prestaties zal verhogen of verlagen.
16. Gebruik de no_reserve-vlag niet
De vlag no_reserve zorgt ervoor dat Firebird geen vrije ruimte (30%) reserveert op datapagina’s voor de mogelijke recordversies, die optreden na UPDATE of DELETE. Deze vlag zorgt ervoor dat de gegevens compacter worden opgeslagen (en de grootte van de database is ook kleiner), maar in het geval van UPDATE/DELETE gaan alle wijzigingen naar de nieuwe datapagina. Als gevolg daarvan zijn in de database met de no_reserve-vlag UPDATE/DELETE-bewerkingen langzamer.
Dus, als uw database niet alleen-lezen is, raad ik aan de no_reserve-vlag te verwijderen.
Hoe te controleren of deze is ingesteld of niet - zie regel Attributes in de uitvoer van
gstat -h database
Hoe uit te schakelen:
gfix -use reserve database
Na dit commando worden de nieuwe datapagina’s aangemaakt met gereserveerde ruimte.
Om echter het volledige effect te bereiken, is het noodzakelijk een database te back-uppen met gbak en vervolgens te herstellen, in dit geval zullen alle datapagina’s gereserveerde ruimte hebben.
Houd er rekening mee: de databasegrootte zal groeien na het verwijderen van de no_reserve -vlag en backup/restore.
17. Stel een hoge initiële grootte in voor de Firebird-locktabel
De locktabel is het mechanisme van Firebird, dat wordt gebruikt om de toegang tot de interne engine-objecten te synchroniseren.
De Firebird-locktabel kan automatisch groeien, maar het vergroten ervan is een langzame bewerking, wat kan leiden tot micro-freezes. De locktabel kan alleen groeien, uitgaande van de initiële grootte (deze wordt ingesteld in firebird.conf).
Om meerdere rondes van het vergroten van de locktabel te voorkomen, is het een goed idee om aan het einde van de werkperiode (dag, week, enz.) de grootte van de locktabel in de gaten te houden en deze vervolgens als initiële grootte in firebird.conf in te stellen.
LockMemSize=99999999
Ter referentie: LockMemSize op systemen met hoge belasting met ~1000 gebruikers is doorgaans minder dan 200Mb.
18. Gebruik fb_lock_print om het aantal verbindingen met de database te tellen
Het verkrijgen van het aantal databaseverbindingen is een veelvoorkomende taak voor databaseontwikkelaars: het kan bijvoorbeeld nodig zijn voor licentiedoeleinden.
Vaak gebruiken ontwikkelaars de query SELECT count(*) FROM MON$ATTACHMENTS om deze waarde te verkrijgen, maar dat is niet de optimale manier: frequente queries op MON$-tabellen kunnen een belasting voor de database vormen, dus gebruik liever het alternatief:
Voer
fb_lock_print -d database_name | alias
uit en controleer de waarde Owners - deze toont het huidige aantal verbindingen met de database.
19. Vermijd onnodige LEFT JOINs
Vaak zie ik queries met een constructie als deze:
T1 LEFT JOIN T2 ON (…) WHERE T2.Field_condition
In wezen sluit de voorwaarde op T2 NULLs uit van de uitvoer van LEFT JOIN T2, dus het is mogelijk om LEFT JOIN te wijzigen in INNER JOIN - dit heeft geen invloed op het resultaat van de query.
INNER JOIN geeft meer vrijheid aan de Firebird-optimizer, en in de moderne versies van Firebird wordt deze veel beter geoptimaliseerd dan LEFT.
Vooral in de volgende gevallen is dit zinvol:
- Geen voorwaarde voor T1 in de WHERE-clausule
- T2 is een kleine tabel
20. Vermijd onnodig tellen van records
Een andere veelvoorkomende fout in complexe databasequeries en stored procedures is het gebruik van select count() alleen om het bestaan van het record te controleren.
De volgende query leest alle records volgens condition1:
(select count(*)…. where condition11) >0
Gebruik in plaats daarvan deze constructie
Exists(select first 1 id where condition1)
Als condition1 meer dan 1 record oplevert, zal de voorgestelde optie veel sneller zijn, omdat deze niet alle records leest, maar stopt na het eerste opgehaalde record.
21. Vermijd onnodige sortering in stored procedures
De ordening van de resultaten van de query binnen de stored procedure moet gerechtvaardigd zijn door de bedrijfslogica.
In het voorbeeld van de onderstaande stored procedure is de ORDER BY-clausule bijvoorbeeld nutteloos vanuit het oogpunt van de bedrijfslogica, maar voegt deze een onnodige sorteerbewerking toe.
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
Controleer uw PSQL-code op vergelijkbare situaties en verwijder nutteloze ORDER BY (evenals distinct en UNION).
22. Houd queries niet zonder noodzaak in de prepared state
Vaak zien we 500-1000 prepared statements in elke verbinding (dit kan worden gecontroleerd met MON$-queries).
De overgrote meerderheid ervan wordt slechts één keer uitgevoerd en zit daarna gewoon in het RAM, waardoor de working set van Firebird groter wordt en MON$-queries worden vertraagd.
De aanbeveling is om SQL-queries alleen in de prepared state te houden als ze bedoeld zijn om vele malen te worden gestart, of als hun prepare-tijd groot is (dit kan het geval zijn bij zeer grote queries met veel joins en toegang tot enorme tabellen).
23. Sluit altijd queries met grote sortering
Totdat een SQL-query met sortering (ORDER BY, GROUP BY, UNION, distinct) is gesloten, houdt Firebird gesorteerde records in het geheugen. De grootte van het geheugen dat voor sortering wordt toegewezen, wordt ingesteld door de parameter TempCacheLimit in firebird.conf; standaard is dit 64Mb.
Zelfs met een verhoogde TempCacheLimit zullen langdurige queries met een groot aantal gesorteerde records uiteindelijk de volledige toegewezen hoeveelheid verbruiken, en als gevolg daarvan zal de sortering naar tijdelijke bestanden (dus schijf) gaan. Dit kan leiden tot aanzienlijke traagheid.
De aanbeveling is om al dergelijke queries tijdig te sluiten.
Vragen?
Neem gerust contact met me op met eventuele vragen: [email protected]!