20.8.21

Повреждено - значит уничтожено

 Опять я про ремонт. Никак люди с битыми базами не могут понять, что "починить базу данных" - это не восстановить абсолютно всё. Это привести ее в рабочее состояние, не более того (а рабочее состояние - это прохождение штатных backup/restore).

Но те данные (записи), которые были повреждены - их восстановить невозможно, никак, абсолютно.
Например, у вас есть 5 печатных листов текста. И один лист потеряли (сгорел, в шреддере, и т.д.). Как вы "почините" потерянный лист? Ага, только набив этот текст заново! Причем, его же надо еще как-то помнить. А если не помните, то всё.

Тем не менее, в базах данных потерянную информацию восстановить можно, но косвенными способами (на всякий случай - мы таким не занимаемся, потому что не лезем в прикладную область).

Допустим, есть справочник компаний CLIENTS, и таблица заказов ORDERS. Если повреждена ORDERS, то можно перевбить пропавшие записи с бумажных или ЭДО документов.
А если повредилась таблица CLIENTS? Тут хуже. Потому что backup пройдет, а restore - нет. Т.е. restore пройдет, но при активации индекса по столбцу связи выдаст ошибку (что отсутствуют записи в CLIENTS, на которые есть ссылающиеся записи в ORDERS), индекс не будет построен, ограничение целостности не будет работать, и будут тормоза с запросами, которые использовали такой индекс раньше.

Как это победить? Для начала, нужно найти потерянные в CLIENTS записи. Например
SELECT C.ID, O.CL_ID, <другие нужные столбцы>
FROM ORDERS O LEFT JOIN CLIENTS C
ON O.CL_ID = C.ID
WHERE C.ID IS NULL

То есть - нам нужно вытащить ВСЕ записи из таблицы ORDERS, т.к. там есть заказы, для которых клиенты потеряны. И потом оставить только те, которых не нашлось в CLIENTS - WHERE C.ID IS NULL.
Поскольку индекс по FK (ORDERS.CL_ID) активирован быть не может, для ускорения можно создать просто индекс по этому столбцу вручную. А затем уже выполнить запрос.
В противном случае на больших объемах данных запрос будет выполняться крайне долго.

Что дальше? Дальше мы можем вручную создать недостающие записи в CLIENTS, с минимумом информации - достаточно заполнить только ID и те столбцы, которые not null. Правда, если записей больше 10-20, то вручную это делать уже проблематично, и придется как-то автоматизировать.
Например, вместо SELECT C.ID, O.CL_ID в запросе выше написать
SELECT 'INSERT INTO ORDERS (ID) VALUES ('||O.CL_ID||');'

Добавили записи, убрали лишний индекс по CL_ID, активировали индекс по FK (напомню, это просто - ALTER INDEX indexname ACTIVE). И дальше уже можно по печатным или ЭДО документам заполнять информацию по клиентам.

Долго, нудно? Да! Надо было чаще бэкапы делать.

23.10.20

Вы пока базу поремонтируйте, а мы с ней поработаем

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

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

Но увы, нет. Редко какая база (в смысле разработки и предметной области) позволяет "склеить" базу из двух - починенной и "рабочей". Можно даже сказать, что вообще никакая.

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

Так что, единственный вариант ремонта:

- останавливаем работу
- передаем базу в ремонт
- сидим ждем, пока починят
- получаем отремонтированное, продолжаем работать.

И тут, конечно, засада в том, что длительность ремонта неизвестна. Поэтому что?
Да, надо чаще делать бэкапы! :-) Вполне вероятно, что восстановиться из вчерашнего бэкапа и перевбить данные за день будет гораздо дешевле, чем тупо сидеть пару дней, пока базу починят (еще и с неизвестным результатом).

7.8.20

- А вы базы чините? - Ага...

 Да, с 2002 года у нас есть услуга платного ремонта баз данных СУБД Firebird и InterBase. В процессе ручного ремонта для облегчения наших усилий мы выпустили утилиту для ремонта этих БД, под названием FirstAid (для России и для всего мира). И она чинит примерно 70% наиболее частых повреждений (Direct). А если не чинит, то даже при самых сильных повреждениях можно экспортировать уцелевшее содержимое БД в новую БД (Extract).

Как и что делать, можно прочитать в документации (см. раздел documentation, слева). Также есть общее описание типов повреждений БД, и что можно сделать в этом случае штатными средствами Firebird и InterBase.

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

- здравствуйте! а вы базы чините?
- да, чиним
- ок, хорошо

Никакой более ценной информации из этого разговора практически никогда нельзя извлечь.

Всё равно требуется письмо на support@ibase.ru (или support@ib-aid.com), где будет перечислено:

- что за ошибка при соединении с БД, примерно в результате какого события она произошла
- размер базы данных, ОС, версия Firebird или InterBase
- лог диагностики из FirstAid (это бесплатно)

Если нам что-то будет неясно, мы уточним технические вопросы опять же, по email.

В общем, я думаю, вы поняли. Что звонить нам не надо. Да, мы чиним базы Firebird и InterBase. Точно. Конечно, можно и позвонить. Но вы ведь уже прочитали этот пост.