Утилита GBAK, Firebird и InterBase

KDV, iBase.ru, 27.11.2008, последнее обновление – 13.10.2011.
 

Содержание

 

Назначение

Утилита gbak, входящая в комплект любого дистрибутива СУБД Firebird и InterBase, является средством создания резервных копий баз данных и восстановления баз данных из резервных копий.

Термин "резервное копирование" имеет достаточно общий смысл, целью которого является получение копии базы данных, пригодной для архивирования. Например, "резервную копию" БД можно изготовить простым способом – скопировать базу данных, предварительно остановив Firebird/InterBase (иначе, при работающем сервере, копия будет являться "поврежденным файлом", т. к. копирование производится последовательно, а база данных – файл произвольного доступа). Если же нужно сделать резервную копию базы данных "на ходу", во время работы СУБД, то для этого и предназначен gbak.

Далее в статье будет рассматриваться только использование утилиты командной строки, т. к. она есть во всех дистрибутивах для всех платформ, и в отличие от интерактивных средств, использующих Services API LINK (например, IBExpert), позволяет автоматизировать процесс резервного копирования.
 

Создание резервных копий – backup

gbak является программой, которая подсоединяется к базе данных, стартует транзакцию snapshotLINK, и затем сохраняет в специальный файл метаданные (описания таблиц, процедур, триггеров и т. д.) и данные (запросами select * from tablename). Вы можете самостоятельно написать подобную программу, например, для экспорта данных из БД в какой-либо другой формат.

Благодаря тому, что считывание данных происходит в транзакции snapshot, gbak на протяжении процесса чтения данных "видит" неизменные данные благодаря версионностиLINK. То есть, во время работы gbak другие приложения могут работать с базой данных. Однако, те изменения, которые были произведены приложениями во время работы gbak, разумеется не будут сохранены в резервную копию БД.

Формат командной строки для создания резервной копии простой:
gbak <опции> <база> <резервная копия>

Основная опция при создании резервной копии -b (другие опции подробно описаны дальше). Причем опции могут быть указаны как в начале, так и в конце. Как правило, gbak при выполнении резервного копирования и восстановления требует указать имя и пароль пользователя. Это могут быть или SYSDBA, или имя владельца базы. Например:
gbak -b employee.fdb emp.fbk -user SYSDBA -pass masterke

Чтобы не засорять текст постоянными -user... -pass... я дальше в примерах не буду приводить их в командной строке. Если же вы предполагаете вызывать gbak несколько раз подряд в одном окне консоли или bat/cmd-файле, то можно установить переменные среды
SET ISC_USER=SYSDBA
SET ISC_PASSWORD=masterke
после чего в этом окне консоли или bat/cmd файле вводить опции -user и -password не потребуется.

Также для облегчения читаемости я рекомендую использовать следующий "формат" командной строки:
gbak -b [другие опции] <база> <резервная копия> [-v -y <имя файла>] -user ... -pass ...

То есть, "что делаем", "с какими параметрами", "база и копия", "полный вывод лога", "пользователь и пароль". Такой порядок в левой части, где концентрируется внимание, содержит ключевую информацию, а правая часть – содержит вторичную информацию. Разумеется, вы можете выбрать иной порядок следования параметров gbak, но далее в статье я буду придерживаться указанного порядка.

Если вы хотите потренироваться по мере чтения статьи, то я рекомендую вам взять employee.fdb (или employee.gdb) из папки установки Firebird (InterBase), и скопировать эту базу в каталог bin, рядом с gbak. Затем открыть окно консоли, и перейти в каталог bin. Предварительно, чтобы не мучиться со вводом, рекомендую employee.fdb переименовать в e.fdb.

Итак, выполняем командную строку:
gbak -b e.fdb e.fbk

Что-то произошло, т. к. на диске образовался e.fbk, но никаких сообщений выдано не было. gbak в таком режиме выводит только сообщения об ошибках, если таковые возникли. Впрочем, для систем с регулярным резервным копированием, а также когда backup выполняется долго, лучше сразу указать опцию полного вывода лога действий. Даже в случае появления ошибки контекст этой ошибки будет виден четче, и также будет видно что именно сервер успел поместить в резервную копию до ошибки. Повторяем команду с ключом -v:
gbak -b e.fdb e.fbk -v

Теперь видно, что делает gbak при -b. Правда, по умолчанию размер буфера консоли небольшой, и вы увидите только финальную часть лога. Чтобы лог можно было посмотреть полностью, придется еще раз повторить команду, только теперь уже с перенаправлением лога в файл:
gbak -b e.fdb e.fbk -v -y e_bak.txt

Теперь опять на экран ничего не выводится, зато можно посмотреть e_bak.txt и изучить его. Предоставляю вам сделать это самостоятельно. Кстати, если вы попытаетесь еще раз повторить такую же командную строку, то gbak выдаст ошибку.
 
Внимание! gbak при создании резервной копии уничтожит файл с таким же именем. Однако для ключа -y при указании вывода файла лога этот файл не перезаписывается.
Замечание. Параметр -v в справке, выдаваемой gbak, описан как -v[erify]. Это неверно, потому что опция gbak -v не имеет ничего общего с проверкой БД. Скорее, этот параметр должен расшифровываться как "verbose".

Имена файлов

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

Имя базы

Поскольку уже было сказано, что gbak это обычная программа, которая читает данные из БД, то сама база данных и сервер могут находиться где угодно. В примерах выше использован локальный коннект, подразумевающий, что gbak выполняется на сервере. Если бы мы запускали gbak с клиентской машины, и обращались к серверу, то тогда вместо
e.fdb
надо было бы писать
server:c:\Firebird\bin\e.fdb
то есть штатную строку коннекта с указанием сервера и пути к БД (или алиаса, если таковой сконфигурирован в aliases.conf для Firebird 1.5 и выше, или admin.ib для InterBase 7.x и выше). В нашем примере вместо server надо указать или имя вашего компьютера, или localhost, поскольку мы все делаем на одном компьютере.

Разумеется, gbak создавая резервную копию, будет создавать ее локально, т. е. на компьютере где находится gbak. И если сервер  это другой компьютер, то фактически вся база данных будет считана по сети. Не стоит делать резервные копии баз размером гигабайт и выше например через 100мбит сеть. Быстрее будет сделать резервную копию на сервере, а затем просто скопировать ее файл на другой компьютер (если это нужно).

Имя резервной копии

Абсолютно любое, включая любое расширение. Вы можете встретить bak, gbk, fbk, и так далее. Никаких ограничений в этом плане не накладывается. Имя резервной копии лучше формировать как имя базы и дату, причем дату лучше всего указывать в "японском" формате, в виде YYYYMMDD  так имена файлов будут корректно сортироваться при просмотре папки.

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

Имя файла лога

То же самое, что и для резервной копии, включая расширение. Расширение лога имеет смысл выбрать таким, чтобы по умолчанию файл открывался Блокнотом или программой, которой вы привыкли просматривать текстовые файлы. Если же задать расширение как .log, а ассоция с ним не назначена, то при попытке просмотра вы каждый раз будете мучиться выбирая подходящую программу в выдаваемом Windows списке.

Дополнительные параметры backup

Вот перечень опций командной строки gbak, которые используются при создании резервных копий БД (в квадратных скобках указаны символы, которые можно не указывать в командной строке):
  Опция Назначение
  -b[ackup_database] создать резервную копию
  -g[arbage_collect] отключить сборку мусора
  -co[nvert] конвертировать external table во внутренние таблицы БД
  -ig[nore] при работе с поврежденной БД
   -L[imbo] игнорировать изменения "застрявших" транзакций 2PC (указана прописная буква L, потому что в большинстве шрифтов на экране строчная буква l похожа на 1. Вы можете использовать строчный вариант)
  -m[etadata] сохранить только метаданные (без данных)
  -t[ransportable] для переноса БД между разными аппаратными платформами (по умолчанию)
  -nt формат резервной копии, непереносимой между аппаратными платформами
  -v вывод полного лога процесса backup
  -y <файл> сохранить вывод лога в файл
  -user <имя> имя пользователя, SYSDBA или владелец БД
  -pas[sword] пароль SYSDBA или владельца БД. Опция может быть сокращена до -pass
  -e[xpand] отключение сжатия данных при backup. По умолчанию резервная копия записывается в "сжатом" виде
  -ol[d_descriptions] для совместимости с InterBase 3.3. Атавизм
  -fa[ctor] n для ленточных устройств. Атавизм
  -z вывод версии сервера и gbak
Новая опция Firebird 2.1 -nodbtriggers отключает срабатывание триггеров уровня базы данных. Эту опцию может указать только SYSDBA или владелец БД
Новая опция InterBase 2007 -d создать online dump (инкрементный бэкап). Подробнее см. Update GuideLINK
Новая опция InterBase 2009 -encrypt <key> шифровать базу с существующим в базе ключом шифрования. Подробнее читайте Data Definition Guide, раздел Encrypting backup files.
Новая опция InterBase 2009 -sep указание System Encryption Password
Подробное описание каждого параметра:

-g

Самый важный параметр. Часто встречается его описание как "отключает сборку мусора", но если подробнее, то этот параметр запрещает серверу проверять читаемые записи на наличие мусорных, что ускоряет процесс бэкапа. Более подробно это описано в документе. Здесь я только подчеркну, что создание резервной копии должно выполняться максимально быстро, а соответственно лучше не загружать сервер в это время сборкой мусора. Поэтому рекомендую всегда использовать такое начало командной строки бэкапа
gbak -b -g ...

Если вы делаете бэкап в IBExpert, то включение опции -g производится отключением (!) галки на параметре Garbage collection (или Включить сборку мусора). Почему так сделано – не очень понятно, но такое "обратное" поведение присутствует во многих инструментах, аналогичных IBExpert-у. Возможно так случилось потому, что сам параметр командной строки называется -garbage_collect, в то же время он наоборот, не включает, а отключает сборку мусора в коннекте gbak.
Примечание. Разумеется, при backup никакой "мусор" никогда не попадает в файл backup, ни при каких условиях. Если это не очевидно, то прочитайте еще раз, что делает утилита gbak при backup. Если и там вы не увидели объяснения, то это значит, что вы не понимаете как сервер работает с транзакциямиLINK.

-t

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

transportable в данном случае означает, что полученный файл резервной копии можно восстановить на альтернативной аппаратной платформе, где порядок байт в целых числах отличается. То есть, например, между Intel и Sparc, или HP-UX и Intel, и так далее. Но между Windows и Linux (или другой ОС) на Intel файл резервной копии будет и так переносимым, даже при указании ключа -nt (non-transportable). Так что, про -t, как и про -nt можно забыть, и никогда не указывать их в командной строке gbak.

-e

InterBase был создан примерно в 1985-86 годах, а тогда жесткие диски были очень малого объема. Поэтому по умолчанию gbak -b производит некую легкую компрессию данных. Отключить ее можно параметром -expand. Я сделал тест бэкапа базы 2.6 гигабайт, и обнаружил, что вместо обычного 2.2 гигабайта (база только что после restore, поэтому разница между размером БД и бэкапом невелика, обычно она больше) файл резервной копии с параметром -expand стал 5.2 гигабайта. Провел еще тесты, с резервным копированием на другой диск. Получил ускорение с -expand на 5%. Визуально процессор загружен на те же самые 34-38%, что и без ключа -e. На restore, скорее всего, разницы вообще не будет заметно. Так что практическую полезность параметра -expand, учитывая сильное увеличение размера резервной копии, можно считать равной нулю.

-co

Если в базе данных созданы внешние таблицы (external tables), то при создании резервной копии они будут помещены внутрь бэкапа как обычные таблицы. Без параметра -co внешние таблицы в резервную копию не попадают.

Можно сказать, что -co нужен тогда, когда вам требуется для эксперимента "взять с собой" не только базу, но и внешние файлы. Правда, в зависимости от назначения эти файлы могут иметь разный размер, и может оказаться, что сами они будут больше чем база данных. Для обычного, регулярного backup, параметр -co не нужен.

-factor

В документации этот параметр указан как "uses blocking factor n for tape device". Что это такое – уже неизвестно, т. к. в документации по нынешним версиям InterBase описания этого параметра нет, да и на ленту уже мало кто делает резервные копии (разве что копии дисков целиком).

-ig

До InterBase 5 сервер использовал вычисление контрольных сумм страниц БД. С InterBase 5 эта функциональность была отключена, поскольку диски сами научились восстанавливать поврежденные блоки по контрольным суммам, и поврежденный блок либо восстанавливается автоматически и незаметно, либо не может быть восстановлен вообще.

Сейчас InterBase и Firebird вместо контрольной суммы записывают на страницу число "12345". Если произошло повреждение базы данных, и данные на страницах БД искажены (нули или другая произвольная информация), то сервер при чтении такой страницы будет выдавать ошибку контрольной суммы.

Параметр -ig позволяет игнорировать ошибки контрольных сумм страниц, и не останавливать резервное копирование из-за этих ошибок.

Поэтому, в обычной командной строке для создания резервной копии БД категорически не рекомендуется указывать параметр -ig! Если база данных вдруг окажется повреждена, то с этим параметром вы можете "не увидеть" повреждение. Так что, -ig для gbak используется только в крайнем случае – когда поврежденная база починена утилитой gfix, но обычный backup не проходит. Только тогда имеет смысл повторить бэкап с опцией -ig.

-m

Сохраняет только метаданные (описания таблиц, процедуры, триггеры и т. д.). Данные в резервную копию не сохраняются. Используется когда вам нужно сделать копию пустой БД.

Однако, при этом могут не сохраняться значения генераторов. В последних версиях Firebird и InterBase это исправлено, но если нет – при восстановлении такой копии вы можете получить "мусор" в значениях генераторов (не 0, а случайные значения). Проверьте вашу версию Firebird или InterBase на наличие или отсутствие данного бага.

-limbo

Не сохраняет в резервной копии БД версии записей, которые созданы транзакциями, находящимися в состоянии in limbo. Такое состояние может быть только у не завершившихся транзакций двухфазного коммита (2PC). Если приложения не используют двухфазный коммит, или вы не знаете, что это такое, то этот параметр вам никогда не понадобится.
 
Примечание. Если требуется сделать резервные копии сразу несколько баз, то нужно выполнить команду gbak -b для каждой базы данных отдельно, но ни в коем случае не указывать нечто вроде gbak -b *.gdb *.gbk. Шаблоны и маски в данном случае не работают.

-y <файл>

Выше уже были приведены примеры перенаправления вывода в файл этой командой, однако, если просто в окне cmd (Windows) эта команда работает нормально, то при ее использовании в bat/cmd командном файле ошибки могут не сохраняться в файл, указанный в опции -y. Вы можете отказаться от этой опции, используя перенаправление вывода самостоятельно, в соответствии с документом http://technet.microsoft.com/ru-ru/library/bb490982(en-us).aspx

Другие параметры gbak – InterBase 2007 и выше

В InterBase 2007 введена возможность создания резервных копий, аналогичная nbackup в Firebird 2. В то время как nbackup является в Firebird отдельной утилитой, функции, похожие на nbackup, в InterBase выполняет gbak. Вот краткое описание новых опций:
 
gbak -d <database> <dump_file>
выполнить онлайн-дамп базы данных <database> в файл <dump_file>. Результатом будет копия базы данных в файле <dump_file>. Эта база по умолчанию находится в состоянии read-only. Если <dump_file> уже существует, то в него будут перенесены изменения, произошедшие в базе данных с момента предыдущей операции дампа (gbak -d)
 
gbak -d -ov ...
перезаписать <dump_file> целиком, если он существует.

Подробнее о других опциях gbak (-archive_journals, -archive_database, -archive_recover, -archive_dumps) и новых функциях InterBase 2007 читайте в документеLINK.

Services API – backup

По умолчанию gbak "прокачивает" данные через себя, как изображено на картинке:


Однако, в InterBase 6 было "опубликовано" Services API для выполнения сервером по команде действий, аналогичных выполняемым утилитами командной строки gbak, gfix, gsec. "Опубликовано" потому, что это API присутствовало в InterBase 5, но было секретным, и никак не использовалось программами, сопровождающими IB.
 
Примечание. Services API – это, например, закладка компонент InterBase Admin в Delphi (компонент IBBackupServiceLINK, например), компоненты pF...Service в FIBPlus (pFIBBackupService), также, IBExpert выполняет backup/restore только при помощи Services API, и т. д. Грубо говоря, если приложение не вызывает gbak.exe, но может делать backup, restore, и другие подобные "серверные" действия, значит оно использует Services API. И gbak.exe тоже использует Services API, если указана опция -se (см. далее).
Теперь (c 2000 года, с момента выхода InterBase 6.0) InterBase и Firebird могут делать так:


gbak или программа, использующая Services API, отправляет серверу команду, а сервер ее выполняет сам. В этом случае программа, отдавшая команду, может получать лог выполнения от сервера и выдавать все что сообщит о процессе сервер.

Пример:
gbak -b -g -se server:service_mgr c:\db\e.fdb d:\bak\e.fbk ...

-se  – это и есть команда серверу, чтобы не gbak, а сам сервер выполнил резервное копирование.
 
server – имя компьютера, где находится сервер InterBase или Firebird (если на этом же, то можно указать localhost). server можно не указывать, если сервер "локальный", и работает локальный протокол:
gbak -b -g -se service_mgr c:\db\e.fdb d:\bak\e.fbk ...

:service_mgr – имя интерфейса Services API, оно обязательно, неизменно, и пока только одно. Может быть в дальнейшем появится что-то еще, но пока есть только то что есть.

Поскольку не gbak, а сам сервер теперь выполняет резервное копирование, то есть несколько требований:
  • пути к базам (или алиасы) должны быть указаны только серверные, как для базы так и для файла резервной копии. Имя сервера к имени БД добавлять не нужно, т. к. оно уже должно быть указано как опция команды -se
  • у сервера должны быть права на запись туда, куда сохраняется резервная копия. На Windows сервер по умолчанию стартует под учетной записью LocalSystem, которая не имеет и не может иметь прав на внешние ресурсы (например, шаренные папки). Поэтому, если вы хотите сохранять резервные копии БД на другой компьютер сразу, а не путем копирования получившегося на сервере файла backup – нужно создать пользователя (например firebird), дать этому пользователю права на папки установки сервера, папки с базами данных и папки с резервными копиями, и затем остановить сервер и запустить его указав в параметрах сервиса новое имя пользователя.
К слову, резервное копирование через Services API является самым быстрым, по сравнению с локальным протоколом или tcp (результаты тестирования).

Заключение по backup

Резервное копирование – "онлайновая" операция, т. е. может быть выполнена в любой момент, во время работы пользователей с БД. Эту операцию можно и нужно автоматизировать, сделав резервное копирование регулярным. Без резервных копий вы рискуете остаться ни с чем, если база данных окажется повреждена по какой-либо причине.

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

 

Восстановление базы данных из резервной копии – restore

Операция, обратная резервному копированию:
gbak -c e.fbk e.fdb

База e.fdb будет восстановлена из резервной копии e.fbk. Процесс восстановления базы данных из резервной копии происходит следующим образом:
  1. Cервер создает пустую базу данных e.fdb. Причем, создает ее в том формате баз данных, который является для него "родным". Пустая база данных будет содержать все таблицы rdb$ (пока пустые), и будет иметь ряд параметров, например, такие как размер страницы, forced write и т. д., которые или взяты из резервной копии, или установлены в командной строке gbak.
  2. Cервер считывает метаданные (описания таблиц и индексов, процедур) из резервной копии и переносит их в базу данных.
  3. Cервер считывает данные из резервной копии и переносит их в базу данных
  4. Cервер считывает остальные метаданные (триггеры, гранты, check constraints и т. п.) из резервной копии и переносит их в базу данных
  5. Cервер создает (активирует) все индексы таблиц (которые были активны в момент создания резервной копии)
То есть, восстановленная из резервной копии база данных будет на самом деле не копией старой базы, а совершенно новой базой данных, наполненной старыми данными.

Помните, что если вы делаете восстановление на новой версии сервера, например, резервную копию делали на Firebird 1.5 (формат БД ODS 10.1), а восстанавливаете на Firebird 2.1 (формат БД ODS 11.1), то база будет создана в формате, поддерживаемом по умолчанию Firebird 2.1, и Firebird 1.5 с этой базой работать не сможет.

Резервные копии, кстати, тоже имеют свой формат, и резервная копия БД, сделанная например в Firebird 2.1 утилитой gbak этой же версии, не может быть восстановлена утилитой gbak от Firebird 1.5. Подробнее варианты переноса резервных копий и баз между версиями серверов описаны в документе.
 
Примечание. Если вас интересует точная последовательность действий gbak при backup и restore, например, порядок сохранения и восстановления объектов метаданных, то вы можете обратиться к исходным текстам – backup.epp и restore.epp соответственно. По мере развития IB/FB и исправления ошибок порядок сохранения-восстановления некоторых объектов изменялся (например, udf стали идти в бэкапе "раньше" некоторых других объектов).
Примечание. Существует возможность при восстановлении создать многофайловую базу данных. Однако, такая функциональность была нужна когда были распространены файловые системы, не поддерживавшие файлы более 2-4 гигабайт, а также когда InterBase не поддерживал как базы так и бэкапы более 4-х гигабайт. В настоящее время нет никакого смысла создавать как многофайловые бэкапы, так и многофайловые базы данных, поэтому подобная функциональность в данной статье не описана.

Дополнительные параметры restore

  Опция Назначение
  -c[reate] создать (восстановить) базу данных из резервной копии
  -bu[ffers] n изменить (или указать новый) размер кэша БД. Принимается значение больше 0.
  -p[age_size] n указать новый размер страницы для базы данных
  -i[nactive] не активировать индексы
  -k[ill] не создавать (и удалить) имеющиеся у базы данных shadow
  -m[etadata] восстановить только метаданные (без данных)
  -use_[all_space] максимально заполнять страницы данных (для read-only баз). Обратного ключа нет.
  -mo[de] <режим> восстановить в режиме read_only или read_write (по умолчанию read_write)
  -o делать commit после восстановления каждой таблицы
  -no_validity не выполнять контроль данных (InterBase 6, Firebird, Yaffil)
  -va[lidate] выполнять контроль данных (InterBase 7.x, 2007, 2009), по умолчанию контроль не выполняется
  -user <имя> имя пользователя, SYSDBA или владельца БД
  -pas[sword] пароль пользователя
  -v полный вывод лога действий
  -y <файл> вывод лога в файл
Новая опция Firebird 2.1 -nodbtriggers отключает срабатывание триггеров уровня базы данных. Эту опцию может указать только SYSDBA или владелец БД
Дополнительные опции Firebird 2.5 для исправления кодировки метаданных – автоматизация действий, которые при переходе с предыдущих версий на Firebird 2.1 нужно выполнять вручнуюLINK. -fix_fss_d[ata] исправить кодировку данных
Обе опции -fix_* указываются ОДИН раз в том случае, если при восстановлении бэкапа возникает ошибка malformed string. При указании этих опций повторно при backup/restore база данных будет испорчена. -fix_fss_m[etadata] исправить кодировку метаданных, например,
-fix_fss_metadata win1251
Дополнительная опция InterBase 2007 -pr[eallocate] n Изменить или установить размер преаллокирования базы данных, где n – новое минимальное число страниц, из которых будет состоять файл базы данных.
! "Преаллокирование" на самом деле "добивает" базу данных до заданного количества страниц после выполнения restore, а не до заливки данных в БД.
Дополнительная опция InterBase 2009 -decrypt <key> расшифровать зашифрованный бэкап. Подробнее читайте Data Definition Guide, раздел Encrypting backup files.
Дополнительная опция InterBase 2009 -sep <password> указание System Encryption Password. Cм. статью о шифровании БДLINK.
Дополнительные опции InterBase XE -eua_user
-eua_password
имя и пароль пользователя БД, если включено Embedded User AuthentificationLINK
Что здесь отсутствует? Правильно, знакомый многим параметр -r. Параметр -r на самом деле не -r[estore], а -r[eplace], т.е. не "восстановить", а "заменить" имеющуюся базу данных. Т.е. если в предыдущем примере команды заменить -c на -r, то существующая база данных e.fdb будет молча удалена. Этого допускать нельзя, потому что по разным причинам восстановление из резервной копии может не состояться, и тогда вы останетесь без оригинальной базы данных и с невосстановимой резервной копией.

Интересно, что иногда у людей в командной строке восстановления БД из резервной копии можно встретить и такой оксюморон:
gbak -c -r e.fbk e.fdb

Причина написания такой командной строки кроется в неверном чтении документации по InterBase. Там указано
gbak {-c|-r} [options] source dbfile
Что означает – "или -c, или -r", но никак не оба вместе. Тем не менее, лучше такие неоднозначности не устраивать.

Кроме того, в Firebird 2.0 параметр -r сам по себе был фактически запрещен, т. к. "убиение" оригинальных баз данных при помощи -r имеет массовый характер. Теперь в Firebird 2.0 параметр -r просто не работает, и вместо него нужно использовать явно -rep (или -replace_database полным текстом), или -r o (-recreate_database overwrite).

Таким образом, если требуется сделать резервную копию базы данных и тут же восстановить базу из нее на том же сервере, нужно
  1. gbak -b -g e.fdb e.fbk
  2. переименовать e.fdb например в tmp.fdb
  3. gbak -c e.fbk e.fdb
Если восстановление прошло успешно, то tmp.fdb можно удалить. До этого момента tmp.fdb категорически удалять нельзя. (Есть вариации – можно восстановить не в e.fdb, а например в e1.fdb, после успешного восстановления удалить e.fdb, а e1.fdb переименовать в e.fbk).

Поборники параметра -r могут сказать, что они или выполняют пункт 2, или вместо пункта 2 копируют базу данных в другой файл (остановив сервер InterBase или Firebird, разумеется). На это могу сказать следующее – все равно использовать -r не надо. Во-первых, он несовместим с Firebird 2.0, и во-вторых, что будет, если переименование или копирование вдруг произойдет с ошибкой?

Теперь можно перейти к более подробному описанию параметров restore.

-bu n

Изменить размер кэша базы данных. По умолчанию кэш базы данных задан в файле конфигурации сервера (firebird.conf, ibconfig), и равен 2048 страниц. Это значение действует для всех баз данных, у которых размер кэша задан неявно. Если вы используете на сервере несколько баз данных, то может потребоваться указать для них разный размер кэша, в зависимости от назначения этих баз. Параметр -bu n позволяет при восстановлении базы данных задать или изменить этот размер. К сожалению, у gbak можно указать значение -bu только больше 0. Если вы обнаружили, что в бэкапе уже "зашито" значение кэша, то "сбросить" его при restore не получится. Для убирания размера кэша в БД придется использовать gfix.

Если размер кэша вообще задан в БД (а в большинстве случаев это не делают), то этот параметр используется обычно при переносе базы данных, например, со старого сервера на новый, или при переносе БД между архитектурами Classic и SuperServer.

Эквивалентно команде gfix -bu n.

-p n

Позволяет задать новый размер страницы базы данных. Это единственный способ, которым можно изменить размер страницы БД. На текущий момент можно сказать следующее – если вы посмотрели параметры БД через gstat -h, и увидели, что у базы данных размер страницы 1024 или 2048 байт – рекомендуется сделать backup и restore с указанием размера страницы 4096, 8192 или 16384 байт (если ваша версия сервера поддерживает страницы в 16к). Потому что даже небольшие базы данных с таким небольшим размером страницы имеют явно худшую производительность, чем базы со страницей 4 килобайта и выше.

Сервер сохраняет размер страницы БД при создании резервной копии, поэтому повторно указывать размер страницы при restore нет необходимости.

Не вставляйте этот параметр в "автоматизированную командную строку restore", потому что если вы захотите изменить размер страницы текущей БД вручную, то "автоматизированный restore" поменяет ее обратно.

-i

Не выполнять создание (активацию) индексов (последняя фаза restore). После восстановления базы данных все индексы в ней останутся отключены (неактивны). Фактически с такой базой данных работать нельзя, т. к. при отключенных индексах Primary key, Foreign key и Unique возможны нарушения целостности данных в таблицах (дублирование первичных ключей и т. д.).

Данный параметр имеет смысл использовать разве что в специфических целях – например, восстановить только данные из бэкапа за максимально быстрое время, или определить длительность создания всех индексов (замерить время gbak -c, затем замерить время gbak -c -i, после чего вычесть одно время из другого – получите длительность активации всех индексов), чтобы определить или текущую производительность каталога temp, или сравнить ее с явно заданным в конфигурации расположении temp на другом физическом диске.

Если вы восстановили бэкап с опцией -i, индексы можно активировать командой alter index nnn active (для каждого индекса).

-k

Не создавать shadow, если таковые были созданы в оригинальной базе данных. На самом деле этот параметр не только "не создает" shadow, но и еще удаляет существующие, например в варианте с backup/restore с промежуточным переименованием базы данных. Впрочем, поскольку использовать shadow (программный raid 1) сейчас нет смысла, то и параметр -k можно считать атавизмом.

Эквивалентно команде gfix -kill.

-m

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

-mode <режим>

По умолчанию база данных восстанавливается в режиме read_write. Однако, если вам нужно получить базу только для чтения, особенно для размещения ее на CD или DVD, то можно воспользоваться -mode read_only.

Эквивалентно команде gfix -mode read_write/read_only.

-use_

По умолчанию базы данных InterBase и Firebird резервируют примерно 30% пространства на страницах данных, для размещения версий при будущих вставках, удалениях или обновлениях записей. Если предполагается запись базы данных на CD или DVD, то лучше базу данных несколько "сжать", указав параметр -use_ при restore (одновременно указав -mode read_only).

Эквивалентно команде gfix -use full. Обратная команда (снятие режима максимального заполнения страниц) – gfix -use reserve.
 
Внимание! При помощи restore вы не можете указать -use reserve, такой опции у gbak при восстановлении нет ни у InterBase, ни у Firebird.

-o

Помогает при некоторых случаях "невосстановимого backup". Тут больше добавить нечего.

-n

Отключает проверку constraints, если при обычном восстановлении БД оказалось, что логическая целостность оригинальной БД была повреждена (например, из-за битого индекса PK возникли дубликаты первичного ключа).

Крайне не рекомендуется для использования в "командной строке автоматизированного restore".

-va

В InterBase 7.x, 2007 и 2009 при восстановлении БД из резервной копии параметр -n (см. выше) включен по умолчанию. Это опасно тем, что можно не заметить появление в базе данных нарушений целостности Primary key, Foreign key и Unique в случае повреждения оригинальной базы данных. Поэтому в данных версиях InterBase параметр -va рекомендуется использовать всегда, кроме случаев восстановления "невосстановимого backup".
 
Примечание. Если требуется восстановить сразу несколько баз из бэкапов, то нужно выполнить команду gbak -c для каждой базы данных отдельно, но ни в коем случае не указывать нечто вроде gbak -c *.gbk *.gdb. Шаблоны и маски в данном случае не работают.

-fix

Опции -fix_fss_metadata и -fix_fss_data у Firebird 2.5 предназначены для приведения чарсета метаданных (и данных), которые были записаны в некорректной кодировке. Например, при редактировании процедур или триггеров в код могли попасть комментарии или константы в кодировке none, в то время когда они на самом деле являются символами 1251.

Если при restore gbak выводит сообщение об ошибке
Malformed string
то нужно принудительно указать нужную кодировку при помощи указанных опций. После этого в столбцах Unicode данные будут записаны корректно.

gbak от Firebird 2.5 также может выдавать сообщение
gbak:Invalid metadata detected. Use -FIX_FSS_METADATA option.
что сигнализирует об аналогичной ситуации, и требует явного указания данной опции с нужной кодировкой.
 
Внимание! Указывать опции -fix... можно ТОЛЬКО ОДИН РАЗ! Если вы сделаете еще раз backup/restore этой же базы данных с этими опциями, то исходные тексты процедур и триггеров БУДУТ ИСПОРЧЕНЫ!

Другие параметры gbak – InterBase 2007 и выше

-preallocate n

весьма странная опция, учитывая то, что она "добивает" базу данных до указанного в n размера страниц, а не аллокирует сразу эти страницы в момент начала restore. Физически это выглядит следующим образом:
gbak -c -pr 1300000 db.gbk db.gdb...
  1. сначала пройдет restore
  2. в конце restore сервер добьет базу нужным числом страниц до заданного размера. Если размер страницы базы db.gdb был 4096 байт, то размер файла будет ровно 5324800000 байт (1.3 млн страниц умножить на 4096. то есть, к счастью, preallocate не плюсует размер преаллокирования к размеру БД).
Причем, с этого момента значение preallocate будет кочевать из базы в бэкап и обратно, до тех пор пока при очередном restore не будет сброшено опцией -pr 0.

Одновременно, если вы поменяете при restore размер страницы, автоматически изменится и значение preallocate, чтобы соблюсти заданный размер независимо от размера страницы.

Если вы делаете restore бэкапа рабочей базы себе на компьютер, то сначала посмотрите gstat -h db.gdb, нет-ли там опции preallocate. Если есть – при restore придется указать -pr 0, иначе сервер развернет базу у вас на компьютере в полный размер preallocate.

Services API – restore

Здесь все то же самое, что и при создании резервной копии:
gbak -c -se server:service_mgr d:\e.fbk c:\db\e.fdb

Восстановление (например, проверочное) на тот же самый диск, где находится резервная копия, не так опасно, как в случае backup (когда свободное место может кончиться, и резервная копия будет неполной, да еще и база данных может быть повреждена). Но разумеется имеет те же самые проблемы с производительностью, когда восстановление проводится на тот же самый физический диск (поочередные чтение и запись с разных участков диска). Поэтому при восстановлении базы данных из резевной копии рекомендуется использовать разные физические диски.

Ошибки при restore

Причины "невосстановимости" резервных копий подробно описаны в статье. Здесь я опишу в общих чертах причины и моменты, когда такие ошибки могут произойти. Если вернуться к описанию последовательности процесса restore, то можно сказать следующее:
  • на этапах 1 и 2 (создание БД и создание описаний таблиц и индексов) ошибки вряд ли могут произойти. Разве что если вы пытаетесь создать БД там, где это сделать невозможно – нет прав, read-only носитель и т. п.
  • на этапе 3 (заливка данных) могут быть ошибки, которые "чинятся" повтором restore с параметром -o
  • на этапе 4 (заливка процедур, триггеров и т. п.) могут быть ошибки, связанные с некорректным blr (двоичным кодом) процедур и триггеров. Текст процедур и триггеров в этот момент никакого значения не имеет, он даже может отсутствовать в оригинальной базе и резервной копии.
  • на этапе 5 (создание индексов) могут быть ошибки, связанные с нарушением целостности первичных, вторичных и уникальных ключей (повреждения индексов в базе). До Firebird 2.0 такие ошибки приводили к прекращению restore, и в базе оказывались неактивными все индексы, шедшие после "проблемного". Firebird 2.0 продолжает активирование индексов после такой ошибки.
Соответственно, при возникновении ошибки вы получаете "неполноценную" базу данных, в которой может быть часть данных, данные без триггеров, данные с процедурами и триггерами, но без части индексов.

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

Хуже, если резервная копия оказывается битой сама по себе. В данном случае сможет помочь только инструмент IBBackupSurgeon, который позволяет "вытащить" все что было в резервной копии, полностью или по частям, даже если резервная копия имеет повреждения "посередине".

Заключение по restore

Никогда не используйте параметр -r. Всегда используйте -v – это поможет вам определить в случае ошибки, что восстановилось из БД, а что нет. Если во время restore произошла ошибка, то база данных будет в состоянии shutdown, т. е. к ней сможет присоединиться только SYSDBA или владелец БД. Поэтому невозможность для обычных пользователей подсоединиться после restore может служить дополнительным сигналом, что восстановление не прошло нормально, если вы не проверяете логи restore.

Как правило, restore по времени занимает в 2-4 раза дольше, чем backup. Это не относится к восстановлению из резервных копий nbackup или online dumpLINK.
 

Замечание по Services API

Вы уже в курсе, что можно заставить сервер делать backup или restore, через Services API – компонентамиLINK или утилитой gbak с опцией -se.

Как показывают тесты, как минимум backup через Services API происходит быстрее, чем с использованием локального протокола или tcp. Однако, если потребуется прекратить процесс backup или restore, то
  • для gbak -b/-c достаточно принудительно снять (завершить) процесс gbak.exe, или если он запущен интерактивно, нажать в окне cmd Ctrl-C. Поскольку backup или restore выполняется не сервером, а утилитой gbak, этот процесс будет прекращен.
  • для backup и restore, выполняемых через Services API, это возможно только остановкой сервера, т. к. именно он выполняет этот процесс.
 

Автоматизация резервного копирования

Автоматизацию резервного копирования можно выполнить как самостоятельно, так и при помощи готовых инструментов. Например, как готовое решение можно использовать наш FBDataGuard Community Edition, который не только защищает базу данных от повреждений, но и может делать резервные копии по расписанию, тестовое восстановление, а также отправку уведомлений по email, и много других полезных вещей. Кроме него, разумеется, есть ряд других инструментов для автоматизации резервного копирования (только), но здесь мы их рассматривать не будем.

Что нужно помнить при самостоятельной автоматизации резервного копирования, производимой скриптами, написанными вручную
  1. команда gbak -b database.gdb database.gbk сотрет имеющуюся резервную копию с именем database.gbk
  2. не рекомендуется сохранять резервную копию на тот же самый логический диск, где находится база данных. Исключением можно считать одинокий клиентский компьютер, у которого есть только один диск C:.
Итак, у нас есть утилита командной строки gbak, и средства операционной системы для периодического выполнения команд – в Windows это AT или "планировщик заданий", в Unix – cron. Вот пример использования at в Windows:

Создаем файл backup.cmd. В файле должна быть одна команда создания резервной копии БД, возможно с параметром, указывающим некое число или день.
@echo off
set DOW=%1
del d:\backup\data%DOW%.log
c:\interbase\bin\gbak -b -g -user sysdba -pass masterkey localhost:c:\db\data.gdb
d:\backup\data%DOW%.gbk -v -y d:\backup\data%DOW%.log

Здесь всего три строки – последние "две" на самом деле одна строка, здесь разбита на две части для облегчения читаемости. Полные пути прописаны для того, чтобы backup.cmd можно было вызвать из любого каталога.

Если мы вызовем командный файл как
backup.cmd 1
то в результате в каталоге d:\backup будет создана резервная копия data1.gbk и лог data1.log.

Теперь автоматизируем вызов at. Можно открыть окно командной строки (Пуск, выполнить, cmd), а можно открыть в Панели управления окно планировщика задач и задать нужные параметры интерактивно. Я приведу текст командного файла conf_at.cmd, который автоматически задает для AT создание резервных копий каждый день недели:
at %1 /every:M c:\backup.cmd Mon
at %1 /every:T c:\backup.cmd Tue
at %1 /every:W c:\backup.cmd Wed
at %1 /every:Th c:\backup.cmd Thu
at %1 /every:F c:\backup.cmd Fri
at %1 /every:S c:\backup.cmd Sat
at %1 /every:Su c:\backup.cmd Sun

Теперь можно вызвать этот командный файл как
conf_at 03:00

В результате каждый день недели ровно в 3 часа ночи at будет запускать backup.cmd с соответствующим параметром. И мы в каталоге d:\backup получим т. н. "револьверный" бэкап, то есть по одной резервной копии на каждый день недели, которые будут перезаписываться каждый день.

Имена резервных копий будут dataMon.gbk, dataTue.gbk и т. п., что не совсем удобно при просмотре каталога. Вместо Mon, Tue и так далее можно задать номера дней 1, 2, 3..., только главное не забыть, какой день недели у вас соответствует цифре 1.

Это самый примитивный вариант, который не обрабатывает ошибки при выполнении резервного копирования. Если вы не будете проверять логи бэкапа, то может оказаться что все резервные копии "дефективные". Поэтому нужно не только регулярно проверять логи, но и периодически делать тестовое восстановление например из самой последней резервной копии.

Если backup делается на другой компьютер, то нужно задавать команды AT от имени пользователя, который имеет право доступа к разделяемой папке на этом компьютере. Также можно добавить обработку ошибок в backup.cmd, даже с отправкой email в случае ошибки, но это выходит за рамки статьи.

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

Автоматизированное восстановление

На самом деле зло. Что, если автоматический бэкап завершился с ошибкой? Что будет, если при автоматизированном восстановлении возникнет ошибка?

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

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

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

Есть вопросы по статье? Присылайте на support@ibase.ru.


Запрещается перепечатка, перевод и копирование. Разрешается частичное цитирование с обязательной ссылкой на источник www.ibase.ru/gbak/