23 dodatnih načina da ubrzate Firebird
Алексеј Ковазин, IBSurgeon, [email protected], 08-јан-2019
Преводи: португалски
Зашто „још 23“?
Неки од вас се сећају чланка « 45 начина да убрзате Firebird», који је објављен у мају 2016. Сада је време да објавимо следећу серију савета и трикова, углавном заснованих на искуству оптимизације и одржавања Firebird база података и сервера са великим бројем конекција (1000+).
1. Подесите опције напајања на високе перформансе у Windows Server 2016 и 2019
Подразумевано, Windows Server има план напајања подешен на „Balanced“, који није погодан за сервере база података. Подесите га на „High Performance“ и добићете приближно +20% перформанси за операције интензивне на CPU. Може се подесити онлајн, без рестарта или поновног покретања. Слика испод приказује график CPU-а, који демонстрира предност плана напајања „High-performance“:

Више детаља о нашим тестовима са Windows плановима напајања можете пронаћи овде.
2. Омогућите „Interact with desktop“ на Classic за Windows
Ако користите Firebird са Classic архитектуром на Windows-у, омогућите поље за потврду „Allow service to interact with desktop“. Без овог подешавања, ресурс „desktop heap“ је ограничен од стране Windows-а, и Firebird не може да отвори више од 250-300 конекција (зависи од метаподатака базе података и повезане потрошње меморије) - доћи ће до Out Of Memory грешке.

3. Пажња: Domain Controller
Проблем је што Windows са улогом Domain Controller онемогућава кеш за писање на диску са Active Directory базом података.
То утиче на Firebird на различите начине (као и на друге апликације, наравно), и показује знатно лошије перформансе него на серверима без Active Directory улога.
Имајте на уму да овај проблем утиче на тако популарну Windows верзију као што је Windows Small Business Server 2011, као и на друге верзије са DC.
4. Повећајте ограничење „max open files“ на Linux-у
Ако користите Linux као сервер базе података, не заборавите да подесите ограничења за Firebird. Проверите ограничења за ваш Firebird процес (SuperServer или SuperClassic) следећом командом:
cat /proc//limits
и обратите пажњу на линију са максималним бројем отворених фајлова.
Firebird може да користи до 4 handle-а по конекцији, и ако имате нешто попут овога:
Max open files 4096 4096 files
то значи да ће укупан број конекција које опслужује Firebird процес бити ограничен на око 1000.
Имајте на уму - ако имате 4 базе података на серверу, конекција за сваку базу се рачуна.
Подесите више - препоручујем 65535.
Не заборавите да поново проверите након поновног покретања Firebird процеса: да ли је примењено или не.
За Classic архитектуру, потребно је проверити и повећати ограничења за корисника „firebird“.
5. Користите модеран Linux
Да, разумем да је овај савет тривијалан, али сам много пута видео добро побољшање перформанси након миграције са CentOS 6 на 7, Ubuntu 12 на 16 (на истом хардверу!), тако да је сада то обавезна препорука за сервере база података са више од 250-300 конекција. Модеран Linux је предуслов пре даљих корака оптимизације.
Препоручене верзије Linux-а: CentOS 7.x и Ubuntu 16, 18.
6. Резервишите 40% RAM-а за кеш фајлова на Windows-у
OS Memory Manager има импликације у вези са доделом меморије, и, подразумевано, Windows захтева 40% RAM-а за кеш фајлова.
Нажалост, лош алат Windows Task Manager приказује меморију која се користи за кеш фајлова као „слободну“, и неки администратори покушавају да натерају Firebird да троши сву ту слободну меморију, па подешавају параметар DefaultDBCachePage у firebird.conf на веома високе вредности, што обично доводи до swap-овања.
Увек користите алат RAMMap да видите стварну потрошњу меморије на Windows-у.
Емпиријско правило за Windows Server (намењен за коришћење као Firebird сервер) је следеће: Firebird меморија (Working Set) треба да буде мања од 40% укупног RAM-а. Ако је укупна величина working set-ова за све процесе већа од 50%, Windows може покренути swap.
Имајте на уму: „резервишите“ овде не значи само „не подешавајте превише page buffer-а у Firebird-у“ већ, такође важно, ограничите потрошњу меморије другог софтвера. На пример, ако имате MS Exchange или MSSQL на истом серверу са Firebird-ом, обавезно ограничите њихове апетите за меморијом.
Ако вас занимају детаљи, снимио сам вебинар посвећен управљању меморијом у Firebird-у:
- Део 1. https://www.youtube.com/watch?v=ZBmLgbYt4aM
- Део 2, https://www.youtube.com/watch?v=-1.DF2FnU-A
7. Резервишите 30% RAM-а за кеш фајлова на Linux-у
Linux ради са кешом фајлова на другачији начин него Windows, и, уопштено, количина RAM-а која се користи за кеш фајлова може бити знатно мања него на Windows-у, без приметног погоршања перформанси Firebird-а. Међутим, да бисте гарантовали високе перформансе система са великим бројем конекција, посебно на Classic и SuperClassic, добра идеја је резервисати 30% RAM-а за кеш фајлова.
8. Користите irqbalance на Linux-у
irqblalnce често побољшава перформансе Firebird-а и балансирање оптерећења CPU-а на серверима са великим бројем језгара.
9. За виртуелне машине - пазите на Memory Overcommit
Виртуелна машина може бити конфигурисана да има више меморије него што физички постоји на хост машини - са функцијом познатом као Memory Overcommit (назив може бити другачији на различитим системима за виртуелизацију). То значи да у случају врхунца потрошње меморије (на VM-у са сервером базе података или на суседном VM-у) може почети swap, што ће довести до знатних кашњења. За високоперформансни VM намењен серверу базе података, сва меморија треба да буде статична.
10. За виртуелне машине - проверите ограничења VM-а
Често се VM-ови креирају са подразумеваним ограничењима CPU-а и IO-а, која могу бити веома ниска, као 50 IOPS и 10% CPU. Проверите подешавања вашег серверског VM-а и уклоните сва ограничења - високоперформансни сервер базе података треба да има сав могући CPU, пропусни опсег и IO.
11. Очистите привремене фајлове Firebird-а
Firebird креира много привремених фајлова за разне операције: сортирање, обраду BLOB-ова, трасирање. Ови фајлови се чувају на следећим локацијама: на Windows-у C:\ProgramData\firebird, на Linux-у / tmp / firebird
Нормално, ови фајлови би требало да се аутоматски чисте, међутим, понекад се то не дешава (на пример, у случају поновног покретања сервера).
Проверавајте ове фасцикле периодично и чистите старе фајлове - може бити много GB застарелих фајлова fb_NNN, а њихово чишћење ће ослободити простор на системском диску.
12. Не заборавите да омогућите кеш фајлова са великим Firebird кешом
Као што знате, Firebird кеш (који се још назива „page buffers“) се одређује параметром DefaultDBCachePages у firebird.conf/databases.conf, или директно у заглављу базе података.
У Firebird 3 SuperServer величина овог кеша може бити подешена веома високо, али је важно запамтити још један параметар: FileSystemCacheThreshold.
Ако је FileSystemCacheThreshold мањи од DefaultDBCachePages или page buffer-а, кеш фајлова оперативног система неће се користити, што може довести до проблема са перформансама.
У 99% случајева, боље је имати омогућен кеш фајлова.
Да бисте то осигурали, увек подешавајте параметре према следећем правилу:
- DefaultDBCachePages = X
- FileSystemCacheThreshold = X+ N, N>1
Постоје ретки случајеви када онемогућавање кеша фајлова побољшава перформансе - ако имате такав пример, контактирајте ме - [email protected]!
13. Убрзајте безбедносну базу података
Свака конекција на Firebird базу података успоставља конекцију на безбедносну базу података (security3.fdb у случају Firebird 3), и извршава неколико читања и писања (странице трансакција, заглавље странице). Ако имате честе конекције, перформансе ваше безбедносне базе података могу постати проблем.
Kao minimum, možete uraditi sledeće:
- Povećajte page buffers za securityN.fdb (empirijski optimum je 256 bafera)
- Premestite security3.fdb na brzi disk (to je standardna funkcija u Firebird 3, u 2.5 će zahtevati ponovnu instalaciju)
Zatim, možete isključiti Forced Writes za security bazu podataka - mala šansa za korupciju u ovom slučaju nije problem.
Najradikalniji način je da security bazu podataka učinite samo za čitanje - to će eliminisati sve upise u nju.
Ako ne menjate često korisnike u security bazi podataka, to je najbolje rešenje.
14. Isprobajte SuperClassic na Firebird 3
U Firebird 3 arhitektura SuperServer je bila snažno reklamirana kao vrhunsko rešenje za performanse, ali postoje neki tipovi opterećenja koji pokazuju bolje performanse sa SuperClassic (ali ne Classic - on uvek radi sporije od SuperServer/SuperClassic).
Kako sprovesti ovaj eksperiment na bezbedan način? Sledite korake u nastavku:
Da isprobate SuperClassic
- Podesite u firebird.conf
- ServerMode=SuperClassic
- DefaultDbCachePages=1024
- gfix -buff 0
- Restartujte Firebird
Da se vratite na SuperServer
- Podesite u firebird.conf
- ServerMode=SuperServer
- DefaultDbCachePages=N # N*page size*databases_count < 25% RAM
- FileSystemCacheThreshold = N+1
- gfix -buff 0
- Restartujte Firebird
Molim vas pišite mi ([email protected]) o rezultatima eksperimenta, zainteresovan sam da vidim rezultate.
15. Velika baza podataka? Povećajte veličinu stranice
Podrazumevano, Firebird baze podataka imaju sledeće veličine stranica:
- 2.5 - 4096 bajtova
- 3.0 - 8192 bajta
Međutim, maksimalna veličina stranice je 16K (u 4.0 - 32K).
Za baze podataka veće od 100Gb u 95% slučajeva bolje je imati najveću dostupnu veličinu stranice, kako bi se:
- Smanjila dubina indeksa. Preporučuje se imati indekse sa dubinom manjom ili jednakom 3. Indeksi sa dubinom 4 i 5 biće mnogo sporiji
- Povećala iskorišćenost RAM-a. Firebird keš se specificira u stranicama, 1000 stranica sa veličinom stranice 8K biće 8Mb stvarne memorije, a sa 16K - 16Mb.
- Smanjio broj sistemskih stranica. To će ubrzati pristup zapisima velikih tabela (manje skokova pointer-pointer-data page), i pomaže pri pripremi velikih SQL upita. Da biste povećali veličinu stranice baze podataka, baza podataka treba da bude backup-ovana pomoću gbak alata i zatim restaurirana sa parametrom -page ( gbak -c -page 16384).
Napomena: ako imate bazu podataka sa mnogo malih blob-ova, povećanje veličine stranice može ili smanjiti fragmentaciju ili povećati fragmentaciju, i teško je predvideti da li će povećati ili smanjiti performanse.
16. Ne koristite no_reserve flag
Flag no_reserve čini da Firebird ne rezerviše slobodan prostor (30%) na data stranicama za moguće verzije zapisa, koje nastaju nakon UPDATE ili DELETE. Ovaj flag omogućava da se podaci skladište na kompaktniji način (i veličina baze podataka je takođe manja), ali u slučaju UPDATE/DELETE sve izmene idu na novu data stranicu. Kao rezultat, u bazi podataka sa no_reserve flag-om UPDATE/DELETE operacije su sporije.
Dakle, ako vaša baza podataka nije samo za čitanje, preporučujem uklanjanje no_reserve flag-a.
Kako proveriti da li je postavljen ili ne - pogledajte liniju Attributes u izlazu
gstat -h database
Kako onemogućiti:
gfix -use reserve database
Nakon ove komande, nove data stranice će biti kreirane sa rezervisanim prostorom.
Međutim, da bi se postigao pun efekat, neophodno je backup-ovati bazu podataka pomoću gbak i zatim restaurirati, u tom slučaju, sve data stranice će biti sa rezervisanim prostorom.
Napomena: veličina baze podataka će porasti nakon uklanjanja no_reserve flag-a i backup/restore.
17. Postavite visoku početnu veličinu za Firebird lock tabelu
Lock tabela je mehanizam Firebird-a, koji se koristi za sinhronizaciju pristupa internim objektima engine-a.
Firebird lock tabela može automatski rasti, ali njeno povećanje je spora operacija, koja može dovesti do mikro-zamrzavanja. Lock tabela može samo rasti, počevši od početne veličine (koja se postavlja u firebird.conf).
Da biste sprečili višestruke runde povećanja lock tabele, dobra ideja biće da pratite veličinu lock tabele na kraju radnog perioda (dan, nedelja, itd), i zatim je postavite kao početnu veličinu u firebird.conf.
LockMemSize=99999999
Za vašu referencu: LockMemSize na sistemima sa visokim opterećenjem sa ~1000 korisnika je obično ispod 200Mb.
18. Koristite fb_lock_print za brojanje broja konekcija na bazu podataka
Dobijanje broja konekcija na bazu podataka je čest zadatak za developere baza podataka: može biti neophodno u svrhe licenciranja, na primer.
Često developeri koriste upit SELECT count(*) FROM MON$ATTACHMENTS da dobiju ovu vrednost, ali to nije optimalan način: česti upiti na MON$ tabele mogu biti opterećenje za bazu podataka, pa je bolje koristiti alternativu:
Pokrenite
fb_lock_print -d database_name | alias
i proverite Owners vrednost - ona će pokazati trenutni broj konekcija na bazu podataka.
19. Izbegavajte nepotrebne LEFT JOIN-ove
Često vidim upite sa konstrukcijom kao što je ova:
T1 LEFT JOIN T2 ON (…) WHERE T2.Field_condition
Suštinski, uslov na T2 isključuje NULL-ove iz izlaza LEFT JOIN T2, pa je moguće promeniti LEFT JOIN u INNER JOIN - to neće uticati na rezultat upita.
INNER JOIN daje više slobode Firebird optimizer-u, i u modernim verzijama Firebird-a, mnogo je bolje optimizovan od LEFT.
Posebno ima smisla u sledećim slučajevima:
- Nema uslova za T1 u WHERE klauzuli
- T2 je mala tabela
20. Izbegavajte nepotrebno brojanje zapisa
Još jedna česta greška u složenim upitima baze podataka i stored procedurama je korišćenje select count() samo da bi se proverilo postojanje zapisa.
Sledeći upit će pročitati sve zapise prema condition1:
(select count(*)…. where condition11) >0
Bolje koristite ovu konstrukciju umesto toga
Exists(select first 1 id where condition1)
Ako condition1 vraća više od 1 zapisa, predložena opcija će biti mnogo brža, jer ne čita sve zapise, zaustavlja se nakon prvog preuzetog zapisa.
21. Izbegavajte nepotrebno sortiranje u stored procedurama
Redosled rezultata upita unutar stored procedure treba da bude opravdan poslovnom logikom.
Na primer, u primeru stored procedure ispod, ORDER BY klauzula je beskorisna sa stanovišta poslovne logike, ali dodaje nepotrebnu operaciju sortiranja.
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
Proverite vaš PSQL kod za slične situacije i uklonite beskorisni ORDER BY (kao i distinct i UNION).
22. Ne držite upite u pripremljenom stanju bez potrebe
Često vidimo 500-1000 pripremljenih statement-a u svakoj konekciji (to se može proveriti MON$ upitima).
Ogromna većina njih se izvršava samo jednom, a zatim samo stoje u RAM-u, čineći Firebird radni set većim, i usporavaju MON$ upite.
Preporuka je da držite SQL upite u pripremljenom stanju samo ako su namenjeni da se pokreću mnogo puta, ili ako je njihovo vreme pripreme veliko (može biti tako za veoma velike upite sa mnogo join-ova i pristupom ogromnim tabelama).
23. Uvek zatvorite upite sa velikim sortiranjem
Dok SQL upit sa sortiranjem (ORDER BY, GROUP BY, UNION, distinct) nije zatvoren, Firebird zadržava sortirane zapise u memoriji. Veličina memorije dodeljene za sortiranje se postavlja parametrom TempCacheLimit u firebird.conf, podrazumevano je 64Mb.
Čak i sa povećanim TempCacheLimit, dugotrajni upiti sa velikim brojem sortiranih zapisa će na kraju potrošiti svu dodeljenu količinu, i kao rezultat, sortiranje će preći na privremene fajlove (tj. disk). Kao rezultat, to može dovesti do značajnog usporavanja.
Preporuka je da blagovremeno zatvorite sve takve upite.
Pitanja?
Slobodno me kontaktirajte sa bilo kakvim pitanjima: [email protected]!