- •§ 2 Обеспечение надежности микропроцессорных информационно-управляющих вычислительных систем (увс).
- •Для увс с общим нагруженным дублированием и восстановлением
- •§ 3 Методы повышения надежности программно-информационных технологий для корпоративных структур
- •3.1.2. Резервное копирование и восстановление данных
- •3.2. Резервирование процессорных модулей
- •Отказоустойчивые системы
- •Проблема параллельного выполнения
- •Транзакции.
- •Реализация транзакций.
- •Модульные транзакции.
- •Список литературы
Отказоустойчивые системы
Дефекты программного обеспечения (ПО) преодолеваются намного тяжелее. Одна из причин состоит в том, что отказы, восстановление, и вычисление происходят параллельно. Другая − в том, что восстановление после отказа ПО, трудно само по себе. Мы увидим, что атомарные операции − ключевой подход, который решает обе проблемы.
Проблема параллельного выполнения
Пусть у нас имеются три процедуры − "сбойная" процедура F, процедура восстановления R, и процедура пользователя U - каждая состоит из трех шагов. Если мы выполняем эти процедуры параллельно на машине с одним только процессором, то он выполнит в режиме реального времени некоторую последовательность шагов с расслоением указанных процедур; например, {F1, R1, U1, F2, FЗ, R2, RЗ, U2, U3}. Эта конкретная последовательность − одна из 1680 возможностей, и мы не можем легко предсказать, какая из них выполнится на самом деле.
Некоторые из этих последовательностей могут производить правильные результаты, в то время как другие могут производить неправильные результаты. Пример: несколько потоков, разделяющие кэш: в web-сервере. Мы можем работать в течение нескольких месяцев без столкновения с ошибками. Если мы все-таки сталкиваемся с ошибкой, то попытка ее повторить не будет работать на практике. Отсутствие воспроизводимости делает отладку трудной.
Чтобы решить эту проблему, мы используем простой общий аргумент, который устраняет все такие ошибки. Мы видели в лекции по параллелизму, что этот общий аргумент − атомарность. Мы хотим иметь блок команд, который выполняется неделимым образом.
Рассмотрим передачу денег между совместно используемыми банковскими счетами:
transfer (debit, credit, amount)
{
/* 1 */ read debit;
/* 2 */ read credit;
/* 3 */ newDebit = debit - amount;
/* 4 */ newCredit = debit + amount;
/* 5 */ write newDebit
/* 6 */ write newCredit
}
Если две передачи происходят параллельно, то в зависимости от порядка команд в процедуре transfer, возможны различные результаты. Предположим, что следующие процедуры transfer А и transfer В выполняются параллельно:
A: transfer(x, у, $100)
В: transfer (у, z, $5)
Если банковский счет у содержит $100, то желательный результат этих двух передач − $195, который, например, получается, когда порядок выполнения команд такой, что вначале выполняются все команды А, а потом − В. Однако, если у нас порядок выполнения следующий: A read у, В read у, А вычисляет newy = у + 100, В вычисляет newy = у - 5, A write newy, В write newy, тогда итоговое значение у равно $95. Счет у потерял $100!
Чтобы получить желаемый результат ($195), мы хотим выполнить блок команд неделимым образом. Итак, наше первое временное определение атомарной операции: выполнять ее целиком до или целиком после. Оно не совсем хорошее, потому что не рассматривает, что происходит в случае отказа.
Проблема восстановления после отказа
Отказы показывают, что атомарные операции являются составными. Пример: процедура transfer пишет записи по информации счета. Основная база данных создает запись, отмечая, что должна быть добавлена новая запись, и выделяя место под нее. Затем запись обновляется, что приводит к последовательности дисковых операций по сохранению информации в стабильной памяти. Если происходит дисковая ошибка (например, блок не записан правильно), система продолжает работать, но запись находится в потенциально неправильном состоянии (например, запись выделена, но значение так и не было записано). Отказ диска раскрывает перед программой пользователя, что создание файла − составная операция.
Нам нужен способ, как сделать невидимым то, что создание и сохранение записи являются составными операциями: создание записи должно полностью закончиться или не начинаться совсем. Это рассуждение ведет к нашему второму временному определению атомарных операций: как только операция началась, необходимо выполнить ее без задержки или отступить, не оставляя никаких следов.
Атомарные операции
Отступая на шаг, мы видим здесь обычный поток в том, что атомарная операция скрывает внутреннюю структуру. С точки зрения клиента, атомарная операция всегда заканчивается или испытывает откат. С точки зрения параллельных операций, она всегда происходит целиком до или после любых других операций. Таким образом, вот наше определение атомарной операции: нет никакого способа обнаружить, что атомарная операция является составной.