Версии ODS, переход между версиями InterBase и Firebird

KDV, 01.02.1998, последнее обновление – 23.12.2004, 03.04.2006, 20.09.2006, 12.03.2007, 20.01.2009, 10.08.2009, 04.09.2012, 04.02.2015, 15.09.2016.
 

Версии ODS

InterBase и Firebird для работы с базами данных от разных версий IB/FB использует понятие ODS (OnDisk Structure, или "формат базы данных"), номер которого меняется от версии к версии. Это позволяет серверу работать с базами данных от предыдущих версий IB (так называемый Y-valve, или "мост"), и одновременно с новыми.

Узнать версию ODS можно выполнив команду
gstat -h имя_файла_базы_данных
в выводе будет строка ODS version, сопровождаемая номером.
 
Примечание. Эту команду gstat выполняет считывая первую (нулевую) страницу базы данных самостоятельно, прямо из файла БД, не обращаясь к серверу. Если версия ODS будет "непонятна" конкретной версии gstat (от любой версии InterBase/Firebird), то gstat выдаст ошибку, из которой все равно будет видна версия ODS базы данных. В частности, gstat от InterBase 4 при обращении к базе данных от Firebird 2 выдал следующее:
Wrong ODS version, expected 8, encountered 32779?
что в переводе означает "Неверная версия ODS, ожидалась 8, обнаружено 32779".
(Для того, чтобы отличить базы Firebird 2.x от баз InterBase 7.x Firebird прибавляет "знак" (старший бит) к значению ODS. Т.е. в 16-ричном виде 32779 это будет 800B, что означает ODS 11.)
Или, например, тот же gstat выдает при обращении к базе от InterBase 2009:
Wrong ODS version, expected 8, encountered 13?
Исключение составляет ситуация, когда gstat не может найти interbase.msg/firebird.msg. В этом случае сообщение будет следующим:
can't format message 21:3 -- message file ...msg not found
В этом случае для исправления проблемы достаточно поместить требуемый файл в ожидаемый gstat-ом путь.

Дополнительные примеры:
Wrong ODS version, expected 8, encountered 32779? – InterBase 4.x пытается открыть базу от Firebird 2.x
Wrong ODS version, expected 8, encountered 13? – InterBase 4.x пытается открыть базу от IntrBase 2009
Wrong ODS version, expected 15, encountered 32779  InterBase XE/XE3 пытается открыть базу от Firebird 2.x
Wrong ODS version, expected 11, encountered 11 – Firebird 2.x пытается открыть базу от InterBase 7.x
Wrong ODS version, expected 11, encountered 15 – Firebird 2.x пытается открыть базу от InterBase XE/XE3
Внимание! Клиентская часть при несоответствии формата БД на сервере выдает сообщение чуть в другом формате, но аналогичное по смыслу.
Например, если базу от Firebird 2.x попытаться открыть сервером Firebird 1.5, будет выдана ошибка 
unsupported on-disk stucture for file ...; found 32779, support 10
Вот список основных ODS для каждой версии Interbase и Firebird:
 
Версия Основная версия ODS Может работать с ODS Примечания
InterBase 4.0/4.1 8.0 ...  
InterBase 4.2 8.2 8.2  
InterBase 5.0/5.1 9.0 8.2 2. Из-за отличий в версиях BLR, используемых IB 6 и IB 5.x, не рекомендуется полноценно работать с базой ODS 9 из IB 6 (особенно, если предполагается возврат на IB 5.6), в частности, модифицировать триггеры и процедуры. То же самое относится к рестору под 5.6 бэкапа, с БД которого успели поработать (меняли процедуры и триггеры) в 6.0 и выше.
InterBase 5.5 9.1 8.2
InterBase 5.6 9.1 8.2
InterBase 6.0 (прим. 1)
Firebird 1.0
Yaffil 1
10.0 9.0/9.1 (прим. 2) 1. Сюда же относятся InterBase 6.5, Firebird 1.0, Yaffil. Они могут добавлять незначительные изменения в отношении системных таблиц (например, дополнительные индексы), которые не влияют на совместимость между разными версиями серверов.
Firebird 1.5 10.1 (прим. 7) 9.0/9.1 (прим. 2), 10.0 7. ODS 10.1, созданная 64-разрядным FB 1.5 несовместима с обычной ODS 10.1. Поэтому открыть такую базу могут Firebird 1.5 и 2.x только 64-разрядные. В других номерах ODS как Firebird, так и InterBase, отличий по разрядности сервера нет.
InterBase 7.0 11.0 10.0  
InterBase 7.1 11.1 10.0  
InterBase 7.5 (прим. 3) 11.2 10.0 3. Перед установкой IB7.5 обязательно нужно сделать backup, даже если вы работаете на 7.0/7.1 с базой ODS 11.0/11.1. IB 7.5 автоматически обновит ODS до 11.2, что не гарантирует обратную работоспособность 7.0/7.1 с этой ODS. В ODS 11.2 как минимум поддерживаются индексы со специальным хранением null, новые конструкции SQL, и т. п. Подробнее см. документ.
Firebird 2.0 11.0 (прим. 4) 10.x 4. Firebird 2.0 имеет ODS 11.0, однако эта версия ODS не совпадает с ODS 11.x от InterBase 7.x. Firebird никакой версии не работает с базами формата InterBase ODS 11.x, и наоборот – никакая версия InterBase не поддерживает формат Firebird 2.0 ODS 11.0. В данном случае никаких опасений по поводу "порчи базы не тем сервером" нет.
Firebird 2.1 11.1 (прим. 4) 10.x, 11.0  
Firebird 2.5 11.2 (прим. 5) 10.x, 11.0 5. ODS 11.2 Firebird 2.5 несовместима с Firebird 2.1 и 2.0. То есть, базы от Firebird 2.5 не могут быть открыты Firebird версий 2.0 и 2.1.
Firebird 3.0 12.0 предыдущие не поддерживаются В Firebird 3.0 включен движок (engine12.dll) только для поддержки ODS 12. Предыдущие ODS не поддерживаются.
InterBase 2007 12.0 11.x (InterBase 7.x)  
InterBase 2009 13.1 12.0  
InterBase XE 15.0 (прим. 6) 13.1, 12, 11, 10 6. Где ODS 14? Никто не знает.
InterBase XE3 15.0 13.1  
InterBase XE7 16.0 15, 13 "Рабочая" версия ODS для InterBase XE7 может быть настроена в IBCONFIG. В этом случае restore и создание БД будут происходить в той ODS (13,15,16), которая указана в IBCONFIG.
! поддерживается ODS 13.2, которая несовместима с InterBase 2009. ODS 13.1 при первом коннекте принудительно обновляется до 13.2
Примечание. При backup в файл бэкапа пишется номер версии gbak для того, чтобы можно было произвести restore версией gbak не ниже текущей. При restore ODS базы данных будет определяться уже версией сервера, а не версией gbak, т. к. только сервер создает базу данных, а gbak при restore всего лишь ее наполняет метаданными и данными. Таким образом, если на сервере Firebird 1.5 сделать restore утилитой gbak от InterBase 7.1, база данных будет иметь формат ODS 10.1, а не 11.1.

При переходе с IB 7 на FB 1.5 или обратно, если использовалась только общая функциональность (IB 6, без специфики FB 1.5 или IB 7.x), достаточно сделать backup одним сервером и restore другим. Соответственно, бэкап произведенный на конкретной версии сервера, можно восстановить на сервере младшей версии, используя утилиту gbak от старшей версии. Например, БД создана или восстановлена в 6.0. Делается бэкап. Для его рестора на сервере 5.6 надо использовать gbak от 6.0. Нужно добавить, что смысл таких действий в большинстве случаев сомнителен.
Разница между ODS может быть как существенной, так и незначительной (подробно отличия ODS можно увидеть в файле jrd\ods.h исходных текстов и файлах ods*.gdl). Например, ODS 9.0 по сравнению с 8.x поддерживает декларативную ссылочную целостность, роли SQL, сборку мусора в индексах. А ODS 9.1 отличается от 9.0 только ускоренной работой с constraint (добавлен индекс на одну из системных таблиц).

"Мост" предназначен для поддержки версии ODS, меньшей текущей на 1. Например, IB 5.x работает с базами данных ODS 8.x. Базу данных с ODS 8.x можно "превратить" в базу данных с ODS 9.x только путем backup/restore.

Если версии 4.x и 5.x поддерживают разные ODS при помощи механизма Y-valve, т. е. когда для соответствующей ODS выбирается способ работы с данными, то версия 6.0 может работать только с ODS 10. Поэтому при переходе на 6.0 базы данных можно использовать только после backup в 4.x/5.x и restore в 6.0.
 
Примечание. Подробно по переходу на IB 6 см. документ.

Обновление ODS

Однако, младший номер ODS при переходе с версии на версию в InterBase может быть обновлен автоматически:
 
Версия IB Обновление ODS
4.2 8.0 -> 8.2
5.0 8.0 -> 8.2
5.1 8.0 -> 8.2
5.5 8.0 -> 8.2, 9.0->9.1
5.6 8.0 -> 8.2, 9.0->9.1
6.0 9.0 -> 9.1
7.1 11.0 -> 11.1
7.5 11.0/11.1 -> 11.2
XE7 13.1 -> 13.2
Примечание. Firebird 1.5 для базы ODS 10.0 обновит ее до 10.1. Одно время была ситуация, когда Firebird не мог обновить базу до ODS 10.1, если там уже был создан дополнительный индекс по одной из системных таблиц. Сейчас такой проблемы нет.
Это означает, что при переходе на IB, версия которой отличается от текущей младшим номером, возможна обратная несовместимость с базами данных. Например, Вы работаете с IB 4.0 (ODS 8.0), затем устанавливаете IB 4.2 или 5.x. При первом же обращении к базе данных ее ODS будет автоматически обновлен до 8.2. Если Вам чем-то не понравится IB 4.2 или 5.x, то после их деинсталляции и установки IB 4.0 может оказаться, что IB откажется от работы с новой ODS. Точно так же gbak не может восстановить резервную копию базы данных, если ее версия больше, чем версия gbak.
Абсолютно та же ситуация с InterBase XE7 с поддержкой ODS 13 от InterBase 2009. 2009 поддерживает ODS 13.1, а XE7 при первом же открытии такого файла БД делает апгрейд до 13.2, а 2009 такой формат файла БД не понимает.

ODS 10 совершенно несовместима с предыдущими ODS, т. к. в IB 6.0 введены новые типы данных.

Чтобы не попасть в "капкан" подобной ситуации, при любом переходе с версии на версию необходимо предварительно делать backup всех баз данных.

 

Переход между последними версиями InterBase и Firebird

Firebird 1.5 и InterBase 7.x (не говоря про более новые версии) уже достаточно сильно отличаются по функциональности. Поэтому смысл в таком переходе есть, если
  1. вы не пользовались специфической функциональностью Firebird 1.5 или InterBase 7.x
  2. вы пользовались специфической функциональностью Firebird 1.5 или InterBase 7.x, но готовы все переделать под новый сервер.
На сегодняшний момент для ряда баз это уже практически неосуществимая задача. И дальше, с появлением все новой функциональности в Firebird 2.x и InterBase 2007/2009/XE расхождения будут еще больше.

Первое, что нужно сделать, это извлечь метаданные из БД в скрипт и попробовать создать новую БД под новым сервером из этого скрипта (isql -x db.gdb, isql -i script.ddl). Так вы обнаружите все несоотвествия и несовместимости в метаданных.

Если все прошло нормально, можно делать backup/restore. В соответствии с изложенным в предыдущих разделах нужно
  • при переходе с Firebird на InterBase сделать бэкап утилитой gbak от InterBase,
  • при переходе с InterBase на Firebird сделать бэкап утилитой gbak от Firebird,
после чего нужно выполнить restore полученного backup под новым сервером.

Если backup/restore прошел, и создание метаданных БД из скрипта также прошло, то нужно быть готовым к несовместимости BLR. BLR – это псевдокод в виде которого хранятся объекты БД – процедуры, триггеры, view и т. п. При restore, разумеется, эти объекты не перекомпилируются. В Firebird и InterBase константы языка BLR могут не совпадать, даже при совершенно идентичном тексте SQL процедур, триггеров и view. Вероятность такого несовпадения мала, но ее не стоит исключать.

Если вы заметили, что процедура или триггер под новым сервером работает как то "не так" – перекомпилируйте этот объект.

Если backup/restore не проходит, тогда единственный путь – это
  1. создание БД из исправленного скрипта метаданных,
  2. перекачивание данных из исходной БД любыми доступными средствами.

Переход на версию «назад»

Замечание. Ни один из перечисленных способов не дает 100% гарантии успеха.
Если вы сделали backup баз данных перед переходом на новую версию IB, то никаких проблем с возвратом к предыдущей версии нет. Однако если это не так (backup нет), или по другим причинам, вернуть базы данных в предыдущий формат ODS все-таки возможно. Это делается при помощи двух компьютеров с серверами IB/FB разных версий, или на одном компьютере с поочередно запускаемыми версиями IB/FB (подробнее об этом – здесь).

Самый простой вариант уже изложен выше. Если вы не использовали никакой специфической функциональности сервера версии X, то вы можете легко перейти на версию X-1 следующим способом: 
  1. возьмите утилиту gbak от сервера версии X-1 и сделайте ею бэкап на сервере X,
  2. перенесите полученный бэкап на сервер X-1 и восстановите его.
Если бэкап в пункте 1 не проходит, можно попробовать другой способ: 
  1. нужно сделать backup на имеющемся сервере X (gbak-ом от X),
  2. нужно взять утилиту gbak сервера версии X,
  3. на сервере X-1 утилитой gbak от X восстановить базу.
Cервер версии X-1 при восстановлении создаст базу в своем родном формате, который, очевидно, вам и нужен.

При выполнении этих операций (бэкап или восстановление бэкапа) рекомендуется использовать формат команды 
gbak -b localhost:c:\dir\db.gdb ...
т. е. обращаться к серверу по tcp, т. к. локальный протокол может быть несовместим между серверами, а без указания localhost или бэкап, или восстановление не пройдет.

Процесс переноса базы с сервера X на X-1 пройдет успешно только при одном условии – метаданные базы данных, которой делается backup, не должны содержать никаких особенностей новой версии (то есть, должна быть гарантия, что с момента переноса данных с X-1 на X в базе не делалось никаких изменений процедур, триггеров, таблиц и т.п.). Например,
  • при переходе с 5.x на 4.2 в базе данных не должно быть определения ролей и декларативной ссылочной целостности
  • при переходе с InterBase 7.x на Firebird в базе не должно быть булевских столбцов (тип boolean IB 7.x)
  • при переходе с Firebird 1.5 на InterBase в базе не должен использоваться тип bigint, и расширения sql в процедурах и триггерах, не поддерживаемые InterBase
  • при переходе с Firebird 2.0 на Firebird 1.5 в базе не должна использоваться никакая новая функциональность FB 2. Например, индексы по символьным столбцам больше 252 символов, derived tables в запросах в процедурах, триггерах и view, и т.п.
  • переход с Firebird 2.5 на предыдущие версии при помощи gbak практически не возможен, т.к. в 2.5 изменилось именование классов безопасности, создаваемых Firebird.
  • и так далее.
Операцию можно выполнить или на одном компьютере, запуская сервера поочередно, или на разных компьютерах. В этом случае желательно, чтобы между серверами было сетевое соединение с максимальной пропускной способностью (100МБит), т. к. backup по сети выполняется намного дольше, чем backup на винчестер.

Если восстановление БД таким образом не прошло, остается единственный способ – извлечение метаданных в виде скрипта из исходной базы, затем создание базы из скрипта под сервером предыдущей версии, и копирование данных с одного сервера на другой (утилитой IBPump, например).
 
Примечание. Перенос баз данных диалекта 3 в диалект 1 возможен только через скрипт и копирование данных утилитой IBPump. В любом случае такая процедура требует тщательной проверки совместимости переносимых данных.