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 представляется такой:
Если пункт 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 в нормальных условиях.