Комментарии по "невосстановимому backup"

KDV, 05.11.2003

Комментарии к
http://www.ibase.ru/devinfo/norestore.htm

(см. начиная с
" ...логические ограничения, нарушение которых приводит к..."

а) пункты 1 и 3, т.е. наличие null в добавленных столбцах not null. В отличие от check (дальше) указание not null находится прямо у стольбца в rdb$fields и rdb$relation_fields (RDB$NULL_FLAG).

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

Здесь надо чуть отвлечься, и отметить что backup-ов может быть 2:
первый игнорирует ошибки как сейчас, но допускает "щадящий" restore, т.е. независимо от типа "повреждений" БД позволяет ее восстановить.
И второй, который ни в коем случае не делает бэкап при наличии "ошибок".
Причем скорее всего, что обе реализации должны быть. Как для strong data checking так и для restore in any case (прошу прощения, что по английски).
Продолжаем.

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

Не упомянуто правильно, потому что ошибка конвертации будет показана именно на этапе backup. Т.е. сделать бэкап с неконвертируемыми данными не получится (как впрочем, не получится сделать некорректное преобразование через alter table. А если разработчик сам такое сделал путем прямой модификации системных таблиц, то он и виноват).

в) check constraints, наложенные на некорректные данные, пункты 2 и 4. Собственно, если возможность создать такой check constraint существует, то при restore надо все check constraints (rdb$check_constraints, и check в rdb$triggers) создавать в метаданных после восстановления данных. И только так. Это приведет к изменению формата backup, т.к. в текущем варианте последовательность сохранения данных совершенно однозначная, и данные восстанавливаются после восстановления всех метаданных. Необходимо отметить, что сейчас у gbak есть ключ -no_validity, который не восстанавливает check constraints.

При таком изменении в gbak мы получим ситуацию, когда данные, нарушающие check constraints, могут быть долго не обнаружены в БД. Поскольку обратная ситуация, т.е. появление данных, нарушающих check constraints, после создания check constraints возможна разве что при повреждении БД, то можно считать отсутствие проверок соответствия данных check constraints при backup/restore нормальным поведением сервера.

г) Primary, Unique и Foreign key, индексы вообще, пункты 5, 6 и 7. Никаких сложностей. Эти constraints контролируются индексами, которые создаются после восстановления данных из backup. Если индекс PK, FK, UNIQUE не смог "восстановиться", то он остается в состоянии rdb$index_inactive = 3. Основная проблема в том, что ошибка при создании индекса (нарушение уникальности, нехватка места в temp и т.п.) приводит к остановке процесса восстановления всех индексов. Т.е. при ошибке на первом индексе ни один больше не восстановится (и все индексы придется восстанавливать руками, меняя указанное значение с 3 или 1 на 0 прямо в rdb$indices). Поэтому предложение состоит в том, чтобы сделать сообщение об ошибке восстановления конкретного индекса не ERROR, а WARNING.

При этом часть систем может считать такую БД восстановленной успешно, а часть - нет, и потребует ручного вмешательства администратора. В любом случае, количество ручной работы по восстановлению индексов при warning будет минимизировано.

д) пункт 8 - относится к restore только метаданных. Это просто должно быть исправлено в gbak, без учета всех остальных пунктов.

е) вложенные вызовы процедур из процедур и триггеров, с несоответствием параметров.
Здесь удивляет скурпулезность ядра, которое не перекомпилирует текст процедур и триггеров при restore, но тем не менее проверяет соответствие blr и rdb$procedure_parameters. Опять же, как и для пункта "в", если ядро допускает такое "на ходу", то и restore должен производиться с игнорированием подобных "казусов".

Некоторые разработчики предлагают автоматизировать процесс backup добавляя туда контрольный restore.
На больших объемах это может стать неоправданным (по времени или расположению файлов backup и БД). Как раз для пунктов "д" и "е" имеет смысл выполнять контрольный restore метаданных, причем в начале процесса backup.

Т.е. пока, без автоматизации примерная последовательность backup с тестовым restore представляется такой:

  1. бэкап метаданных >gbak -b db.gdb db.gbk -m
  2. контрольный рестор метаданных >gbak -c db.gbk test.gdb
  3. если пункт 2 прошел успешно, то в базе нет явных проблем с метаданными ("д", "е" и др. варианты). test.gdb можно удалить.
  4. бэкап (без сборки мусора, макс. скорость) >gbak -b -g db.gdb db.gbk (ключи -v -y - по вкусу, желательно)
  5. контрольный рестор >gbak -c db.gbk test.gdb (ключи -v -y по вкусу, желательно)
  6. сравнение скриптов оригинальной БД и восстановленой в п.5 БД (через dbcomparer)

Если пункт 5 (и 6) прошел, то имеющися бэкап на 100% восстановим (также можно считать, что дефектного "железа" нет, т.е. оно не внесло искажений в backup/restore). При желании можно удалить db.gdb и переименовать temp.gdb. Сохранять в архив можно как db.gbk так и temp.gdb.

Учитывая будущие изменения в gbak данную схему можно изменить:

Жесткий контроль: backup с ключом, контролирующим not null и конвертацию данных. Если есть ошибки, то бэкап не пройдет. Т.е. если этап 4 выполняется в таком режиме, то в случае ошибки мы исключаем пункт 5 (не тратим на него время), и начинаем "чинить" имеющуюся базу данных до успешного выполнения пункта 4.

Отсутствие контроля: restore с ключом, игнорирующим not null и конвертацию данных (и все остальные ошибки по пунктам "д", "е". Итоговая БД в смысле логических ошибок будет идентична имеющейся БД. При соблюдении в gbak всех случаев контроля и не-контроля данных такой restore можно считать штатным в "аварийных" случаях, т.е. когда БД повреждена.

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