Восстановление Apache Derby Без Резервной Копии

Для собственного удовольствия у меня на персональном компьютере работает робот Википедии( счет1 , счет2 , источник ).

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

Данные собираются в базу данных, управляемую Apache Derby, и вместе с кешем база данных занимает около 50 ГБ.

И вот, в один прекрасный выходной, когда бот обрабатывал данные в 8 потоков на 4 процессорах, Abbyy Finereader узнала 14 том русского биографического словаря под редакцией А.

А.

Половцева, а оппоненты сделали свой ход в Civilization Age of Kings. появилось - синий экран смерти.

Давно не виделись, подумал я, перезагружая компьютер.

Причина в порядке - скорее всего аппаратные проблемы с видеоадаптером.

Но когда компьютер загрузился и я снова попытался запустить бота, произошло следующее:

ОШИБКА XSDG2: неверная контрольная сумма на странице.

А последняя резервная копия, как обычно, датирована мартом.

Потратив полчаса-час на исследование проблемы (читай: поиск в Google), я выяснил, что:

  • Утилит для восстановления данных нет. Никто.

    Используйте резервные копии – это единственный официальный способ.

  • Предлагаются патчи, позволяющие обойти проверку контрольной суммы конкретной страницы.

    Например, ДЕРБИ-1648

  • Наконец, есть способ просто игнорировать восстановление данных.

    Да, ваши глаза вас не обманывают – это выздоровление.

    Дело в том, что после некорректного завершения Apache Derby читает журнал транзакций и, как любая уважающая себя ACID-совместимая СУБД, пытается откатить незавершенные транзакции.

    У нее это просто не получается, поэтому она ругается.

Как сделать последнее? Просто удалите логи! Однако как IBM предупреждает нас (разработчик Cloudscape — того, что позже стало Derby):
Никогда не удаляйте и не манипулируйте *ЛЮБЫМИ* файлами в структуре каталогов базы данных Derby. Это приведет к повреждению базы данных.

Итак, что я делал в ночь с субботы на воскресенье?
  1. Я убедился, что на жестком диске места более чем в 3 раза больше, чем текущий размер базы данных.

  2. Я сделал резервную копию нерабочей базы данных.

    Лучше поздно, чем никогда.

  3. Помолившись Летающему Макаронному Монстру, я удалил все файлы из папки logs (саму папку надо оставить - без нее она не загрузится).

  4. Я зашёл в базу данных через SQuirreL SQL Client и убедился, что она работает.
Но это, конечно, еще не все.

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

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

Встроенный Apache Derby механизм резервного копирования-восстановления нам не поможет - он тупо копирует файлы данных, никак не проверив их структуру.

Однако в пакет входит интересная утилита под названием ij .

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

Нам понадобятся две такие функции из набора Вывоз ввоз :

  • SYSCS_UTIL.SYSCS_EXPORT_QUERY_LOBS_TO_EXTFILE
  • SYSCS_UTIL.SYSCS_IMPORT_TABLE_LOBS_FROM_EXTFILE
Эти функции экспортируют (и импортируют) данные в стандартный текстовый формат. Дополнительный префикс LOBS_FROM_EXTFILE указывает, что двоичные и большие текстовые поля будут сохранены в отдельный файл.

Это удобно, если вы хотите хотя бы взглянуть на данные на корректность.

Поэтому следующим шагом стал запуск ij.

java -cp "derby.jar;derbytools.jar" -Dij.maximumDisplayWidth=120 org.apache.derby.tools.ij

подключитесь к базе данных (не забудьте точку с запятой в конце команды для ij)

ij>connect secretarydb;

экспортировать все данные приложения (отдельные команды для каждой таблицы)

ij>CALL SYSCS_UTIL.SYSCS_EXPORT_TABLE_LOBS_TO_EXTFILE(null,'TABLENAME','c:\data\TABLENAME.del',null,null,'UTF-8', 'c:\data\TABLENAME.dat');

Кстати, команда "ПОКАЗАТЬ ТАБЛИЦЫ" в ij Есть .

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

Вы можете удалить лишние строки из .

del файла, если что-то окажется не так.

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

После завершения удалите базу данных.

Если да, то у нас есть резервная копия.

Дальше мне оставалось только снова запустить бота, и он, сделанный в спящем режиме, сам восстанавливал структуру таблицы при запуске.

После этого сразу останавливаем приложение и запускаем ij для импорта данных:

java -cp "derby.jar;derbytools.jar" -Dij.maximumDisplayWidth=120 org.apache.derby.tools.ij



ij>connect secretarydb;



ij>CALL SYSCS_UTIL.SYSCS_IMPORT_TABLE_LOBS_TO_EXTFILE(null,'TABLENAME','c:\data\TABLENAME.del',null,null,'UTF-8', 1);

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

Имя файла с LOB-данными указывать не нужно — ссылки на него есть в основном файле.

Вот и все.

Данные восстановлены.

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

Теги: #Apache Derby #Восстановление данных #транзакции #sql

Вместе с данным постом часто просматривают: