Форумы

Серверы Counter-Strike :: Форумы :: Документация :: Databases
 
Как починить базу данных Interbase
Модераторы: kapitowka, A1exseder, McNamara, HuKuToC, Jake_One, Meranpocynep6om, Chaos2Order, FizZ
Автор Добавил
kapitowka
06.02.2007, 18:36
FreeBSD The Power To Serve

статус Skype
STEAM_0:0:34602107

[RAT]


ID пользователя #1
Зарегистрирован: 01.01.1970, 03:00

Сообщений: 3361
Отблагодарен: 255 раза в 192 сообщениях
Репутация: 64
Репутация темы: 0 из 0 голосов

Причины повреждений баз данных,
Как починить базу данных Interbase или Firebird


KDV, 03.09.2002
исправления и дополнения:
25.01.2003, 06.02.2003, 15.04.2003, 16.05.2003, 02.09.2003, 26.11.2003, 03.02.2004, 06.09.2004, 17.02.2005
Содержание:

если вам надо срочно починить БД, то можете сразу перейти к ремонту БД.
Введение
Повреждения баз данных
отключение питания сервера
дефекты оборудования
память
диски
контроллеры
другие программы
сбои самого сервера
остановка во время сборки мусора
повреждения индексов
повреждения таблиц
Ремонт БД
Невосстанавливаемый backup
добавление столбцов not null
изменение типа столбца
конфликт данных и check constraint
процедуры и триггеры
повреждения системных таблиц
проблемы оборудования
Дополнительные способы ремонта БД
Перевод документа Database Validation and Repair
Заключение

Первый закон Чизхолма: Все, что может испортиться, портится.
Следствие: Все, что не может испортиться, портится тоже.
Введение

На эту тему можно было бы процитировать половину законов Мэрфи. Вместо этого я процитирую начало статьи в журнале Intelligent Enterprise

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

Когда я читал эту статью, меня больше всего потрясло именно второе предложение в этом абзаце. К сожалению, это грубая правда жизни. И здесь под "предупредительными мерами" ни в коем случае нельзя понимать "покупку техники brand-name". Как показала дискуссия в конференции epsylon.public.interbase, "брэнды" тоже ломаются, иногда даже чаще чем "самосборные машины". Поэтому "предупредительные меры" - это не только качественное "железо", но и планирование резервного копирования данных.

примечание: планирование-планированием, но вот еще одна цитата, уже из письма:
"... днем сдох IBM-ер у моих "ну очень уважаемых клиентов", а вместе с ним и БД акционерок и акционеров, с общим объемом уставных фондов около полуярда гривень (около 100 млн вечно-зеленых гульденов). Резервация ее делалась на RW-диск, отформатированный под UDF. Но кто-то (никто не признался) вставил вместо него неотформатированную RW. И так она пролежала там на протяжении последнего месяца. Как раз в октябре/ноябре у них шел сплошной поток обновлений в БД...."

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

Обычно при сбое базы данных ее можно починить утилитой gfix. Однако, иногда этот инструмент не помогает. В таких случаях нужно обратиться в конференцию, где попытаются помочь. В случае больших баз данных нужно быть готовым при починке полагаться только на себя, поскольку вряд ли получится отправить ~>1Гб базу (имеется в виду размер архива - zip или rar -, конечно) данных специалистам по email или на ftp. И нужно знать, что бывают случаи, когда базу данных восстановить не удастся никаким образом. Поэтому никогда не забывайте своевременно делать backup, а также проводить "контрольный" restore! (разумеется, никогда нельзя делать restore на место оригинальной базы данных, т.е. с ключом -r. Вы рискуете остаться без базы данных).

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

Если gfix не чинит базу данных, то в 70% случаев простых повреждений может помочь платная утилита IBFirstAid Ambulance. Для оценки повреждений БД имеет смысл сначала воспользоваться IBFirstAid Diagnostician и прислать лог (в zip) на support@ibase.ru, т.к. может оказаться, что ваш случай попадает в худшие 30%. В любом случае не стоит надеяться на появление инструмента, который из любой самой убитой базы данных сможет вытащить ваши данные.
Если база убита, а есть только backup, и он тоже поврежден, или по иным причинам нужно извлечь из backup только часть данных - к вашим услугам инструмент IBBackupSurgeon. (IBFirstAid Ambulance и IBBackupSurgeon - платные. Их можно купить).

примечание: чаще всего обращения о ремонте БД содержат не абстрактную просьбу "починить БД", а желание вытащить из поврежденной БД какие то жизненно-важные данные. Как раз этот случай зачастую требует именно ручного ремонта, поскольку автоматизируемый ремонт как gfix так и Ambulance старается отремонтировать БД для 100% возможности ее бэкапа, но не факт что сделано это будет с максимальной сохранностью данных (см. Ремонт БД, примечание к пункту 5).

примечание: исследовать структуру БД самостоятельно можно при помощи утилиты IBSurgeon Viewer.
Повреждения базы данных

Существует несколько причин, при которых база данных может оказаться поврежденной. Здесь перечислены наиболее характерные.
Отключение питания сервера

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

InterBase имеет два режима записи страниц - синхронный и асинхронный. Для всех версий до 6.0 создаваемые базы данных имели по умолчанию синхронный режим (Firebird v1.0 также имеет этот режим включенным по умолчанию). Для изменения режима можно воспользоваться утилитой gfix:

Включение сихнронного режима
gfix -write sync database.gdb

Включение асинхронного режима:
gfix -write async database.gdb

Синхронная запись означает, что измененные страницы базы данных не будут кэшироваться операционной системой, а будут записываться непосредственно на диск при выталкивании страниц из кэша на запись (на Windows это в буквальном смысле отсутствие флага lazy write при открытии файла БД).

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

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

Однако, на Windows было обнаружено, что если у базы данных установлено Forced Write = Off, то при определенных условиях измененные страницы БД могли неделями не попадать в БД, и оставаться в кэше операционной системы. При этом, в случае сбоя сервера (или отключения питания), пропадало огромное количество изменений в БД (а база могла выглядеть вообще неповрежденной). То есть, БД как бы оказывалась "неизменяемой" в течение длительного времени. Для исключения данной проблемы в Firebird 1.5 были введены дополнительные параметры для принудительного сброса кэша операционной системы при ForcedWrite=Off (см. параметры MaxUnflushedWrites и MaxUnflushedWriteTime в firebird.conf).

примечание: на современных дисковых системах включение Forced Write практически не влияет на производительность. Это заметно разве что на desktop-системах с IDE-дисками (старыми). Хотя вообще кэширование записи операционной системой дает выигрыш в производительности при массовых обновлениях данных.
Дефекты оборудования
Память

Самый частый дефект за последние полтора года - сбои памяти (RAM) (случаи такого рода сильно сократились в 2005 году). Очевидно, при использовании серверов "своей сборки" приобретается память подешевле, что приводит к соответствующим результатам. Желательно для сервера приобретать и материнскую плату и память с поддержкой ECC.

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

Сбои памяти еще плохи тем, что в этом случае поврежденными как правило оказываются и база данных и ее shadow, если shadow используется в качестве "быстрой резервной копии" (т.к. запись на диск идет из одних и тех же участков памяти).
Диски

Упоминавшиеся выше контрольные суммы страниц данных были исключены в сервере IB 5.0 не зря. Дело в том, что эти контрольные суммы фактически дублировали контроль данных, который должен производиться дисковым накопителем. Раньше, лет 10-15 назад, bad-блоки появлялись часто, и существовали специальные утилиты для их исправления. Сейчас контроль ошибок не только может исправить данные на поврежденном блоке самостоятельно, но и прозрачно сохранит блок в рабочем месте диска, а плохой блок пометит к исключению из дальнейшего использования. Грубо говоря, нынешние диски либо работают, либо не работают целиком.
Контроллеры

Здесь можно отметить только то, что при сбое в работе контроллера некорректная информация может быть записана на все носители, которые подключены к этому контроллеру. Именно поэтому при организации shadow рекомендуется располагать ее на винчестере, подключенном к другому контроллеру.
Другие программы

Interbase, Firebird или Yaffil не работают с операционной системой на "внутреннем" уровне. Это обычное приложение, которое никогда не может вызвать сбой типа известного "синего экрана" в Windows NT. Поэтому если подобный сбой ОС произошел, в этом скорее виноваты некорректно работающие драйверы, другие программы или само оборудование (очень часто в "синем экране" виноваты драйвера видео).

примечание: в W2K по умолчанию при сбое ОС происходит рестарт системы. Если хотите видеть, что система зависла, в My Computer/Properties, Advanced, Startup and Recovery уберите чекбокс Automatically reboot.

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

Разумеется, Interbase (Firebird, Yaffil) как и любое другое ПО не является идеальной программой. Идеальной, конечно, в смысле отсутствия ошибок. Если "железо" работает нормально, сервер может сам "сломаться" и либо просто перестать работать, либо испортить базу данных.

Конкретный случай последних 1.5-2-х лет - превышение размера в 4 гигабайта файлом базы данных. Раньше, и в том числе в 5.x, код сервера содержал вызов обычной функции позиционирования по файлу БД (seek), которая не могла адресовать более 4-гигабайт (в те далекие времена просто не было файловых систем, которые поддерживали файлы больше 4-х гигабайт). Когда в функцию передавалось такое большое число, оно обрезалось по старшим разрядам. Происходила такая ситуация при операции расширения файла БД, т.е. при записи новых страниц, а следовательно файл БД оказывался "затертым" новой информации с самого начала, т.е. с нулевой страницы (страница заголовка БД). Если новых страниц к записи было много, то уничтожалась начальная часть БД, где как правило содержатся системные таблицы, страницы информации о транзакциях и т.п.

причем борьба с пресловутым размером файла в 4 гигабайта дольше всего велась на Linux, что связано не только с кодом СУБД, но и с поддержкой файлов таких размеров самой операционной системой и ее файловыми системами. Firebird исправил эту проблему окончательно только в версии 1.0.2, причем все равно пока выпускаются как обычные версии Classic, так и т.н. с 64bit-IO. Borland также не миновала чаша сия, и для IB 7 выпущен патч (7.0.1). Firebird для FreeBSD до сих пор не поддерживает файлы такой длины
На Windows в IB7, Firebird и Yaffil этой проблемы уже нет, т.е. файл БД может иметь размер и 10, и 20 и больше гигабайт.
В любом случае, при работе на Unix или Windows следует внимательно изучить возможности ядра и конкретной (используемой) файловой системы - способны ли они работать с файлами больше 4-х гигабайт, а также проверить версию IB/FB/YA, чтобы быть уверенным в корректной работе с такими файлами, или наоборот, сразу предусмотреть разбиение БД на многофайловую, например "кусками" по 2 гигабайта.
В отношении файловых систем Windows известна следующая особенность: на FAT32 поддерживаются файлы размером не более 4 гигабайт (чаще всего указанное повреждение БД и происходит при использовании этой, фактически уже устаревшей, файловой системы). Допустим, размер вашей БД достиг 3-х гигабайт, и вы хотите перенести ее на NTFS, чтобы избежать ограничения в 4 Гб. Проблема в том, что с FAT32 на NTFS скопируется только 2 гигабайта из 3-х, из-за особенностей Windows. Это еще раз подчеркивает необходимость знания ограничений используемых файловых систем и их взаимодействия на одном компьютере.

В остальных случаях, одной из характерных ошибок, которую наблюдают разработчики, является

"cannot continue after bugcheck(xxx)"

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

замечание: сообщение bugcheck не имеет ничего общего с ошибками (багами, bugs), обнаруживаемыми и регулярно исправляемыми в коде сервера.
Остановка во время сборки мусора

Когда исходный код Interbase был опубликован, оказалась выявлена еще одна неприятная особенность, которая может привести к серьезным повреждениям базы данных. Если во время принудительного завершения работы сервера (gfix -shut ...) были активные подключения и сервер занимался сборкой мусора (работал sweep thread), то база данных может быть повреждена (и чаще всего это так и происходит).

Уменьшить вероятность таких повреждений можно только отключив автоматическую сборку мусора (gfix bd.gdb -housekeeping 0), а в случае принудительной сборки мусора (gfix -sweep) предварительно делать "быстрый" backup (gbak с ключом -g, то есть без сборки мусора), чтобы резервная копия базы данных оказалась самой свежей в случае сбоя и повреждения БД.

В Yaffil эта проблема исправлена.
Повреждения индексов

Повреждения индексов могут происходить как по всем вышеперечисленным причинам, так и из-за ряда багов сервера при работе с индексами (исправлены в Firebird 1.5, Yaffil).

Поскольку индексы не являются 100% необходимым видом объектов для функционирования базы данных, их повреждения обнаруживаются значительно позже (если администратор смотрит в interbase.log), чем повреждения других объектов БД (например, данных таблиц). И клиентские приложения могут продолжать функционировать в такой ситуации как и прежде.
Однако, при повреждении индексов возможно искажение данных, получаемых приложениями. Если в индексе повреждено несколько ключей, и сервер не выдал сообщения об ошибке при выполнении запроса, использующего такой индекс, в результат запроса не попадут записи, на которые ссылаются те самые поврежденные ключи. То есть, часть записей может "пропасть". Обнаружить разницу в выдаваемом количестве записей можно только используя запросы с полным перебором записей
SELECT * FROM TABLE

и с перебором по индексу
SELECT * FROM TABLE
WHERE FIELD > 0

где FIELD - столбец, по которому есть возможно поврежденный индекс, а > 0 - условие, которое однозначно будет выбирать все записи.
(разумеется, лучше этого не делать, а при подозрении на "пропадание записей" сразу посмотреть в interbase.log, перестроить те индексы, о повреждениях которых там сообщается.
В interbase.log пишутся только порядковые номера индексов (а не их имена) для конкретных таблиц, как это и указано в rdb$indices).

Процесс backup поврежденные или неповрежденные индексы (за исключением повреждений индексов по системным таблицам) не интересуют, т.к. индексы в backup хранятся только в виде описания в системных таблицах (restore создает индексы по этим описаниям в самом конце процесса restore). Backup считывает записи в натуральном порядке и индексы не использует, поэтому все существующие (committed) записи обязательно попадут в backup. Однако, если поврежден уникальный индекс, то в определенных условиях существует вероятность повторной вставки записи в таблицу с уже существующим (уникальным) значением столбца. Эта ситуация может привести к невосстановимому backup, т.е. процесс restore остановится в момент создания уникального индекса, обнаружив дубликат уникального значения в восстановленных записях. Но такая проблема также не является катастрофической - процесс создания индексов выполняется самым последним, т.е. после того как абсолютно все объекты БД уже восстановлены в базе данных процессом restore. Если вдруг обнаружена проблема неуникальных данных при создании индекса, можно попробовать найти такую запись (и затем удалить лишнюю) запросом
SELECT ID, COUNT(*) FROM TABLE
GROUP BY ID
HAVING (COUNT(*)) > 1

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

После этого можно активировать индексы, которые не были восстановлены (установив RDB$INDICES.RDB$INACTIVE в 0, там, где этот столбец не 0).
Повреждения таблиц

Нормальная база данных - это не набор отдельных таблиц. Таблицы между собой могут быть достаточно сильно взаимосвязаны, вплоть до циклических ссылок. Поэтому даже один и тот же тип и объем повреждения может иметь разные последствия, в зависимости от того, с какой таблицей это произошло. Типичный пример: таблица CLIENTS - справочная, а ORDERS - оперативная. Если пропадет часть записей из ORDERS, то после починки БД будет нормально функционировать. Если же будет повреждена CLIENTS, то после починки в ORDERS будут записи, ссылающиеся на несуществующих клиентов. Таким образом БД вроде бы будет отремонтирована, но логическая целостность данных будет нарушена. Бороться с этой ситуацией никак невозможно, разве что чаще делая backup (поскольку справочники меняются реже, чем оперативные данные).

Подобная ситуация (с повреждением master-таблицы) может возникнуть даже в том случае, если все записи пакета master-detail вставляются в одной транзакции, а Forced Write выключен (off) - страницы с записями detail могут быть записаны на диск операционной системой из кэша раньше, чем соответствующие им записи таблицы master. Это не приводит к "невосстановимому backup", но после restore придется или добавлять недостающие master-записи, или удалять "осиротевшие" detail-записи (в зависимости от сложности триггеров, обрабатывающих вставку в master или удаление в detail. Возможно, такие триггеры на время ремонта



[ Редактирование 10.11.2007, 15:13 ]

-------------------------------------------------------
Правила сервера

Банлист
Наверх
Сайт
Сообщение отблагодарили: 1 раз(а)
 

Перейти:     Наверх

Транслировать сообщения этой темы: rss 0.92 Транслировать сообщения этой темы: rss 2.0 Транслировать сообщения этой темы: RDF
Powered by e107 Forum System