Oznámení
po aktualizaci na 2.0 – PHP Fatal error: Allowed memory size of 53477376 bytes exhausted
před 7 lety
- daliborcaja
- Člen | 57
Po aktualizaci dibi na verzi 2.0 se zvýšila paněťová náročnost
aplikace.
Konkrétně jsem to poznal na některých scriptech které mi provádí stovky
tisíc insertů v cyklu – tyto mi končí na
PHP Fatal error: Allowed memory size of 53477376 bytes exhausted
.
Script se vždy zastavi uvnitr funkce DibiTranslator::translate ne vždy na
stejném řádku. Když se podívám na proces apache přes top tak využití
paměni v průběhu běhu scriptu stoupá, u staré verze dibi ne.
před 7 lety
- Milo
- Nette Core | 1119
Máš zapnutý/vypnutý profiler?
Chtělo by to kousek kódu a info o typu databáze aby se to dalo reprodukovat.
před 7 lety
- daliborcaja
- Člen | 57
profiler vypnuty
datábaze mysql
no a insert napěíklad takto:
<?php
$values = array(
'col1' => array('%s', 'bsba4a16gf'),
'col2' => array('%i', '45'),
'col3' => array('%f', '416.00')
);
dibi::getConnection()->query('insert into ', 'table', ' %v ', $values, ' on duplicate key update %a', $values);
?>
Tento insert je uvnitř cyklu ktrerý se opakuje třeba milionkrát (jedna se o import z CSV a soubory mívají do milionu řádků).
před 7 lety
- Milo
- Nette Core | 1119
Špatně se to hledá. Zdá se, že paměť mizí právě v DibiTranslator. Mohl bys zkusit sestavovat SQL dotazy ručně? Tedy ručně escapovat:
for (......) {
$sql = 'INSERT INTO table (col1, col2, col3) VALUES (' . mysql_real_escape_string($val1) . ', ' . mysql_real_escape_string($val2) . ', atd ...)';
dibi::getConnection()->nativeQuery($sql);
}
před 7 lety
- daliborcaja
- Člen | 57
Milo napsal(a):
Mohl bys zkusit sestavovat SQL dotazy ručně?
To mě taky napadlo, ale je to celkem velký zásah do kódu (nebudu tady
vysvětlovat proč – z mojeho příkladu to není zřejmé a je to OT).
Takže jedině to vyzkoušet někde bokem na testovacím kódu – zkusím až
budu mít více času (koncem týdne).
Ale osobně si myslím že dibi si při těch insertech něco ukládá do
ňáké proměnné a pak ji nesmaze a porad se to hromadi.
Podle mých velice přibližných výpočtů každý insert udělá v RAM 5kB,
což např. u 10000 radku udělá 50MB v RAM. U staré verze dibi není při
stejném dotazu patrný žádný nárust konzumace paměti.
Já jsem zatím downgradoval verzi, takže mi můj kód běží, ale dle mého
názoru by to chtělo v té nové verzi opravit ať to funguje tak dobře jako
v té staré.
před 7 lety
- Milo
- Nette Core | 1119
Zkoušel jsem to na 1000 insertech, někde to mizí, ale neměl jsem čas to pořádně odkrokovat. Je fakt, že co INSERT to 6.8kB. Pak ale zasáhne garbage collector a něco se vyčistí, ne však všechno.
Napadjí mě ještě dvě velké změny, které se ve verzi 2.0 udály.
Zkus v DibiResult::__construct()
zakomentovat automatickou
detekci typů $this->detectTypes();
a hned po připojení
k databázi dibi::getConnection()->onEvent = NULL;
před 7 lety
- daliborcaja
- Člen | 57
Dostal jsem se k tomu až teď.
Milo napsal(a):
Zkus vDibiResult::__construct()
zakomentovat automatickou detekci typů$this->detectTypes();
Tak tohle akorát podle mého o něco zrychlilo program, ale problém stále trvá.
a hned po připojení k databázi
dibi::getConnection()->onEvent = NULL;
U toho jsem nezpozoroval žádnou změnu.
před 7 lety
- daliborcaja
- Člen | 57
Tak jsem ještě provedl nějaké testy a došel jsem k poznatku že paměť se vytěžuje jen když je u hodnot v poli definovaný jejich typ. Viz. příklad – při použití prvního pole problém nastává u druhého ne.
<?php
$values = array(
'col1' => array('%s', 'bsba4a16gf'),
'col2' => array('%i', '45'),
'col3' => array('%f', '416.00')
);
$values = array(
'col1' => 'bsba4a16gf',
'col2' => '45',
'col3' => '416.00'
);
dibi::getConnection()->insert('table', $values)->execute();
?>
před 7 lety
- David Grudl
- Nette Core | 6806
Jakou máš verzi PHP a co vrací funkce gc_enabled()?
před 7 lety
- daliborcaja
- Člen | 57
David Grudl napsal(a):
Jakou máš verzi PHP a co vrací funkce gc_enabled()?
PHP Version 5.2.6–1+lenny16
a gc_enabled() pochopitelně neexistuje protože je dostupná až od
php 5.3
před 7 lety
- jannemec
- Člen | 62
jj, mám podobný problém – při mnoha insertech přeteče paměť … bohužel při datové pumpě se těm insertům nevyhnu. PHP 5.2.17
před 7 lety
- daliborcaja
- Člen | 57
Ještě jsem to nestih otestovat na php 5.3, ale asi to udelam at vime jestli to dela i tam.
před 7 lety
- jannemec
- Člen | 62
daliborcaja napsal(a):
Ještě jsem to nestih otestovat na php 5.3, ale asi to udelam at vime jestli to dela i tam.
Vyzkoušel jsem, dělá to i tam … hádám, že při parsování (resp. vytváření) SQL dotazu se vytváří objekty stromové struktury s obousměrnou vazbou – garbage collector je následně nedokáže odstranit.
před 7 lety
- koblihcz
- Backer | 1
Taky pumpuju data a mam ten problem, PHP Version 5.3, docela to zlobi, moc pameti, server swapuje a jede to pomalu. Zatim jsem vyresil tim, ze jsem se vratil k dibi 1.5, nejede mi profiler v debugbaru ale jinak podstatne sviznejsi.