Показать сообщение отдельно
Старый 18.02.2008, 12:13 Вверх   #4
Admin
 
Аватар для RAMZA
RAMZA вне форума
Доп. информация
Лампочка

A: Данный вопрос касается только бета-версий IB 6 и самого последнего релиза IB 6.01 от Borland. FireBird может работать с БД от 5.x.

Скорее всего вы поставили IB 6 в каталог, где ранее был установлен IB 5 или 4. При установке инсталлятор не переписывает базу данных паролей пользователей (isc4.gdb), т.е. он ее сохраняет, предполагая что вы могли забыть сделать резервную копию этой БД. А поскольку бета IB6 не может работать с базами данных предыдущего формата (только после backup/restore), то и не может подсоединиться к isc4.gdb для получения пароля SYSDBA (или любого другого пользователя).
Если вам нужен isc4.gdb, то скопируйте его в isc4copy.gdb и положите в сторонку. Потом возьмите isc4.gdb из дистрибутива IB 6, и поместите на место старого. После этого подсоединиться можно как SYSDBA и masterkey. Для восстановления списка пользователей необходимо сделать backup isc4copy.gdb на IB версии 5, затем восстановить этот backup под IB6, остановить сервер IB6 и переименовать isc4copy.gdb в isc4.gdb.
Можно обойтись и без такой процедуры, если откопировать данные из старой базы данных в новый isc4.gdb каким-нибудь инструментом вроде datapump (см. Tools Downloads).
select DISTINCT выполняется медленно или не использует индексы

В IB 6.0 оптимизатор использует сортировку (PLAN SORT) вместо использования индекса, как это было в 5.x.
что такое "сертифицированные билды"?

"Сертифицированные билды" - означает дистрибутивы Interbase/Firebird, тщательно протестированные на определенной версии какой либо ОС (Windows, Linux, Solaris и т.д.). Причем как правило сертифицированные билды являются ПЛАТНЫМИ (см. например faq по сертифицированным билдам от Borland). Конечно, в любом случае в лицензии написано, что не дается никаких гарантий, однако такие версии работают намного более надежно, чем просто скомпилированные и выложенные на web.
dpb constant 0 unknown

Это ошибка одной из самых древних версий IBConsole. У Вас однозначно слишком старый дистрибутив Interbase, а возможно даже и бета-версия 1999 года. Немедленно удалите эту версию с диска, и возьмите более свежую версию Interbase или Firebird. Еще лучше в качестве средства разработки использовать IBExpert - www.ibexpert.com.
Клиент от Firebird, Yaffil и IB7 не работает под Win95/98

Первая причина: во всех последних версиях IB в клиентской и серверной части используется только WinSock2 (например в Firebird начиная с билда 682). Windows 95 в этом плане уже устарела (в базовом комплекте есть только WinSock1), ей требуется обновление:

http://www.microsoft.com/windows/dow...95ws2setup.exe

Yaffil начиная с билда 860 не требует Winsock2 (достаточно winsock1)

Вторая причина: пока относится только к Yaffil - он скомпилирован MSVC7, поэтому в качестве сервисной библиотеки требуется msvcr7.dll, которая присутствует по умолчанию пока только в WinXP и Win2003 (Interbase и Firebird пока компилируются MSVC6, который требует msvcrt.dll. В чистой Win95 эта библиотека также отсутствует).
Поэтому для нормальной работы нужно положить msvcr7.dll (есть в дистрибутиве Yaffil) в path или рядом с gds32.dll.

Третья причина: Firebird 1.5 кроме обычно требуемой msvcrt.dll требует наличия msvcp60.dll. Этой библиотеки по умолчанию нет ни в Win95, ни в Win98.

Также см. пункт "после установки Yaffil сервер или udf падают"
Есть ли Interbase 6 или Firebird для Novell Netware?

Нет и не будет. Вообще данная операционная система плохо предназначена для работы в качестве сервера и в настоящее время является достаточно экзотической. Даже существовавшие версии Interbase (5.6, 4.2) для Netware не рекомендуется использовать по этим же причинам. Подробнее см. http://www.ibase.ru/devinfo/0108.htm
DBD: ошибка Not enough LongReadLen buffer

Прислал Alex Maximenko:

Из справки по DBI: нужно устанавливать для $dbh аттрибут LongReadLen, который заведомо больше любого читаемого блоба. Это можно сделать как при коннекте к базе, так и на лету: $dbh->{LongReadLen} = ... /В принципе установка LongReadLen вроде лишнюю память не отнимает, так что установить этот параметр можно в DBI::connect.
почему не используются два (четыре) процессора?

Начнем с того, что существует две архитектуры IB/FB - SuperServer и Classic. Вначале IB был только Classic, и первым SuperServer-ом стала версия 4.2 для Windows. Далее Classic оставался на Unix, а на Windows остался только SuperServer (см. выше о Classic в Firebird и Yaffil).

Различие Classic и SuperServer состоит в том, что Classic - старая технология, когда на каждого пользователя (коннект) создается процесс. Кэш БД у каждого процесса раздельный, и занимает он минимум 3 мегабайта памяти (в реальной жизни в среднем 10-20 мегабайт, бывает и 35). Поэтому в Classic при большом количестве пользователей требуется большое количество RAM.
SuperServer - это один процесс, где пользователи обрабатываются в threads (несколько пользователей могут обрабатываться одним thread-ом). В данном случае кэш БД общий, поэтому много пользователей не требуют много памяти.

Однако в случае падений сервера, если в Classic "погибает" только один пользовательский процесс, SuperServer "падает" весь.

При выпуске 6.0 Borland хотел отказаться от выпуска Classic, поэтому Services API в Classic фактически не реализовано. В 6.5 Classic вообще отсутствует, есть только SuperServer для Windows, Linux и Solaris. Однако, Firebird выпускает почти для всех ОС как Classic, так и SuperServer, и даже есть ОС на которых существует только Classic (FreeBSD). Более того, в настоящее время есть Yaffil Classic for Windows и Firebird Classic for Windows.

SuperServer не может использовать несколько процессоров в силу своей архитектуры. Конечно, загружены будут оба процессора, но из-за нераспараллеливания операций ввода-вывода каждый процессор будет загружен не более чем на 50% (при двух. При четырех - на 25%). Для решения этой проблемы в Firebird и позже в Interbase 6.5 был добавлен параметр IBCONFIG - CPU_AFFINITY. Это битовая маска, в которой указываются номера процессоров, которые необходимо задействовать. Например, 1 означает работу на первом процессоре, 2 - на втором, 3 - на первых двух и так далее. Освободившийся процессор можно занять другими задачами.

Самое оптимальное решение масштабирования при работе на многопроцессорных машинах - использование архитектуры Classic для Linux (или других Unix).
хочу шифровать трафик

IB, FB или Yaffil не поддерживают шифрование трафика. Если вы хотите этого, то имеет смысл воспользоваться например
http://www.winton.org.uk/zebedee/ см. статью по использованию ZeBeDee для IB/FB/Yaffil
http://www.stunnel.org/
http://www.nothingbutnet.co.nz/ibeproxy.htm

При более серьезных требованиях, например сертификации средств шифрования, следует обратить взгляд на аппаратно-программные средства, например http://www.ancud.ru/.

Скорее всего, никакие средства шифрования трафика в IB/FB/Yaffil в ближайшее время встроены не будут.
медленный коннект (и работа) на WinMe/WinXP

Причина в том, что Me и XP содержат так называемую систему восстановления файлов. В соответствии со списком расширений любой файл, который изменяется, копируется системой в специальное место для возможного восстановления в дальнейшем. В этом списке есть расширение gdb, что приводит для IB к долгому коннекту и очень медленной работе.
Данную особенность можно выключить целиком:

На XP: System Properties | System Restore | Turn off System Restore on all drives.

На Me:

либо убрать из списка расширение gdb, отредактировав файл
на XP: $WINNT$\system32\Restore\filelist.xml

на Me: ... (примерно аналогичный, точное имя данного файла на ME не указано)

Или просто-напросто изменить расширение файла базы данных, на такой, для которого указанная функциональность не работает (например, для баз InterBase начиная с 7.0 рекомендуется расширение *.ib, только по указанной выше причине).

p.s. не нужно при этом упрекать MS в нелюбви к IB. Это просто случайность, т.к. расширения файлов в большинстве состоят из трех букв, количество комбинаций которых ограничено.
медленный (долгий) коннект на Win2003

Это происходит только на старых версиях IB/FB/YA, например Interbase 6, Firebird 1.0.x. Причина - изменения в ядре Win2003, в результате чего ошибки синхронизации в коде старых версий IB/FB/YA стали проявляться в виде очень долгого коннекта (20 секунд и более), и иногда в виде нестабильной или очень медленной работы.

Избавиться от этой проблемы можно либо переходом на InterBase 7.1, Firebird 1.5, последнюю версию Yaffil, или возвратом на Windows 2000.
нет коннекта после установки SP2 на Windows XP

После установки SP2 на Windows XP автоматически включается встроенный Firewall, который блокирует доступ практически по всем портам tcp/ip, и что самое главное - по порту 3050, который используют InterBase, Firebird и Yaffil для работы (по умолчанию). Т.е. порт 3050 в Firewall нужно открыть (если не будет работать, нужно еще открыть порт 113).

Если используются Events, то в Firebird 1.5 можно принудительно указать их работу по порту 3060 (например) параметром remoteauxport в firebird.conf. В случае остальных серверов, возможно, придется отключить firewall, или промониторить попытки открытия портов (утилитами с www.sysinternals.com), т.к. в предыдущих версиях для Events использовался произвольный номер порта tcp.

См. http://www.ixbt.com/soft/win-xp-sp2....ork_protection и

http://bdn.borland.com/article/0,1410,32532,00.html
При выполнении запроса выдается "I/O Error for file..."

При выполнении запроса (скорее всего запрос содержит ORDER BY и план такого запроса содержит PLAN SORT) выдается ошибка:
"I/O Error for file c:\windows\temp\ib_sort_a02472.
Error while trying to write to file. Sort Error."

(имя файла может быть любым)

Это означает, что на диске, указанном в пути TEMP в системе нет свободного места для сортировки данных, возвращаемых запросом. Нужно или изменить переменную TEMP, чтобы она указывала на диск с достаточным свободным пространством, или сконфигурировать tmp_directory в ibconfig (или firebird.conf).
При долгой работе переполняется память сервера

Выглядит это как увеличение памяти, потребляемой процессом сервера с течением времени, неосвобождение памяти при отключении всех пользователей, либо сообщение ОС о том что виртуальная память кончилась, и т.п.

Как правило, на 99% причина такой проблемы - это некорректно написанная UDF. Причем необязательно ваша, а например сторонняя (rfunc рекомендуется брать самой последней версии).

Лучше всего проверять UDF на утечки памяти при помощи процедур. Для этого делается процедура
create procedure testudf
as
declare variable i int;
declare variable s <>;
begin
i=0;
while (:i < 1000000) do
begin
s=MyUdf(<udfparam>);
i=:i + 1;
end
end

при выполнении которой вы смотрите в TaskManager. Если занимаемая сервером память с течением времени увеличивается - значит в udf есть утечки памяти.
не удается создать вторичный ключ (FK)

при ALTER TABLE X ADD [constraint FK_X] FOREIGN KEY (ID) REFERENCES Y (ID);

выдается сообщение

"unsuccessful metadata update, STORE RDB$REF_CONSTRAINTS failed,
action cancelled by trigger (1) to preserve data integrity,
Name of Referential Constraint not defined in constraints table."

A: в IB 6.0 (например 6.0.0.627) не удается сделать FK, если у таблицы Y к этому моменту уже есть FK по ID от любой другой таблицы, или просто индекс по полю ID, название которого начинается с буквы меньше S. Либо нужно сменить версию (в Firebird RC2 такой ошибки нет, как ее нет и в IB 5.6), либо располагать создание FK отдельно, в порядке detail-master, после чего создавать индексы (если по этим полям они вообще нужны).
Я удалил SYSDBA. Что делать?

A: пока что в IB/FB/Yaffil все пользователи хранятся в файле ISC4.GDB (IB7 - admin.ib, FB 1.5 - security.fdb). Это обычная база данных. В дальнейшем, возможно какой-либо из серверов будет поддерживать пользователей прямо в базах данных, без необходимости ISC4.GDB, но пока это только в планах.

Следовательно, нужно сделать следующее:
остановить сервер IB
скопировать isc4.gdb например в isccopy.gdb
взять isc4.gdb из того самого дистрибутива, версия которого установлена, подсунуть на место isc4.gdb
запустить сервер IB. теперь логиниться сможет только SYSDBA с паролем masterkey
подсоединиться к isccopy.gdb, и например IBExpert-ом извлечь данные из таблицы users в скрипт
применить скрипт к новой isc4.gdb
не забыть сменить пароль masterkey у SYSDBA, продолжить работу.
Что такое rdb$db_key?

A: Это "номер записи". Для таблиц он имеет длину 8 байт (для view - 8 байт умножить на количество таблиц в запросе, если запрос содержит явный или неявный join), которые представлены в виде строки, содержащей двоичные значения. Поэтому в ряде инструментов запрос

select rdb$db_key, t.* from table t

будет возвращать "мусор" в первом столбце.

rdb$db_key можно использовать в качестве уникального идентификатора записи, так же как и ее поле первичного ключа. Однако rdb$db_key по ходу работы может меняться. Физически он представляет собой номер таблицы, номер страницы и смещение на запись (причем не на конкретную версию, а вообще на пакет версий этой записи, если они есть).

По использованию rdb$db_key можно почитать следующие документы:

Удаление или поиск дубликатов записей в таблице
http://www.ibase.ru/devinfo/deldupes.htm

Update данными из других таблиц
http://www.ibase.ru/devinfo/updsame.htm

немного о db_key (eng)
http://www.ibase.ru/mail/dbkey1.txt и http://www.ibase.ru/mail/dbkey2.txt

"Practical use of rdb$db_key" на английском:
http://www.cvalde.com/document/pract...of_the_rdb.htm

The mistery of rdb$db_key, на английском, в 4-х частях
http://www.cvalde.com/document/mysteriousDbKey.htm
Есть ли хостинг баз Interbase/Firebird/Yaffil?

Да, есть. В России:

www.sweb.ru

за рубежом:

www.kylixhost.com/ahosting.php

www.datamarkenterprises.com/Packages.htm

www.yournewhosting.com
как правильно задать SEGMENT SIZE для BLOB?

Задавать этот параметр вовсе не нужно. Фактически, это атавизм - используется только утилитой GPRE при обработке Embedded SQL.
При этом препроцессор Embedded SQL будет использовать объявленный segment size просто как буфер требуемой длины для чтения или записи блоба. Blob segment size = 80 байт по умолчанию, потому что в изначальной версии InterBase в блобах хранились строки, а в те древние времена длина строки была обычно ограничена числом символов, помещающихся на алфавитно-цифровой терминал.

Компоненты или драйверы практически всегда используют жестко заданный размер "сегмента". Например, в IBX (и FIBPlus) размер буфера для записи куска данных в blob определяется константой DefaultBlobSegmentSize (ibblob.pas), которая равна 16к. Если посмотреть код функции записи blob,
procedure WriteBlob(hBlobHandle: PISC_BLOB_HANDLE; Buffer: PChar; BlobSize: Long);
то в коде видно, что если размер записываемых данных меньше чем размер буфера (16к), то в isc_put_segment указывается скорректированный размер буфера (переменная SegLen).

Сервер сохраняет blob следующим образом
Если размер данных, записываемых в blob, помещается на свободном месте рядом с оригинальной записью, которой принадлежит blob - blob записывается на это место (при этом возникает "фрагментированность" страниц данных блобами, что в некоторых случаях может ухудшить производительность при обработке только записей). Объем свободного места зависит от размера страницы и количества записей, уже размещенных на этой странице.
Если свободного места на странице записей нет, то для blob выделяется отдельная страница или несколько, в зависимости от размера blob. Если после записи blob на такой странице осталось свободное место, то оно остается пустым и не будет занято другими blob.

Таким образом, как видите, о размере сегмента при объявлении blob не стоит беспокоиться, совершенно.
как работать с BLOB?

Достаточно просто. Даже если вы указываете подтип блоба (sub_type), серверу все равно, что вы будете там хранить - текст, картинку или звук.
Например, сохранить содержимое столбца blob в файл можно таким образом:

В C# (.Net) - http://firebirdsql.org/dotnetfirebir...le-csharp.html

В IBX:
(то же самое - и в FIBPlus. см. статью http://www.devrace.com/ru/fibplus/articles/2261.php)
procedure TForm1.Button1Click(Sender: TObject);
begin
IBDataSet1.FieldByName('BLB') as TBlobField).SaveToFile('c:\blob.bin');
...

end;

Практически то же самое - при записи, причем делать это можно двумя вариантами:

1. передача blob через параметр. Имеется в виду запрос вида
insert into table (field1, field2, blbfield) values (aram1, aram2, :blb); :
IBQuery1.ParamByName('blb').asBlob:=blobvar;

asBlob принимает значение в виде простой строки (string). Действительно, строки в последних версиях Delphi (как минимум с Delphi 3) могут содержать любую, в т.ч. двоичную информацию. Поэтому значение параметру blob можно присваивать и как asString.

2. изменение столбца "редактируемого" DataSet - запись blob из файла в столбец:
IBDataSet1.Edit;
(IBDataSet1.FieldByName('BLB') as TBlobField).LoadFromFile('c:\blob.bin');
IBDataSet1.Post;

В предыдущих версиях IBX (до 4.42 включительно) можно было работать с blob иначе. Например, запись в файл
procedure TForm1.Button1Click(Sender: TObject);
var B: TIBBlobStream;
begin
B:=IBDataSet1.CreateBlobStream(IBDataSet1.FieldByName('BLB') as TBlobField, bmRead);
B.SaveToFile('c:\blob.bin');
B.Free;
end;

и чтение из файла
IBDataSet1.Edit;
B:=IBDataSet1.CreateBlobStream(IBDataSet1.FieldByName('BLB') as TBlobField, bmWrite);
B.LoadFromFile('c:\blob.bin');
B.Free;
IBDataSet1.Post;

Обратите внимание, что метод B.Free вызывается перед вызовом IBDataSet1.Post (а не наоборот, как это приведено в некоторых старых примерах в интернете).

Также, вопреки документации, давно (по крайней мере в версии IB 4.0 и выше) можно спокойно передавать и принимать blob как параметры процедуры. Существует, однако, обязательное условие - поскольку blob это дисковая структура, записываемый blob должен быть сохранен в столбце таблицы (insert/update), а считываемый blob должен быть выбран из таблицы (хотя можно из из функции чтения blob, например LoadBlobFromFile из UDFDEMO).

Для работы с blob на сервере можно использовать UDF например из FreeUDFLib.
Как поместить базу на CD?

Для размещения БД на read-only носитете в InterBase 6.0 введены специальные ключи у gbak и gfix.
Подробно по работе с такими БД читайте документацию (opguide.pdf, страница 111).

Итак, делаете backup, а затем restore с ключами

gbak -c db.gbk db.gdb -mode read_only -use_all_space

ключ -mode read_only включает у БД режим " только чтение". Т.е. транзакции стартовать можно, но разницы между commit/rollback нет, нельзя делать insert/update/delete или менять значения генераторов функцией gen_id().

ключ -use_all_space максимально заполнит страницы данных и индексов, в результате чего БД по объему будет меньше чем обычно.

перевести БД в read-only режим и обратно без backup/restore можно утилитой gfix.
как в параметр передать несколько значений (where id in (aram)

Вообще то никак. В параметр передать можно только одно значение. Попытка передать строку со значениями, разделенными например ',' в параметр для числа (a id здесь число) будет обречено на провал, тем более что сервер и не догадывается, что ему пытаются в aram передать список, а не конкретное значение. Однако, решение данной проблемы возможно:

Ded рекомендует:

Вообще-то мой метод при работе с клиента прост - раз такой запрос не может быть параметрическим, то я и не использую параметры, а между close и open пересобираю текст запроса, вставляя в него требуемую строку :-) Вот если такое требуется внутри процедуры, где запрос не пересобрать (с появлением execute statement стало менее актуально, если этот запрос не внутри цикла, то можно и пересобрать), тогда делаю так. Собираю строку с параметрами вот в таком виде
'~12~23~267~675~'

и запрос пишу
Select тыры-пыры
From Table T
Where :ParamStr Containing '~'||T.ID||'~'

тильду в качестве разделителя списка выбрал потому, что этот символ имеет наименьшие шансы встретиться внутри ID если это строковое поле. Кстати, этот фокус порой выигрывает у IN по быстродействию.
После изменения вызывается старая процедура

(или - alter procedure "не работает")

Это стандартное поведение сервера, начиная с версии InterBase 5.5 (февраль 1999 года). Оно описано в документации, DataDef.pdf, раздел Altering and dropping procedures in use (страница 157).

До версии 5.5 модификация процедур и триггеров во время работы приводила к падениям сервера. Проблему было решено устранить путем запрета обновления кэша метаданных, если к изменяемой процедуре обращаются пользователи.
Например -
пользователь USR вызвал процедуру GETSOMETHING
программист в это же время делает alter procedure GETSOMETHING
сервер при alter меняет текст процедуры и ее blr в RDB$PROCEDURES, но не перегружает ее в кэше метаданных, потому что с этой процедурой работает пользователю USR
пользователь USR опять вызывает процедуру - срабатывает старый вариант процедуры, находящийся в кэше метаданных.
Пользователь USR отсоединяется.
Пользователь USR подсоединяется, вызывает GETSOMETHING - при этом если никто больше с этой процедурой не работал, код процедуры заново загружается в кэш метаданных, и выполняется новый вариант процедуры, модифицированный программистом в пункте 2.

Таким образом, чтобы загружался новый вариант процедуры, нужно отсоединить всех пользователей, которые вызывали эту процедуру хотя бы один раз, и подсоединить снова.

При однопользовательской работе разработчика такое поведение незаметно, разве только если разработчик не подсоединится к одной и той же БД из разных программ как 2 разных пользователя.

примечание: в classic кэш метаданных не обновляется. Для "обновления" процедур обязательно нужно переподсоединиться к серверу.

примечание: данное поведение не имеет ничего общего с версионностью метаданных таблиц, и не имеет ограничений на количество alter procedure/trigger.
можно ли отменить insert в триггере
  Ответить с цитированием
 
Время генерации страницы 0.12345 секунды с 10 запросами