Введение
Операция, применяющая набор различных изменений как единое целое. В области информатики, атомарная фиксация (commit) – это операция, применяющая набор различных изменений как единое целое. Если изменения применены, то считается, что атомарная фиксация выполнена успешно. Если происходит сбой до завершения атомарной фиксации, все изменения, выполненные в рамках этой фиксации, отменяются. Это гарантирует, что система всегда остаётся в согласованном состоянии. Другое ключевое свойство – изоляция – вытекает из их природы как атомарных операций. Изоляция обеспечивает одновременную обработку только одной атомарной фиксации. Наиболее часто атомарные фиксации используются в системах управления базами данных и системах контроля версий. Проблема атомарных фиксаций заключается в необходимости координации между несколькими системами. Поскольку компьютерные сети являются ненадежными, ни один алгоритм не может гарантированно координироваться со всеми системами, что доказано в задаче о двух генералах. По мере увеличения распределенности баз данных, координация усложняет обеспечение истинной атомарности фиксаций.
In the field of computer science, an atomic commit is an operation that applies a set of distinct changes as a single operation. If the changes are applied, then the atomic commit is said to have succeeded. If there is a failure before the atomic commit can be completed, then all of the changes completed in the atomic commit are reversed. This ensures that the system is always left in a consistent state. The other key property of isolation comes from their nature as atomic operations. Isolation ensures that only one atomic commit is processed at a time. The most common uses of atomic commits are in database systems and version control systems. The problem with atomic commits is that they require coordination between multiple systems. As computer networks are unreliable services, this means no algorithm can coordinate with all systems as proven in the Two Generals Problem. As databases become more and more distributed, this coordination will increase the difficulty of making truly atomic commits.
Использование
Атомные коммиты необходимы для многоступенчатых обновлений данных. Это можно наглядно продемонстрировать на простом примере перевода денег между двумя расчётными счетами. Этот пример усложняется транзакцией по проверке баланса счета Y во время перевода 100 долларов со счета X на счет Y. Сначала со счета X снимается 100 долларов. Затем 100 долларов зачисляется на счет Y. Если вся операция не будет выполнена как единый атомарный коммит, могут возникнуть несколько проблем. Если система выйдет из строя в середине операции, после снятия денег со счета X и до зачисления на счет Y, то 100 долларов просто исчезнут. Другая проблема заключается в том, что если баланс счета Y будет проверен до зачисления 100 долларов, будет показан неверный баланс. При использовании атомарных коммитов ни один из этих случаев невозможен: в случае сбоя системы атомарный коммит будет откачен, и деньги вернутся на счет X. Во втором случае запрос баланса счета Y не может быть выполнен до полного завершения атомарного коммита.
Системы баз данных
Атомные коммиты в системах баз данных обеспечивают два ключевых свойства ACID – атомарность и согласованность. Согласованность достигается только в том случае, если каждое изменение в рамках атомарного коммита является согласованным. Как показано на примере, атомные коммиты критически важны для многошаговых операций в базах данных. Из-за современной аппаратной реализации физического диска, на котором размещена база данных, истинные атомные коммиты невозможны. Наименьшая область, в которую можно записать данные на диске, называется сектором. Одна запись в базе данных может занимать несколько секторов. За один раз можно записать только один сектор. Это ограничение на запись является причиной, по которой истинные атомные коммиты невозможны. После изменения записей базы данных в памяти они помещаются в очередь для записи на диск. Это означает, что те же проблемы, которые были выявлены в примере, возникают снова. Любое алгоритмическое решение этой проблемы все равно столкнется с проблемой двух генералов. Протоколы двухфазного и трехфазного коммитов пытаются решить эту и другие проблемы, связанные с атомными коммитами. Протокол двухфазного коммита требует от координатора хранения всей информации, необходимой для восстановления исходного состояния базы данных в случае возникновения ошибки. Как следует из названия, протокол состоит из двух фаз: голосования и фиксации. Во время фазы голосования каждый узел записывает изменения атомарного коммита на свой диск. Затем узлы сообщают о своем статусе координатору. Если узел не сообщает координатору или его сообщение о статусе теряется, координатор предполагает, что запись узла не удалась. После того, как все узлы сообщили координатору, начинается вторая фаза. Во время фазы фиксации координатор отправляет сообщение о фиксации каждому узлу для записи в их локальные журналы. Пока это сообщение не будет добавлено в журнал узла, все изменения будут считаться незавершенными. Если какой-либо из узлов сообщил об ошибке, координатор вместо этого отправит сообщение об откате. Это удалит все изменения, которые узлы записали на диск. Протокол трехфазного коммита направлен на устранение основной проблемы двухфазного коммита, которая возникает, если координатор и другой узел выходят из строя одновременно во время фазы фиксации, и ни один из них не может определить, какое действие следует предпринять. Для решения этой проблемы в протокол добавляется третья фаза. Фаза подготовки к коммиту происходит после фазы голосования и перед фазой фиксации. На фазе голосования, аналогично двухфазному коммиту, координатор запрашивает у каждого узла готовность к коммиту. Если какой-либо узел выходит из строя, координатор ожидает истечения времени ожидания для этого узла. Если это происходит, координатор отправляет сообщение об откате всем узлам. То же самое произойдет, если любой из узлов вернет сообщение об ошибке. После получения сообщений об успехе от каждого узла на фазе голосования начинается фаза подготовки к коммиту. В течение этой фазы координатор отправляет сообщение о подготовке каждому узлу. Каждый узел должен подтвердить получение сообщения о подготовке и ответить. Если какой-либо ответ не получен или узел сообщает о своей неготовности, координатор отправляет сообщение об откате. Любой узел, не получивший сообщение о подготовке до истечения времени ожидания, откатывает коммит. После того, как все узлы ответили на сообщение о подготовке, начинается фаза фиксации. На этой фазе координатор отправляет сообщение о коммите каждому узлу. Когда каждый узел получает это сообщение, он выполняет фактическую фиксацию. Если сообщение о коммите не достигает узла из-за потери сообщения или отказа координатора, узел выполнит коммит по истечении времени ожидания. Если координатор восстановится после отказа, он отправит сообщение о коммите каждому узлу.
commit message to each node. When each node receives this message it performs the actual commit. If the commit message does not reach a node due to the message being lost or the coordinator fails they will perform the commit if the timeout expires. If the coordinator fails upon recovery it will send a commit message to each node.
Контроль за пересмотром
Атомные коммиты – распространенная функция систем контроля версий, критически важная для поддержания согласованного состояния репозитория. Большинство систем контроля версий не применяют часть коммита, если он не удался. Заметными исключениями являются CVS, VSS и IBM Rational ClearCase (в режиме UCM). Например, если система контроля версий сталкивается с конфликтом при слиянии, который не удается разрешить автоматически, ни одна часть набора изменений не будет объединена. Вместо этого разработчику предоставляется возможность отменить свои изменения или разрешить конфликт вручную. Это предотвращает переход проекта в нерабочее состояние из-за частично примененного набора изменений, когда один файл из коммита успешно зафиксирован, а другой файл с зависимыми изменениями – нет. Атомные коммиты также могут относиться к возможности одновременного внесения изменений в несколько проектов с использованием системы контроля версий в рамках одной операции, используя стратегию разработки, известную как monorepo. Лучшее понимание обеспечивается небольшим размером и направленностью коммита. Гораздо проще понять, что изменилось и почему, если рассматривается только один тип изменения. Это особенно важно при изменении форматирования исходного кода. Если изменения форматирования и функциональные изменения объединены, становится очень сложно выделить полезные изменения. Представьте, что пробелы в файле заменены с табуляции на три пробела – в файле будет отображаться, что изменилась каждая табуляция. Это становится критичным, если также внесены функциональные изменения, поскольку рецензент может просто не заметить их. Если используются только атомные коммиты, то коммиты, вносящие ошибки, гораздо проще идентифицировать. Не нужно просматривать каждый коммит, чтобы выяснить, был ли он причиной ошибки – достаточно изучить коммиты, относящиеся к этой функциональности. Если ошибку нужно откатить, атомные коммиты снова упрощают задачу. Вместо того чтобы возвращаться к проблемной ревизии и удалять изменения вручную перед интеграцией последующих изменений, разработчик может просто отменить изменения в указанном коммите. Это также снижает риск случайного удаления несвязанных изменений, которые случайно оказались в том же коммите. Атомные коммиты также позволяют легко рецензировать исправления ошибок, если за один раз фиксируется только одно исправление. Вместо проверки нескольких потенциально не связанных файлов рецензенту нужно проверять только файлы и изменения, которые непосредственно влияют на исправляемую ошибку. Это также означает, что исправления ошибок можно легко упаковать для тестирования, поскольку в коммите содержатся только изменения, исправляющие ошибку.