Использование IB7.5

Access Violation, некорректное выполнение запросов или вызовов API, ошибки утилит командной строки, в общем все, что вам мешает работать

Модераторы: kdv, dimitr

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 19 апр 2005, 17:49

Пока натолкнулся на такую вещь.
Вот глупый запрос:
select Count(*) from RDB$RELATION_FIELDS where f_StrBlob(RDB$FIELD_NAME) is Not null
Для чистоты эксперимента взял не свои udf из freeudflib.zip(на своих все тоже самое, в начале свалил на них, но они написаны почти идентично).
Выполняем запрос, съедается почти у меня 170 Мб.
Теперь самое интересное если использовать CommitRetaining, то Transaction manager память не сбрасывает. Если использовать настоящий Commit, то Transaction manager сбрасывает память. Правда не понятно она все равно остается выделенной.
Подтверждается на версиях IB 7.1; Ib7.5 и FB 1.5(на нем смотрел память только через диспетчер задач). Может проблема и не в переходе на 7.5, а в том, что пользователи стали использовать некоторую функциональность больше.
Но ладно CommitRetaining. А если это запрос выполнить раз так 10 без закрытия транзакции, то памяти вообще не хватит.

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 19 апр 2005, 18:08

Самое мне непонятное происходит при использовании udf на запись
Запрос типа:
update <table> Set <ПолеБлоб>=StrToBlob('dfd') where <условие>
Это не вызывает увеличение памяти даже с CommitRetaining.
Может, проясните мне не сведущему, почему так происходит?
[/code]

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 19 апр 2005, 18:24

Теперь самое интересное если использовать CommitRetaining, то Transaction manager память не сбрасывает. Если использовать настоящий Commit, то Transaction manager сбрасывает память.
ничего интересного. CommitRetaining на "индикаторы" OST, OAT, OIT никакого влияния не оказывает. То есть, с точки зрения мусора и т.п. такая транзакция просто очень долго длится, до реального commit.

твой запрос (select) на FB 1.5.2 отъедает по +5 мег, при каждом выполнении, до очередного commit.

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 19 апр 2005, 18:28

твой запрос (select) на FB 1.5.2 отъедает по +5 мег, при каждом выполнении, до очередного commit.
Зависит от объма данных.

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 25 апр 2005, 11:14

От CommitRetaining так сразу не уйдешь. Пока посталался убрать часть использованных UDF возвращающих болбы и IB7.5 пока живет. Память идет, но терпимо.

Для меня непонятный остался один вопрос, для чего кешируются блобы, которые создаются UDF в хранимых процедурах, к ним извне все равно не подлезешь?

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 25 апр 2005, 14:09

_so_ писал(а):Пока натолкнулся на такую вещь.
Вот глупый запрос:
select Count(*) from RDB$RELATION_FIELDS where f_StrBlob(RDB$FIELD_NAME) is Not null
Для чистоты эксперимента взял не свои udf из freeudflib.zip(на своих все тоже самое, в начале свалил на них, но они написаны почти идентично).
Выполняем запрос, съедается почти у меня 170 Мб
FB 1.5.2

feature is not suported
BLOB and array data types are not supported for conversion operation

Код: Выделить всё

SELECT COUNT(*)
  FROM RDB$PROCEDURES P
 WHERE F_STRBLOB(P.RDB$PROCEDURE_SOURCE) IS NOT NULL

Код: Выделить всё

SELECT COUNT(*)
  FROM RDB$PROCEDURES P
 WHERE F_STRBLOB(P.RDB$PROCEDURE_SOURCE) IS NULL
Память стоит, как вкопанная

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 25 апр 2005, 16:09

2 hvlad :D :D :D А лучше вообще запросы не выполнять тогда еще лучше будет.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 25 апр 2005, 16:46

Фитилёк-то притуши, коптит (С). Чем так ржать, подумал бы о том, на что тебе намекают - ну не блоб RDB$FIELD_NAME, не блоб вовсе :wink:

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 25 апр 2005, 17:13

2 Merlin. Я же сразу написал, что это примерный запрос. Читать надо внимательнее.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 25 апр 2005, 17:20

пррекратить разговорчики! :)

20 числа я лично DE показывал запрос на FB 1.5.2

Код: Выделить всё

select Count(*) from RDB$RELATION_FIELDS where f_StrBlob(RDB$FIELD_NAME) is Not null
который жрет примерно по 5 мег на запуск. Транзакцию завершаем - память освобождается. Так штааа...

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 25 апр 2005, 17:44

_so_ писал(а):2 Merlin. Я же сразу написал, что это примерный запрос. Читать надо внимательнее.
А можа всё-тки писать примерности надо тщательнеЕ? А то Владу заняться больше нечем, кроме как проверять баги конкурентов на своём детище, да к тому же очень может быть примерно- мифические.

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 25 апр 2005, 17:48

Странно... у меня f_StrBlob почему-то была объявлена как

Код: Выделить всё

DECLARE EXTERNAL FUNCTION F_STRBLOB
    BLOB
RETURNS CSTRING(254)
ENTRY_POINT 'StrBlob' MODULE_NAME 'FreeUDFLib.dll'
вместо

Код: Выделить всё

DECLARE EXTERNAL FUNCTION F_STRBLOB
    CSTRING(254),
    BLOB
RETURNS PARAMETER 2
ENTRY_POINT 'StrBlob' MODULE_NAME 'FreeUDFLib.dll'
Стоит сказать, что я ей никогда не пользовался :)

2Merlin: у тебя тоже такое кривое объявление ? Наверное очень старая версия FreeUDFLib, ничем другим не могу это объяснить

С исправленным объявлением память действительно течёт. Примерный р-р утечки = р-р страницы * кол-во обращений к ф-ции.

В 2-ке тоже, так что будем править

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 25 апр 2005, 17:48

kdv писал(а):пррекратить разговорчики! :)
Да я и так уж почти прекратил :) Задрало выспрашивать версии сервера, да пятое-десятое, да в доки носом тыкать, да проктологов лечить безуспешно. И, представь себе, с вечера пятницы, когда решил молчать в таких случаях, вопросов, поставленных так, чтоб захотелось ответить - нуль целых нуль десятых в трёх форумах.

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 25 апр 2005, 17:48

Так нафига ее кушать. Почему-то думаю что-эти блобы кешируюся, но почему они сразу не убиваются? На клиенте я до них все-равно не доберусь.
Я бы согласился с выделением памяти до окончании транзакции если эти блобы были бы в секции select .. from.

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 25 апр 2005, 18:02

Блобы, возвращаемые в данном примере, временные, т.е. на них нет ссылок из записей реальной таблицы. Временный блоб всегда создаётся в памяти и под него выделяется буфер размером со страницу. При завершении тр-ции временные блобы (так и не ставшие постоянными) удаляются, т.к. они всегда действуют в контексте тр-ции. Раньше их удалять нельзя, т.к. их blob_id могут быть выданы клиенту и он может с ними работать, например присвоить какой-нибудь записи. Так что я не думаю, что данная проблема имеет простое решение - движок понятия не имеет о том, что создаваемый блоб никогда не пойдёт на клиента.

В общем - нужно думать :)

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 25 апр 2005, 18:06

_so_ писал(а):Самое мне непонятное происходит при использовании udf на запись
Запрос типа:
update <table> Set <ПолеБлоб>=StrToBlob('dfd') where <условие>
Это не вызывает увеличение памяти даже с CommitRetaining.
Может, проясните мне не сведущему, почему так происходит?
Потому что в данном случае ссылка на временный блоб, созданный ф-цией, присвоена записи - блоб стал постоянным (материализовался), лег на диск и держать в памяти (не в страничном кеше) его больше не нужно.

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 25 апр 2005, 18:13

Для лучшей оптимизации я думаю можно было бы выявить случаи когда болбы не идут на клинт (например секция where и обработка внутри ХП). Если нужно будет обработать много данных с blob, то памяти может и не хватить.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 25 апр 2005, 20:55

т.к. они всегда действуют в контексте тр-ции. Раньше их удалять нельзя, т.к. их blob_id могут быть выданы клиенту и он может с ними работать, например присвоить какой-нибудь записи. Так что я не думаю, что данная проблема имеет простое решение - движок понятия не имеет о том, что создаваемый блоб никогда не пойдёт на клиента.
я почему-то думал, что в данном случае достаточно не контекста транзакции, а контекста открытого запроса. Правда, тогда поломается
select StrToBlob('a') from rdb$database, ибо он по избыточному (упреждающему фетчу клиентом?) чтению тут же закроется...

Ответить