Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Утечка памяти при работе с TIbDataSet [D6, FireBird 2.1]


Страницы:   1 2 3 4

DelphiN! ©   (2008-10-06 16:09:00) 

Доброго времени суток!
Написал следующее:

     for j := 0 to Res.Count-1 do
     begin
       ServerFT.SelectSQL.Text := 'INSERT INTO SERVERFT (FILENAME,FILESIZE,FILECRC,BASEDIR) VALUES('''+Res.FileName[j]+''','+
         IntToStr(Res.FileSize[j])+','+IntToStr(Res.FileCRC[j])+', '''+Res.BaseDir[j]+''')';
       ServerFT.ExecSQL;
       ServerFT.Transaction.Commit;
     end;


В массиве Res более 50 000 записей, при дохождении цикла до 5080ой записи программа вываливается с ошибкой о нехватке памяти. Куда девается память? Что я делаю неправильно?


Johnmen   (2008-10-08 09:30:00) [1]


> MsGuns ©   (07.10.08 23:05) [60]
> При размере порций в 5000 штук ?

Да. Что тут удивительного? Или транзакция в 1-5 сек. считается неприлично длительной?

> MsGuns ©   (07.10.08 23:05) [60]
>> ...прогнать импорт ещё раз.
> Т.е. отресторить базу из бэкапа, предварительно ....

Что за фантазии??? :)
Просто импорт ещё раз. Но, естественно, сам импорт написан не недоучившимся студентом. Т.е., по кр.мере, с грамотной обработкой исключений, возникающих при вставке очередной записи. И БД спроектирована не им же. Т.е., по кр.мере, каждая таблица имеет как минимум уникальный индекс.


Германн   (2008-10-08 01:08:00) [2]


> MsGuns ©   (07.10.08 22:47) [52]
> Я - зловредный и ехидный тип, никого, окромя себя не видящий
> и не слышащий.
>

Самокритика это очень хорошо. :)


kaif   (2008-10-08 00:37:00) [3]

О чем спор?
Создавать временные таблицы в IB не принято.
Хочешь - создавай.

MsGuns ©   (07.10.08 22:53) [55]
>Johnmen ©   (07.10.08 22:50) [53]

Под "целостностью" я в данном случае (первая цитата) имел в виду не нарушение форинкеев, а нечто другое - когда в БД попадут НЕ ВСЕ записи, а только часть, причем абсолютно неизвестно заранее какая


А я как раз имел в виду форинкеи и юниккеи.
И я до сих пор не знаю, как ты собираешься отловить нарушение внешнего ключа при вставке через временную таблицу. У тебя отвалится весь insert into ... select from без всякой информации о том, в какой именностроке это произошло. А при непосредственном импорте у тебя имеется естественная возможность узнать это и что-то предпринять, в зависимости от задачи, например, проигнорироватьи пойти дальше.

А насчет "не всех" записей, я уже сказал. Незачем разбивать на пакеты по 5000. Можно и в одной транзакции загнать хоть миллион. Я загонял без проблем. И в случае отката единственная проблема, которая возникнет, это некоторый тормоз по чистке мусора. После одного душного select count(*) из этой таблицы все придет в порядок (кроме размера файла базы, разумеется).

Страх перед откатом больших вставок, я думаю, идет от старых версий IB6.0,  в которых были ошибки в связи с чисткой мусора.
В Firebird 1.5 Final этих ошибок я не обнаружил.


MsGuns   (2008-10-07 23:05:00) [4]

>Johnmen ©   (07.10.08 22:59) [58]
>С какого они длительные??? Очень даже короткие!

При размере порций в 5000 штук ?

>Я админом не командую. Но если заставят, то просто прикажу прогнать >импорт ещё раз.

Т.е. отресторить базу из бэкапа, предварительно послав на перекур всех юзверей и запустить по новой ? На месте админа я бы такого спесилиста повесил на входе в серверную. За яй... в смысле не за шею ;)


MsGuns   (2008-10-07 23:02:00) [5]

"Хирургия" вполне обоснованна только в одним случае - если "пакет" порезать на независимые логически завершенные (т.е. целостные) "порции" приемлимых размеров. В этом случае клиент может всегда продолжить прерванную трансмиссию данных с "аварийного" пакета. Тогда конечно, следует работать исключительно по классической схеме, ибо она реально является самой оптимальной для сервера.
Но в сабже, повторяю, ни слова об этом.


Johnmen   (2008-10-07 22:59:00) [6]


> MsGuns ©   (07.10.08 22:50) [54]
> ДЛИТЕЛЬНЫЕ ПИШУЩИЕ ТРАНЗАКЦИИ

С какого они длительные??? Очень даже короткие!


> MsGuns ©   (07.10.08 22:53) [55]
> Что прикажете делать админу БД в этом случае ?

Я админом не командую. Но если заставят, то просто прикажу прогнать импорт ещё раз.


MsGuns   (2008-10-07 22:58:00) [7]

Кистати, в ИБ имеется возможность ссылаться в запросах на внешние таблицы, насколько я помню. Эге ж ?


Johnmen   (2008-10-07 22:54:00) [8]


> MsGuns ©   (07.10.08 22:42) [51]
> Ваш способ нафиг и я объяснил почему.

Способ не мой, а классический. Легко находится, как указывалось в [39]. Поэтому посылай классиков. И объясняй им же.


> MsGuns ©   (07.10.08 22:47) [52]
> Но что ты скажешь, если и тебе приклеить ярлычок - "догматик" ?

Пожалуйста. Только с обоснованием.


MsGuns   (2008-10-07 22:53:00) [9]

>Johnmen ©   (07.10.08 22:50) [53]

Под "целостностью" я в данном случае (первая цитата) имел в виду не нарушение форинкеев, а нечто другое - когда в БД попадут НЕ ВСЕ записи, а только часть, причем абсолютно неизвестно заранее какая. Что прикажете делать админу БД в этом случае ?

Слушаю с замиранием сердца ;)


Johnmen   (2008-10-07 22:50:00) [10]

Смотрим:
>> можно дураку объяснить - какой смысл в commit-е порциями
>> (ну скажем, по 500-1000 штук) ?

>быстрее вставка происходить будет.

> MsGuns©   (07.10.08 10:26) [20]
>и фиг с ней, с целостностью?

и вдруг
> MsGuns©   (07.10.08 22:38) [50]
> Ну какая разница, каким макаром всталять записи в таблицу - хором
>(запросом Insrt to select from) или поодиночке с точки зрения ссылочной
> целостности, а ?

Ты, Серега, что-то совсем заговорился...
Далее читать посты глубоко верующего в единственность и непогрешимость просто неинтересно.
Хотя, возможно, ты говоришь про что-то своё, не связанное с темой ветки. Тогда - просто бесполезно.


MsGuns   (2008-10-07 22:50:00) [11]

Поймите же в конце концов, что при вашей "хирургии" ДЛИТЕЛЬНЫЕ ПИШУЩИЕ ТРАНЗАКЦИИ, против коих так дружно вопят все классики интербизма-файрбердизма, просто неизбежны !


MsGuns   (2008-10-07 22:47:00) [12]

>Johnmen ©  

ИШ, конечно, зануда, я понимаю.
Я - зловредный и ехидный тип, никого, окромя себя не видящий и не слышащий.
А вместе мы дилетанты.

Но что ты скажешь, если и тебе приклеить ярлычок - "догматик" ?


MsGuns   (2008-10-07 22:42:00) [13]

>Johnmen ©   (07.10.08 22:29) [49]

Замечательно. Конечно, сабж - это, конечно, нетипичный случай. Но если возникает все же такая необходимость - заливать объемные данные извне - что делать ? Ваш способ нафиг и я объяснил почему.
ИБ у меня попал в разряд "немилостевых" и потому в том числе, что разработчики не удосужились придумать хотя бы что-то напоминающее мелкософтовый DTS


MsGuns   (2008-10-07 22:38:00) [14]

Охохохохонюшки..
Я ему при пльзеньское, он мне про златолюбие блондинок.

Причем здесь вообще форин, а ? Ну какая разница, каким макаром всталять записи в таблицу - хором (запросом Insrt to select from) или поодиночке с точки зрения ссылочной целостности, а ?

Далее. Про "полный маразм, перестраховщину и излишество", т.е. временные таблицы.

...

Фух, начал писАть примеры, наваял два экрана и плюнул ;(
Ну почему тебе надо объяснять очевидное - что лучше во временной таблице, к которой даже теоретически не может быть попыток доступа из других коннектов, собрать все добавляемые записи, а после этого запустить ОДИН запрос и при этом ВСЕ ДАННЫЕ сервер будет брать непосредственно "в себе", не дожидаясь завершения всякой внешней фигни типа тормозов сетки/клиента и т.д. И если что-то не получится, то откатит всю транзакцию. Понимаешь - ВСЮ ! Т.е. все стотыщмильонов записей. А не "аварийную" порцию в твоем "хирургически-традиционном" методе. Во-первых, представлю, как сервер собирает и ХРАНИТ ДЛИТЕЛЬНОЕ ВРЕМЯ (особенно если клиент "медленный") 49999 версий записей и только при добавлении 50000-й "спускает пар", затем вся эта хрень повторятся для следующей порции и т.д.
Но самое смешное, если при отсылке 999-й порции выяснится, что очередная запись не может быть внесена в БД (хотя бы по причине  нарушения так любимой тобою ссылочной целостности) и поэтому ВСЮ ВСТАВКУ НАДО ОТМЕНИТЬ. Вот что ты предлагаешь в этом случае ? Поднимать бэкап и петь "осанну" "классической" хирургии, принесшей в жертву науки только что склеившего ласты при операции аппендицита несчасного пациента ? И ховаться в жито от разгневанных родных и близких зарезанного ?


Johnmen   (2008-10-07 22:29:00) [15]


> kaif ©   (07.10.08 22:10) [48]

Да-да.
В IB до 7.5 и в FB до 2.0, как минимум, не было "встроенных" таблиц. Выполнять DDL команды (в т.ч. CREATE TABLE) в SP недопустимо. Менять структуру БД, создавая таблицу, например, "в рантайме" категорически не рекомендовано. Особенно при незнании определенных нюансов и особенностей.


kaif   (2008-10-07 22:10:00) [16]

MsGuns ©   (07.10.08 20:29) [42]
>kaif ©   (07.10.08 18:13) [34]
>Временные таблицы - это стиль MSSQL,  а не IB.

Ашот, не надо метром мерять объемы, а ? Есть задача и надо найти для ее решения оптимальный способ. А в "стиле" это или нет - это уже эстетство, в данном случае к делу никакого отношения не имеющее.


Сергей, ты неправ. Оптимальное решение в MSSQL и в IB могут оказаться просто прямо противоположными.

Так как IB версионник, а MSSQL - блокировочник.
В MSSQL временные таблицы используются повсеместно, возможно, как лучший способ избежать эскалации блокировок. Временные таблицы можно  даже создавать в хранимых процедурах, а в IB так действовать не принято. Я даже не уверен, что в IB можно использовать CREATE TABLE  в ХП (может в каких-то поздних версиях можно, я не в курсе, так как никогда этим не пользуюсь).

Поэтому и решения для этих двух серверов в данном случае могут быть разными. Я лично в IB никогда не пользуюсь временными таблицами.

И я против таких подходов в IB.
Объясню почему.

При импорте данных наиважнейшими обстоятельствами являются:

1. ссылочная целостность данных
2. скорость.

Временная таблица никаких преимуществ в версионниках в смысле блокировок не дает,  так как никаких блокировок в версионниках попросту не бывает, а при INSERT даже Lock-конфликтов (конкуренции за апдейт одной записи) не предвидится. Так что временная таблица для импорта в версионнике - полный маразм, перестраховщина и излишество.

А вот создавать временную таблицу и вешать на нее foreign key есть еще больший маразм, так как это потребует кучи дополнительных ресурсов и еще больше замедлит импорт.
А если не вешать foreign key, то я не знаю, как обеспечить ссылочную целостность при импорте.
В MSSQL многие вообще не используют foreign key, а проверки делают в триггерах. Старые версии MSSQL (может я ошибаюсь) про декларативную ссылочность вообще ничего не знали, а некоторые учебники до сих пор не рекомендуют ее юзать, предпочитая делать все в триггерах.
А в IB всегда все было прямо наоборот. Декларативной ссылочной целостности уделялось много внимания, а в триггерах заниматься этими проверками в IB просто не рекомендуется по ряду причин. И первая из них - триггер работает в контексте транзакции, а внешний ключ - вне контекста транзакции. Поэтому в IB триггер не обеспечивает со 100% вероятностью ссылочной целостности, а внешний ключ - обеспечивает.

Плюсов же во временной таблице я никаких не вижу вообще.

Я писал десятки программ, в которых приходилось делать импорт в IB,  в некоторых до миллиона записей. Ни разу временные таблицы я не применял и применять (в IB конкретно) не собираюсь.


Германн   (2008-10-07 21:28:00) [17]


> Ну так физики-то так и нету ?

Какая физика? Сегодня вся физика в Стокгольме была :)


Игорь Шевченко   (2008-10-07 20:52:00) [18]

DrPass ©   (07.10.08 20:38) [44]


> А вы теперь перед очевидными доказательствами сразу решили
> в кусты слинять, что-то там про конкретные задачи? ;-)


Ну так физики-то так и нету ? А практических примеров я тоже могу. Давай продолжим дискуссию с поста [13]


DrPass   (2008-10-07 20:38:00) [19]


> Сергей М. ©   (07.10.08 20:35) [43]
> А автор тем временем засох)..

А зачем он нам? Мы и без него неплохо пообщаемся :-D


DrPass   (2008-10-07 20:38:00) [20]


> Игорь Шевченко ©   (07.10.08 20:03) [40]


> Допустим, у меня есть задача вставить, скажем, 20000 записей.
>
> В зависимости от того, что надо сделать, если 15732-ая не
> вставилась, я и буду строить логику - если требуется откатить
> все изменения, то и транзакция будет одна.

Игорь, это само собой разумеется. Но нас этот вопрос вообще не должен интересовать, т.к. логика обработки ошибок - дело сугубо индивидуальное, тут миллионы вариантов, и обсуждать их без конкретной постановки задачи нет никакого смысла. Мы вообще-то говорили о производительности вставки записей в общем случае, без изысков и дополнительных условий.
Да и вы вообще-то не так давно совсем в другую сторону вели (вот тут я не ссылочку, а цитатку приведу, не возражаете?)

> ну понятно - black voodoo. Желающие подкручивать гайки без
> хлеба не останутся. Но все-таки - насколько мне известно,
>  IB не запускает сборку мусора после каждого commit, версии
> все равно зависят от количества одновременно стартовавших
> транзакций - какая физика механизма, что при транзакции
> "пакетом" быстродействие выше ?

А вы теперь перед очевидными доказательствами сразу решили в кусты слинять, что-то там про конкретные задачи? ;-)


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо