Поточная конвертация баз Firebird 2.5 в формат ODS12 (Firebird 3.0)

    У каждой версии Firebird есть собственная версия формата дисковых структур базы данных – O(n)D(isk)S(tructure). До версии 2.5 включительно, движок Firebird мог работать с ODS предыдущих версий, то есть базы от старых версий открывались новой версией и работали в режиме совместимости, но движок Firebird 3.0 работает только с БД в собственной ODS версии 12.0.

    Чтобы перейти на 3.0, базу данных от 2.5 необходимо преобразовывать в новый формат через backup/restore. Разумеется, мы предполагаем, что БД была предварительно подготовлена для конвертации — т.е. метаданные и запросы были проверены на совместимость с Firebird 3.0.

    Если следовать стандартному подходу, это означает, что нужно произвести бэкап на версии 2.5, затем установить 3.0 и сделать рестор. Такая процедура приемлема, если есть достаточно времени, но при миграции больших баз данных, или при одновременной миграции нескольких десятков БД, когда время поджимает, можно воспользоваться поточной конвертацией, которая на 30-40% быстрее. Как именно это сделать (под Windows и под Linux), читайте под катом.

    Общая идея состоит в том, что для ускорения мы воспользуемся конвейером:

    gbak -b … база25 stdout | gbak -c … stdin база30

    Gbak от 2.5 генерирует бэкап в линейном формате и направляет его в stdout, который тут же через stdin подхватывает gbak от 3.0 и создает новую БД.

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

    Ниже мы рассматриваем детали для Windows и Linux.

    Windows

    В случае Windows проще всего сделать полностью автономную сборку Firebird. Для этого берём embed-архив Firebird 2.5, переименовываем fbemded.dll в fbclient.dll, добавляем из архива «обычного» 2.5 утилиты gbak.exe и (необязательно) – isql.exe.

    Firebird 3.0 использует единую сборку и не требует никакой доработки.

    Самый минимальный вариант (не требующий установки рантайм-библиотек VS2008/VS2010 на целевой системе) содержит следующие файлы:

    25/gbak.exe
    25/fbclient.dll
    25/firebird.conf
    25/firebird.log
    25/firebird.msg
    25/ib_util.dll
    25/icudt30.dll
    25/icuin30.dll
    25/icuuc30.dll
    25/Microsoft.VC80.CRT.manifest
    25/msvcp80.dll
    25/msvcr80.dll
    
    30/fbclient.dll
    30/firebird.conf
    30/firebird.msg
    30/gbak.exe
    30/ib_util.dll
    30/icudt52.dll
    30/icudt52l.dat
    30/icuin52.dll
    30/icuuc52.dll
    30/msvcp100.dll
    30/msvcr100.dll
    30/intl/fbintl.conf
    30/intl/fbintl.dll
    30/plugins/engine12.dll

    Опытный администратор может заметить, что в 2.5 не включены файлы intl/fbintl.dll и intl/fbintl.conf. Это действительно так, поскольку gbak не использует чарсет коннекта и не конвертирует данные между чарсетами, но на «приемной» стороне Firebird 3.0 эти файлы необходимы при создании индексов.

    В firebird.conf Firebird 3.0 рекомендуется добавить:

    MaxUnflushedWrites = -1
    MaxUnflushedWriteTime = -1

    Также, желательно установить и разные значение IpcName для 2.5 и 3.0.

    При выборе значений других параметров firebird.conf исходим из простого соображения: на этапе переливки данных в одном процессе gbak работает 2.5, а в другом – 3.0, затем 2.5 завершает работу, а 3.0 начинает построение индексов.

    Чтобы ускорить этап построения индексов в 3.0, рекомендуется увеличить размер параметра TempCacheLimit до ~40% RAM (если это выделенный сервер, конечно).

    Например, если на сервере 16 Гб RAM, то можно поставить

    TempCacheLimit=6G

    Разумеется, такое значение можно ставить только у 64битного Firebird 3, поскольку любой 32-битный процесс не сможет аллокировать больше 2х гигабайт памяти.

    У 2.5 этот параметр менять не нужно – он и так не может быть больше 2х гигабайт, да и при бэкапе на скорость не влияет.

    Перед выполнением операции требуется проверить, что страничный кэш в заголовке базы данных установлен в 0 (команда gstat -h databasename, смотреть строку Page buffers).

    Если кэш задан явно в хидере БД, то он переопределяет значения из firebird.conf (и databases.conf в 3.0), и в случае неадекватно больших значений может привести к излишнему потреблению памяти и уходу в своп.

    Далее, копируем файлы на целевую систему.

    Конвертация проводится после остановки «системной» службы Firebird 2.5, в командной строке с повышением прав до локального администратора (пример):

    set ISC_USER=владелец
    "25/gbak" -z -b -g -v -st t -y 25.log база25 stdout|^
    "30/gbak" -z -c -v -st t -y 30.log stdin база30

    В этом примере используется «прямая косая» в кавычках (допустимый «unix-style»), а «шляпка» (символ «^») экранирует символ перевода строки, что удобно при наборе длинных команд. Опция -st(atus) появилась в Firebird 2.5.8 и позволяет записать в протокол данные о времени работы процесса gbak (подробности – в документации).

    Linux

    На Linux Firebird 3 зависит от библиотеки tommath. В CentOS (RHEL) эта библиотека находится в epel-репозитории, в Ubuntu (Debian) в – системном.

    Для CentOS требуется сначала подключить epel-репозиторий и только потом делать

    yum install libtommath

    Ubuntu не нужно подключать дополнительные репозитории, но в Ubuntu 16 и в Ubuntu 18 устанавливаются разные версии пакетов – libtommath0 и libtommath1, соответственно.

    Firebird 3.0 ищет tommath.so.0 и для Ubuntu 18 дополнительно требуется создать ссылку (symlink) c tommath.so.0 на tommath.so.1. Для этого сначала надо найти tommath.so.1.

    Искомый путь в Ubuntu – /usr/lib/x86_64-linux-gnu/, но в других Debian-based дистрибутивах может быть иначе.

    Вторая проблема связана с тем, что до Firebird 3.0.1, включительно, не было простого способа установить две разные версии сервера. Вариант «компилируем из исходников с нужным префиксом» мы не рассматриваем из-за его относительной трудоемкости.

    Для Firebird 3.0.2 и выше реализована сборка с –enable-binreloc и отдельная опция установщика (-path путь).

    Предполагая, что библиотека tommath и, при необходимости, симлинк для tommath.so.0 добавлены в систему, можно доустановить актуальный (на момент написания этой статьи) дистрибутив Firebird 3.0.4 в, например, /opt/fb3:

    ./install.sh -path /opt/fb3

    После этого можно останавливать системный сервис Firebird и запускать поточную конвертацию.

    При остановке Firebird надо учитывать, что процессы Firebid 2.5 в режиме Classic обычно запускает xinetd – поэтому требуется или запретить сервис firebird для xinetd или остановить xinetd полностью.

    В firebird.conf для 3.0 на Linux не нужно задавать MaxUnflushed-параметры (они работают только на Windows) и менять настройки Firebird 2.5.

    В линуксе локальный (файловый) доступ Firebird 2.5 не эквивалентен embeded-варианту под Windows – сервер 2.5 будет работать в процессе gbak (без сетевой части), но права доступа будут проверяться по базе пользователей, а значит, потребуется не только логин, но и пароль:

    export ISC_USER=username ISC_PASSWORD=password
    /opt/firebird/bin/gbak -b … база25 stdout\
    |/opt/fb3/bin/gbak -c … stdin база30

    После успешной конвертации надо удалить сначала «дополнительный» Firebird 3.0, затем «основной» Firebird 2.5 и уже после этого выполнить чистую установку Firebird 3.0 — причем лучше всего из штатного установщика tar.gz, а не через репозитории, т.к. версия в репозиториях может отставать.

    Также, после рестора БД на Linux и переустановки надо проверить, чтобы новая БД имела владельцем пользователя firebird.

    Если это не так, то надо будет исправить

    chown firebird.firebird database

    Итог

    Кроме экономии времени и места на диске у поточной конвертации есть ещё одно важное преимущество – преобразование базы делается без удаления существующего Firebird 2.5, что заметно упрощает откат при неудачной конвертации (чаще всего — из-за недостатка места или неожиданной перезагрузки во время процесса миграции).

    Экономия времени связана с тем, что «классическая» конвертация это «время бэкапа» плюс «время восстановления». Восстановление состоит из двух частей: чтение данных из файла бэкапа и построение индекса.

    При поточной конвертации суммарное время получается как «время бэкапа плюс пять-десять процентов» и «время построения индексов».

    Конкретные результаты зависят от структуры базы, но в среднем время восстановления примерно равно двойному времени бэкапа. Поэтому, если брать за единицу время бэкапа, то «классическая конвертация» — три единицы времени, поточная — две единицы времени. Дополнительно сократить время помогает увеличение TempCacheLimit.

    В целом, поточная конвертация на практике позволяет сэкономить 30-40% процентов от времени поочередного бэкапа и рестора.

    Вопросы?

    Пожалуйста, все вопросы пишите в комментариях, или направляйте автору методики и соавтору данной статьи — Василию Сидорову, ведущему системному инженеру компании «iBase», по адресу bs at ibase ru.

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

    Какой версией Firebird пользуетесь?

    Поделиться публикацией

    Похожие публикации

    Комментарии 3

      0
      Благодарю за статью, познавательно. Вопрос. Можно ли сделать конвертацию чарсета и данных базы? 1251 > utf8. Пока что знаю только такой путь: в IbExpert полный дамп базы в файл-скрипт с последующим восстановлением из скрипта. Вариант не нравится тем, что скорее всего займет заметное время, база около 11 Gb, Fb 2.5. Можно ли как-то это сделать подобным описанному способом? Спасибо заранее.
        0
        конвертацию «поточным» методом из одного чарсета в другой сделать нельзя.
        Да, сконвертировать чарсеты можно только так — создать базу из скрипта с новым чарсетом, и скопировать туда все данные из старой базы.
        Про utf8 написано тут — www.ibase.ru/unicode_faq
          0
          Понятно. Благодарю.

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