Пессимистический подход к надежности систем

kdv, 29.09.2005-28.10.2005

Для начала хочу привести одну реальную историю и одну цитату из фантастического романа.
 

Из книги "Вы шутите, мистер Фейнман?":

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

А. Азимов, "Основание" (или "Академия"):

"Они прошли обратно в контору, и Мэллоу задумчиво спросил:
– И все генераторы в ваших руках?
– Все до единого, – ответил техник с гордостью.
– И вы держите их в порядке и в рабочем режиме?
– Совершенно верно!
– А если они сломаются?
Техник негодующе покачал головой.
– Они не сломаются. Они никогда не сломаются. Они были построены навечно.
– Вечность – это слишком долгое время. Давайте предположим...
– Это не научно – предполагать ничего не значащие обстоятельства.
– Ну, хорошо. Допустим, я бы сейчас разрушил своим бластером самую важную деталь генератора, или разрубил кварцевую Д-трубку?
– Тогда, – в бешенстве закричал техник, – вас бы просто убили.
– Да, я это знаю.
Мэллоу теперь тоже кричал.
– Но что бы произошло с генератором? Смогли бы вы починить его?
– Сэр, – техник отчеканивал каждое слово, – вы честно получили то, что хотели. Я вас не обманул. А теперь уходите! Я больше ничего вам не должен!"

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

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

Никому не нужная защита данных

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

Перехват сетевых пакетов

Для защиты от этого нужно зашифровать целиком поток данных между клиентом и сервером. Клиентом может быть как обычный браузер (в трехзвенной системе) так и gds32.dll (в системе клиент-сервер). Для браузеров (и вообще) широко распространено использование ssl, а для клиент-сервера (и опять же браузеров) можно применить zebedee или другие программные или аппаратные системы шифрования.

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

Собственно, пароли на доступ украсть гораздо легче, чем заниматься перехватом даже нешифруемых пакетов в сети. И сделано это может быть намного проще, чем представляется – прочитайте статью "Хорошо ли защищены ваши данные" в Компьютерре N 35 (607) от 27 сентября 2005. Вы будете удивлены дешевизной методов и изобретательностью тех, кому вдруг понадобятся ваши данные.

Кража файла базы данных

Действительно, если переместить файл базы данных на другой компьютер, то аутентификация SYSDBA не действует. То есть, злоумышленник может прочитать все данные. Ok, давайте ограничим доступ к базам данных – поставим часового у сервера, замуруем сервер в бетон и т. п. Остались ли наши данные такими же недоступными, как и ранее?

Продолжая тему об экзотических методах злоумышленников нельзя не упомянуть один способ, который позволял скопировать базу данных без доступа к серверу: злоумышленник получает любой логин к серверу БД, далее создает в базе данных external table, указывающую на сам файл базы данных, и состоящую например из одного столбца integer. Затем производится select * from эта "внешняя таблица", и таким образом база перекачивается на компьютер злоумышленника. Конечно, если с базой идет интенсивная работа, то злоумышленник вместо содержимого базы получит "мусор", но хоть часть данных он, конечно, увидит. Чуть менее экзотической дырой была возможность "залить" в базу данных вредоносную udf опять же через create external table. Параметры external_file_directory и external_function_directory были введены в последних версиях InterBase и Firebird именно для блокирования подобных "дыр".

Повреждение базы данных

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

Резюме по защите данных

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

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

Провальные системы резервирования данных

Здесь обойдемся просто перечислением реальных случаев:
  • в системе организован ежевечерний автоматический backup, и утренний автоматический restore. В один из дней "восстановленная" из backup база оказалась никуда не годной. Проблема была в том, что backup всегда делался в один и тот же файл, а restore производился как gbak -r на место рабочей БД. При backup произошел сбой, и файл резервной копии оказался поврежден, а при restore поврежденный файл восстановился лишь частично. Копии backup на альтернативные носители не делались.
  • в системе организован регулярный backup и restore, со всеми предосторожностями, backup-ы копировались на внешний компьютер. Однако, backup производился на тот же самый логический диск, где находилась база данных. Из-за того, что не следили за ростом БД, в очередной раз для backup не хватило места. Сервер прекратил работать с БД также из-за нехватки места. После останова сервера и удаления неполноценного backup оказалось, что в результате еще и повредился файл БД. БД была восстановлена из резервной копии, данные работы за сутки были потеряны, и перевведены.
  • backup автоматизирован записью на cd-rw. В очередной момент был вставлен неформатированный cd-rw, а ошибки создания backup не обрабатывались. В итоге backup не производился в течение месяца. Когда произошел сбой сервера и файл базы оказался поврежден, выяснилось, что самая последняя рабочая копия backup – месячной давности.
  • на сервере организован raid 10 – три диска в raid 0 и еще три диска raid 0 к ним как raid 1. Backup не делался по причине уверенности администратора в подобной схеме raid. При сбое одного из дисков raid 0 по неизвестной причине raid 1 не смог восстановить данные. Результат – треть базы данных (raid 0 осуществляет чередование данных) оказалась прописана нулями, и восстановлению не подлежала. Попытка ремонта диска и восстановления с него данных в фирме, ремонтирующей HDD, результата не дала.
  • регулярные backup базы данных, с сохранением на внешние носители. Проверки восстановимости базы из backup не делались в течение 2-х месяцев. В результате специфического изменения метаданных разработчиком на определенном этапе backup стал "невосстанавливаемым", это выяснилось при сбое сервера и необходимости восстановления БД из резервной копии (подобные ситуации детально описаны в документе).

Понятно, что самым примитивным случаем является когда резервные копии базы просто никогда не делают. Худший случай – когда комбинируют две системы резервирования, одна из которых при сбое сделает невозможным восстановление данных, даже сохраненных второй системой.
 
Примечание. На конференции "Корпоративные базы данных 2005" я обратил вниманиеLINK, что ведущие производители СУБД, такие как Oracle и Microsoft, внедрили в свои сервера программные аналоги аппаратным реализациям RAID (AMS и Mirroring/Snapshots соответственно). Это можно объяснить как минимум тем, что программная реализация подобного резервирования данных дает больше свободы и управляемости, чем аппаратная. С другой стороны, программная "эмуляция" raid не отменяет необходимости обеспечения надежности дисковой подсистемы.
 

Мифические "24 часа в сутки"

Разговоры на эту тему больше всего напоминают приведенную в самом начале цитату из романа Азимова. Я не знаю, каким сверхоптимизмом надо обладать, чтобы быть уверенным что
  • сервер БД будет работать вечно и никогда не даст сбой
  • железо на сервере будет работать вечно и 100% никогда не даст сбой, что могло бы привести к сбою сервера БД, порче базы данных и т. п.
  • сетевое оборудование, соединяющее сервер и клиентов, будет работать вечно
  • электропитание на компьютер сервера или на сетевое оборудование будет подаваться вечно
  • в серверной нет устройств, которые могут стать неисправными и косвенно привести к неисправности сервера
  • молния никогда не ударит в электропроводку
  • трубы отопления никогда не прорвет этажом выше над серверной
  • и т. д., и т. п.
Отсюда следует вывод – планирование регламентных работ, в течение которых сервер БД (или любой другой компонент системы) не будет работать или не будет доступен остальным компонентам системы, обязательно.

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

Представим себе ситуацию: администратор сервера БД знает, что если база окажется поврежденной, то нужно посмотреть документ. Пойдем еще дальше, и представим себе что сбой-таки произошел, и администратор уселся в кресло внимательно изучать указанный документ. Представили? Ага... Наоборот, у администратора должен быть четкий план действий в случае сбоя, основанный в том числе на информации, почерпнутой из указанной статьи. Тогда время на решение проблемы значительно сократится.
 
Примечание. Вот еще случай из реальной жизни. У нас на специальной странице перечислены широко распространенные типы повреждений баз данных, ссылка на подробный документ по ремонту баз данных, и перечень пунктов, что и как должен сделать администратор, если он сам не в состоянии устранить сбой. Тем не менее, произошло следующее:
(Админ): база сломалась, помогите починить.
(Техсаппорт): пробовали чинить как изложено здесь?
(Админ): да, ничего не получается, нужно срочно отремонтировать базу
(Техсаппорт): шлите на support@ibase.ru информацию о размере, повреждении и т. п., срочно.
Приходит письмо с половиной нужной информации. При попытке отправить ответ обратный email не работает. Телефон для связи не указан. Ждем, пока человек перезвонит. Прошло полтора часа.
(Админ): от вас ничего нет!
(Техсаппорт): объясняем, в чем проблема. Человек диктует второй адрес, отправляем туда url ftp для закачки базы.
У человека связь модемная, база около 15-20 мегабайт в rar. Первая попытка не прошла, закачивает куски по 1 мегабайту. Проходит еще 2 часа.
База принята. Проверяем. Сообщаем человеку, что база легко чинится способом, указанным в документе.
Проходит еще час. Человек сообщает, что не получается. Ok, мы выкладываем отремонтированную БД, но на ее скачивание по модему опять уйдет время до 2-х часов.
Проходит еще час. Человек сообщает, что базу починил.
Итог – база могла быть отремонтирована самостоятельно, за максимум полчаса, если следовать инструкциям в опубликованном документе. Вместо этого – целиком потерян рабочий день, в течение которого система не работала.
В качестве небольшого подтверждения мифичности "24x7" хочу привести реальный случай, описанный в конференции e.p.i:
Существовала система RAID 5 с 4-мя одинаковыми дисками. Проработала примерно года 3. Вдруг вышел из строя один диск. Администратор стал срочно искать похожий диск, понятно что в продаже аналогов уже не было (техника сейчас устаревает и пропадает с полок магазинов очень быстро), поэтому была куплена замена БУ. И буквально в этот же день после замены вышел из строя еще один из дисков RAID!

Конечно, я никоим образом не отвергаю возможности существования систем, работающих 24 часа 365 дней в году. Такие системы безусловно есть, и они успешно работают. Я отвергаю лишь возможность подобного режима для всех компонентов системы по отдельности, в особенности для сервера БД. У каждого сервера БД есть определенные "граничные" состояния, после наступления которых он не может работать с базой данных. Это, повреждение базы данных, более 2 миллиарда транзакций в базе данных (в IB 5.6 был баг, когда нижний предел такого числа составлял всего 131 миллион), и даже в одной из версий Oracle была ошибка, которая требовала специфической манипуляции над базой данных после определенного периода ее работы.
 

Ввод (импорт) данных из внешних источников

Известно, что надежность системы определяется перемножением надежностей всех ее компонент. Например 0.9 * 0.9 = 0.81. Однако бывают случаи, когда наоборот, с точки зрения надежности выгоднее увеличение числа компонент.

Типичный пример – биллинговые или подобные системы, где данные приходят в приложение из какой-либо аппаратуры и приложением записываются в базу данных. Опять же, пессимистически оцениваем систему, рассматривая случай тотального сбоя ее каждой компоненты:
  • если аппаратура перестанет передавать данные, то это не фатально для остальных компонент. Как бы, дело системы принять данные и сохранить их. А если данных нет, то ...
  • если приложение перестанет работать, то данные из аппаратуры будут поступать, а сохранить их в БД будет некому. В этом случае аппаратура должна знать, что данные передавать некуда и их надо буферизировать или сохранять самостоятельно. Если аппаратура этого делать не может, данные пропадут.
  • если сервер БД перестанет работать или должен быть временно остановлен, приложению некуда будет сохранять данные. Значит, или приложение должно будет уметь сохранять данные, например, в текстовых промежуточных файлах (при этом оно усложнится, и автоматически снизится его надежность), или при обнаружении недоступности БД оно должно уведомить аппаратуру о необходимости буферизации данных.
Как видите, сбой двух из трех компонент может явиться фатальным для функционирования системы. Наиболее практичное и частое решение – разделение приложения на 2 части: одна часть работает с аппаратурой и сохраняет данные в промежуточный файл, а вторая часть из промежуточных файлов записывает данные в БД. Таким образом, остановка сервера БД или импортирующего данные на систему не влияют. И остается только обеспечить надежность аппаратуры и принимающего данные приложения. Обычно такие приложения примитивны и, по определению, не могут содержать фатальных для функционирования ошибок в коде.

Если сама аппаратура поставляет данные в виде файлов, то еще лучше – вся система упрощается максимально и наименее подвержена сбоям.
 
Примечание. Интересно, что когда реализуют приложение, принимающее данные из аппаратуры и записывающее их в базу, применяют максимум "красивых" приемов – нити (threads), интерфейсы прямого обращения к аппаратуре и т. п. В результате приложение становится максимально ненадежным, насколько это возможно. Здесь в качестве правильного примера проектирования систем можно привести разве что военное оборудование, которое ужасно примитивно и в результате максимально надежно.
 

Двухфазный commit

Казалось бы, в чем уязвимость этой вполне отработанной технологии? Давайте рассмотрим ее характеристики и варианты применения.

2PC стартует транзакцию над несколькими базами данных, и обладает определенной логикой применения изменений в случае сбоя на этапе подтверждения (commit) такой транзакции. Для того, чтобы во всех базах данных, участвующих в распределенной транзакции, данные были или применены или отменены, до commit или rollback в каждой базе данных такая транзакция помечается состоянием "in Limbo". Это означает, что до момента окончательной фиксации или отмены изменений ни в одной из таких базах данных версии, помеченные такой транзакцией, нельзя было бы удалить отдельно. То есть, это требование согласованности такой транзакции.

Значит, версии записей, помеченные "in Limbo", нельзя удалить, их нельзя обновить, и даже для gbak (при backup) есть специальный ключ -L, позволяющий игнорировать такие версии записей. Отсюда мы делаем вывод, что если при выполнении транзакции 2PC произошел сбой, то нормальная работа приложений может быть парализована до устранения "застрявших" версий записи путем commit/rollback двухфазной транзакции на всех базах данных, участвовавших в транзакции.

Теперь давайте рассмотрим, как "расстояние" между базами данных влияет на невозможность работы до устранения проблем с незавершенными 2PC:
  1. Базы данных, участвующие в транзакции 2PC, находятся на одном компьютере (сервере).
Здесь нет никаких проблем, т. к. либо сервер работает и доступ к обоим базам данных есть, либо сервер не работает целиком. То есть, время восстановления в случае работы сервера минимально – запускаем gfix в автоматическом режиме или в ручном режиме указываем что делать с такими транзакциями (вопрос повреждения одной из базы не рассматриваем, все это уже было описано выше).
 
  1. Базы данных, участвующие в транзакции 2PC, разнесены на 2 компьютера, находящиеся в локальной сети.
Здесь основная проблема в физической доступности одного компьютера относительно другого. Если они достаточно близко, то после ремонтных действий на одном из серверов можно быстро запустить процедуру восстановления транзакций 2PC.
 
  1. Базы данных находятся на компьютерах, разделенных модемной связью. Например, между такими базами данных производится репликация путем использования транзакций 2PC.
Это худший из вариантов, потому что нарушение модемной связи может прозойти по массе причин и на непредсказуемо длительный срок. Если не предусмотрен другой способ доставки реплицируемых данных на тот или иной сервер, никакого другого выхода кроме как gbak -b -L (создать резервную копию с игнорированием версий in Limbo и восстановленить БД из резервной копии) нет.
 
Отсюда делаем вывод, что наихудшим вариантом является использование 2PC на модемной связи. Собственно, некоторые для себя могут сделать другой вывод – что для них использование 2PC например для репликации данных неприемлемо.

Еще один момент, возможно неожиданный для вас – инструмент gfix, с помощью которого можно исправлять состояние транзакций 2PC принимает только одну пару username/password в опциях командной строки. Это означает, что если пароли SYSDBA (или OWNER) отличаются на двух серверах, то gfix не сможет подсоединиться к обоим одновременно.


Итог

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

Можно прочитать на эту тему


Обсудить статью на форуме

Подпишитесь на новости Firebird в России

Подписаться