powered by simpleCommunicator - 2.0.44     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / PDO Firebird bugs
25 сообщений из 222, страница 6 из 9
PDO Firebird bugs
    #39650995
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел ИшенинЕсли вдаваться в логику, то statement при смерти должен удалять буферы

Не должен. Блобы могут читаться отдельно без всякого статемента. Их кэш может быть
привязан к транзакции или коннекту. В твоём коде не освобождается ни то ни другое.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651032
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

поскольку PDO не умеет читать идентификаторы BLOB, а всегда читает сразу его содержимое (хотя по уму могли бы и поток для этого организовать), то в самом драйвере они должны освобождать внутренние структуры блоба сразу после фетча.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651036
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а не вру, есть возможность читать BLOB как поток, но через опу
http://php.net/manual/ru/pdo.lobs.php
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651093
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел ИшенинДегтярев Евгенийа что с ibase_?
извиняюсь, в пред сообщении написал ibx
Может ли это помочь проблеме ? И если да, то как?
как вариант, да, там может не быть этой проблемы
когда сталкивался со связкой php+fb использовал функции ibase_xxx, pdo_firebird обходил стороной, т.к. с ним периодически всплывали какие то траблы

за ответом как, сюда - http://php.net/manual/ru/book.ibase.php
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651104
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел ИшенинПри анализе кода pdo_firebird вот первое за что цепляется глаз:
Код: plaintext
1.
*ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1);



Зачем там erealloc? Разве где-то память выделяется ранее? И если нет, то всегда ли там null?

Под все остальные типы используется следующая конструкция:
Код: plaintext
1.
*ptr = FETCH_BUF(S->fetch_buf[colno], char, *len, NULL);



дело в том что у остальных типов длина фиксирована, поэтому достаточно выделить память один раз. А для BLOB который сразу преобразуется в текст приходится переаллокировать буфер при каждом фетче.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651204
Павел Ишенин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovПавел ИшенинЕсли вдаваться в логику, то statement при смерти должен удалять буферы
Не должен. Блобы могут читаться отдельно без всякого статемента. Их кэш может быть
привязан к транзакции или коннекту. В твоём коде не освобождается ни то ни другое.


Имелся ввиду вот этот код pdo_firebird :

Код: plaintext
1.
2.
3.
4.
5.
6.
	/* clean up the fetch buffers if they have been used */
	for (i = 0; i < S->out_sqlda.sqld; ++i) {
		if (S->fetch_buf[i]) {
			efree(S->fetch_buf[i]);
		}
	}
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651205
Павел Ишенин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгенийкак вариант, да, там может не быть этой проблемы
когда сталкивался со связкой php+fb использовал функции ibase_xxx, pdo_firebird обходил стороной, т.к. с ним периодически всплывали какие то траблы

Если прочитать моё начальное сообщение, то видно что я пишу про работу с Firebird в библиотеке Yii. Там используется PDO. Какой смысл проверять не PDO, если мне надо разобраться с проблемой именно в нём?
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651215
Павел Ишенин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисдело в том что у остальных типов длина фиксирована, поэтому достаточно выделить память один раз. А для BLOB который сразу преобразуется в текст приходится переаллокировать буфер при каждом фетче.

Спасибо, мне что-то в голову это не пришло. Тогда всё вроде верно написано. Ну может вместо realloc было бы выгодней сделать free + malloc если realloc ведет к фрагментации памяти. Тем не менее, это не должно порождать утечку.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39651217
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел ИшенинДегтярев Евгенийкак вариант, да, там может не быть этой проблемы
когда сталкивался со связкой php+fb использовал функции ibase_xxx, pdo_firebird обходил стороной, т.к. с ним периодически всплывали какие то траблы

Если прочитать моё начальное сообщение, то видно что я пишу про работу с Firebird в библиотеке Yii. Там используется PDO. Какой смысл проверять не PDO, если мне надо разобраться с проблемой именно в нём?
в том чтобы проверить, локализовать и зарепортить все возможные проблемы
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39655533
Dorin Marcoci
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можете протестить тот же код на таблицы/полей без блобов и проверить память или скажем на Postgres блобах?
Глянул еще раз на firebird_fetch_blob( вроди ничего криминального не нашел.
К выходу идет ptr и len который потом освобождается в базовой PDO классе.
Обычно пхп девы тестят все изминения Valgrind-ом и другими тулами, чтобы минимизировать утечки.
Если все же уверен что утечка есть, то создай баг репорт с юнит тест кэйсом наподобие: https://github.com/php/php-src/tree/8582e53430f12ce36f621d034a40d10ea01061fc/ext/pdo_firebird/tests
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39655577
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dorin Marcoci,

оно легко воспроизводится

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
<?php

$sql = '
SELECT
    RDB$PROCEDURE_NAME AS NAME,
    RDB$PROCEDURE_SOURCE AS SRC
--    CAST(SUBSTRING(RDB$PROCEDURE_SOURCE FROM 1 FOR 8191) AS VARCHAR(8191)) AS SRC
FROM
    RDB$PROCEDURES   
';

try {
    $dbh = new \PDO('firebird:dbname=localhost:test', 'SYSDBA', 'masterkey');
    $dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $dbh->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_NATURAL);
    //$dbh->setAttribute(\PDO::ATTR_AUTOCOMMIT, false);

    echo "First used: " . memory_get_usage(true) . "<br>";
 
  
    for ($i = 0; $i < 20; $i++) {
	//$dbh->beginTransaction();
        $sth = $dbh->prepare($sql);
        $sth->execute();          
        $rows = $sth->fetchAll();
	unset($rows);
        //$sth->closeCursor();
	unset($sth);
	//$dbh->commit();
        echo "$i itteration used: " . memory_get_usage(true) . "<br>";
    }
    unset($dbh);
    echo "Last used: " . memory_get_usage(true) . "<br>";
} catch (\Exception $e) {
    echo $e->getMessage();
}



авторFirst used: 2097152
0 itteration used: 4194304
1 itteration used: 4194304
2 itteration used: 6291456
3 itteration used: 6291456
4 itteration used: 8388608
5 itteration used: 8388608
6 itteration used: 8388608
7 itteration used: 10485760
8 itteration used: 12582912
9 itteration used: 12582912
10 itteration used: 12582912
11 itteration used: 14680064
12 itteration used: 16777216
13 itteration used: 16777216
14 itteration used: 16777216
15 itteration used: 18874368
16 itteration used: 18874368
17 itteration used: 20971520
18 itteration used: 23068672
19 itteration used: 23068672
Last used: 23068672


в базе данных ~200 процедур. При замене BLOB на строку утечек нет. Интересно что при повторном запуске скрипта память постепенно стабилизируется. Наверное менеджер памяти там такой хитрый.

И ещё вот здесь
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,  /* {{{ */
	zend_ulong *len, int *caller_frees)
{
	pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
	XSQLVAR const *var = &S->out_sqlda.sqlvar[colno]; // тадам!!!

	if (*var->sqlind == -1) {
...



нет проверки на допустимость номера столбца. В результате при вызове PDOStatement::fetchColumn с номером большим чем количество столбцов имеем segfault с падением web сервера. Надо бы ошибку бросать
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39655581
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dorin MarcociГлянул еще раз на firebird_fetch_blob( вроди ничего криминального не нашел.
К выходу идет ptr и len который потом освобождается в базовой PDO классе.А сам блоб - закрывается ?

Симонов Денисоно легко воспроизводитсяТут автокоммит вкл ?
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39655585
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

я пробовал его отключать (по умолчанию включен). Разницы никакой.
Кстати разве после закрытия блоб всё ещё будет потреблять ресурсы на клиенте, даже если транзакция не завершена?
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39655604
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисКстати разве после закрытия блоб всё ещё будет потреблять ресурсы на клиенте, даже если транзакция не завершена?После закрытия - конечно не будет.
Вопрос в том - закрыты ли они.
Однако, коммит (роллбек) должен освобождать клиентские ресурсы, связанные с блобами.
Отсюда был вопрос об автокоммите.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39657762
Павел Ишенин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladА сам блоб - закрывается ?

Да, после чтения блоб закрывается .
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39657774
Павел Ишенин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dorin Marcoci,

Если есть возможность поотлаживать код pdo-firebird, то в какой момент вызывается firebird_stmt_dtor? И что если добавить вывод потребления памяти до и после erealloc? Я не знаю как работает этот erealloc, но традиционно перевыделение вызывает фрагментацию и медленнее освобождения с повторным выделением поскольку менеджер должен, помимо прочего, скопировать содержимое старого блока памяти в новый (чего, как я понимаю, в данном случае не требуется).
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39657886
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел Ишенин,

там КМК это можно оптимизировать. Например выделять для начала 32K памяти, если блоб больше увеличивать, т.е. перевыделять память только если для БЛОБа её требуется больше.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39661573
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел Ишенин,

ура!!! Нашёл утечку. Не зря тебе подозрительным вот этот кусок показался

Павел ИшенинПри анализе кода pdo_firebird вот первое за что цепляется глаз:
Код: plaintext
1.
*ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1);




только дело не в erealloc, а в том память перевыделяют для для ptr, в котором вообще чужой буфер может быть из столбца к которому обращались до BLOBa (в моём тесте из NAME). Вот правильный код

Код: plaintext
1.
*ptr = S->fetch_buf[colno] = erealloc(S->fetch_buf[colno], *len+1);



тест
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
try {
    $dbh = new \PDO('firebird:dbname=localhost:horses', 'SYSDBA', 'masterkey');
    $dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $dbh->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_NATURAL);

$sql = '
SELECT
    RDB$PROCEDURE_NAME AS NAME,
    RDB$PROCEDURE_SOURCE AS SRC
FROM
    RDB$PROCEDURES   
';

    echo "First used: " . memory_get_usage(true) . "<br>";
  
    for ($i = 0; $i < 20; $i++) {
        $sth = $dbh->prepare($sql);
        $sth->execute();          
        $rows = $sth->fetchAll();
	    unset($rows);
	    unset($sth);
        echo "$i itteration used: " . memory_get_usage(true) . "<br>";
    }
    unset($dbh);
    echo "Last used: " . memory_get_usage(true) . "<br>";
}
catch(Exception $e) {
	var_dump($e);
}



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
First used: 2097152
0 itteration used: 2097152
1 itteration used: 2097152
2 itteration used: 2097152
3 itteration used: 2097152
4 itteration used: 2097152
5 itteration used: 2097152
6 itteration used: 2097152
7 itteration used: 2097152
8 itteration used: 2097152
9 itteration used: 2097152
10 itteration used: 2097152
11 itteration used: 2097152
12 itteration used: 2097152
13 itteration used: 2097152
14 itteration used: 2097152
15 itteration used: 2097152
16 itteration used: 2097152
17 itteration used: 2097152
18 itteration used: 2097152
19 itteration used: 2097152
Last used: 2097152


теперь надо бы патч оформить. Буду разбираться как им написать
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39661696
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в трекер написал https://bugs.php.net/bug.php?id=76488 патч приложил ждём реакции
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39665222
Dorin Marcoci
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Денис, спасибо за фикс!
Нужно сделать тест-кэйс и пулл реквест на гитхабе, о то будешь ждать бесконечно долго.
Попробую, может сделаю я, но дико не хватает время. Последние месяцы занят повседневными проэктами.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39669595
Dorin Marcoci
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Денис, там тест кэйс должен падать при нынешнем коде, и пройти успешно с твоим кодом.
Например, типа утечка ноль, а с текущим кодом > 0. Но думаю смерджят.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39669599
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dorin Marcoci,

оно падает только при segfault, а если утечка идёт, то оно скорее всего просто упрётся в ограничения на потребляемую память процессом php, который зависит от настроек. То же надеюсь что смержат. Мне комменты присылаются на почту.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39669630
Dorin Marcoci
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не то что прямо падал процес :) мой рускиш не родной..
имел ввиду чтоб не прошел тест, тоесть другой результат, не тот что в еxpected
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39669635
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dorin Marcoci,

а.. так ты про это. Мне дали вот такой коммент

nikic It shouldn't be necessary to test memory usage explicitly (because a leak message will be printed in debug builds), just have a code that was previously leaking.
...
Рейтинг: 0 / 0
PDO Firebird bugs
    #39670857
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
патч приняли :-)
...
Рейтинг: 0 / 0
25 сообщений из 222, страница 6 из 9
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / PDO Firebird bugs
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]