Cette page a été traduite automatiquement. Lisez l'original en anglais. English

Bibliothèque IBSurgeon

Comment faire consommer beaucoup de mémoire à Firebird ?

Parfois, nous avons des cas où le processus Firebird consomme beaucoup de RAM.

Voici 3 raisons principales pour lesquelles cela se produit. Veuillez noter - ce ne sont PAS des recommandations :) Ne les exécutez pas en production !

1. Définir des page buffers trop élevés

Par exemple, pour SuperServer dans firebird.conf

DefaultDbCachePages = 500000M # pages

Redémarrez Firebird et essayez de vous connecter - le résultat sera un message d’erreur “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>

Le même résultat se produira en cas de nombreuses connexions avec SuperClassic ou Classic avec un nombre relativement élevé de page buffers, selon la formule :

Page Buffers X Nombre de connexions X Taille de page.

2. La taille du processus Firebird peut augmenter en raison d’opérations massives avec des BLOBs temporaires

Essayez d’exécuter le script suivant (pas en production) :

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;

Ou, une autre variante de l’idée

create or alter procedure BLOB_LOOP returns ( ATEXT blob sub_type text ) as begin while (true) do begin atext = '123'; suspend; end end

Et la requête suivante consommera toute la mémoire (ne l’exécutez pas en production !)

select count(*) from blob_loop

3. Pour Classic et SuperClassic, il est possible de spécifier un grand nombre de page buffers dans la chaîne de connexion d’isql.exe, et ils seront alloués pour cette connexion

Si Page Buffers n’est pas défini explicitement dans la page d’en-tête (c’est-à-dire égal à 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;

=======