Hoe zorg je ervoor dat Firebird veel geheugen verbruikt?
Soms krijgen we gevallen waarbij het Firebird-proces veel RAM verbruikt.
Hier zijn 3 hoofdredenen waarom dit gebeurt. Let op - dit zijn GEEN aanbevelingen :) Voer ze niet uit op de productieomgeving!
1. Page buffers te hoog instellen
Bijvoorbeeld, voor SuperServer in firebird.conf
DefaultDbCachePages = 500000M # pages
Herstart Firebird en probeer te verbinden - het resultaat zal een foutmelding zijn “Unable to allocate memory from the operating system”:
isql -user SYSDBA -pass masterkey localhost:e:\temp\blob30.fdb Statement failed, SQLSTATE = HY001 unable to allocate memory from operating system -IProvider::attachDatabase failed when loading mapping cache Use CONNECT or CREATE DATABASE to specify a database SQL>
Hetzelfde resultaat zal optreden bij veel verbindingen met SuperClassic of Classic met een relatief hoog aantal page buffers, volgens de formule:
Page Buffers X Aantal Verbindingen X Page Size.
2. De Firebird-procesgrootte kan groeien door massale bewerkingen met tijdelijke BLOBs
Probeer het volgende script uit te voeren (niet op de productieomgeving):
create generator g1; set generator g1 to 0; execute block as declare variable blb BLOB; declare variable icnt integer; begin icnt=0; while (icnt <100000000) DO begin select cast('1234567890qwertyuiopasdfghjklzxcvbnm' as BLOB) from rdb$database into :blb; select gen_id(g1,1) from rdb$database into :icnt; end end;
Of een andere variant van het idee
create or alter procedure BLOB_LOOP returns ( ATEXT blob sub_type text ) as begin while (true) do begin atext = '123'; suspend; end end
En de volgende query zal al het geheugen opeten (voer het niet uit op de productieomgeving!)
select count(*) from blob_loop
3. Voor Classic en SuperClassic is het mogelijk om een groot aantal page buffers op te geven in de verbindingsreeks van isql.exe, en dit zal voor deze verbinding worden toegewezen
Als Page Buffers niet expliciet is ingesteld in de header-pagina (d.w.z. gelijk aan 0)
`C:\FB\30Cs>echo set list on; set stat on; select mon$page_buffers from mon$database; | isql -c 98765 /:e30 -user foo -pas bar Database: /:e30, User: FOO SQL> MON$PAGE_BUFFERS 98765 Current memory = 869314176 Delta memory = 75760 Max memory = 869334512 Elapsed time= 0.001 sec Buffers = 98765 Reads = 3 Writes = 0 Fetches = 42 SQL>
set bail on; set term ^; execute block as declare n int = 10; declare c int; declare my_password varchar(20) = ‘bar’; begin while (n>0) do begin execute statement ‘select 1 from rdb$database’ on external ’localhost:’ || rdb$get_context(‘SYSTEM’, ‘DB_NAME’) as user current_user password my_password role lpad(’’, 20, replace(uuid_to_char(gen_uuid()),’-’,’’)) into c; n = n - 1;`
end
end
^
set term ;^
set list on;
select count(distinct(t.mon$attachment_id)) as num_of_attachments, sum(t.mon$memory_used) as sum_memo_used, sum(t.mon$memory_allocated) as sum_memo_allocated
from (
select
a.mon$attachment_id
,m.*
from mon$attachments a
join mon$memory_usage m on a.mon$stat_id = m.mon$stat_id
where mon$user = current_user
) t;
=======