Русский
Русский
English
Статистика
Реклама

Транзакции. Часть 1. Конспект книги Designing Data-Intensive Applications

Эта статья является конспектом книги Designing Data-Intensive Applications.

В суровой реальности информационных систем очень многое может пойти не так - программное или аппаратное обеспечение базы данных может отказать в любоймомент; в любой момент может произойти фатальный сбой приложения; разрывы сети могут неожиданно отрезать приложение от базы данных или одинузел базы от другого; состояния гонки между клиентами могут привести к неожиданным ошибкам.

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

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

Скользкая концепция транзакции

В конце 2000-х годов приобрели популярность нереляционные (NoSQL) базыданных. Их целью было улучшить существующее положение дел с реляционными БД с помощью новых моделей данных, репликациии секционирования. Транзакции оказались главной жертвой этогоновшества: многие базы нового поколения полностью от них отказались или поменяли значение термина: теперь он стал у них означать намного более слабый наборфункциональных гарантий, чем ранее.

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

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

Обеспечиваемые транзакциями гарантии функциональной безопасности частоописываются известной аббревиатурой ACID (atomicity, consistency, isolation,durability атомарность, согласованность, изоляция и сохраняемость).

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

Системы, не соответствующие критериям ACID, иногда называются BASE: как правило, доступна (BasicallyAvailable), гибкое состояние (Soft state) и конечная согласованность (Eventualconsistency). Это понятие еще более расплывчатое, чем ACID.

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

Атомарность

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

Напротив, в контексте ACID атомарность не связана с конкурентным доступом.Этот термин не описывает, что происходит, когда несколько процессов пытаютсяобратиться к одним и тем же данным одновременно, поскольку относится к понятию изоляции, то есть букве I в аббревиатуре ACID.

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

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

Согласованность

Слово согласованность ужасно перегружено.

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

  • Согласованное хеширование метод секционирования, используемый в некоторых системах для перебалансировки.

  • В теореме CAP слово согласованность используется для обозначения линеаризуемости (linearizability).

  • В контексте ACID под согласованностью понимается то, что база данных находится, с точки зрения приложения, в хорошем состоянии.

О первых трех пунктах можно подробнее прочесть в книге. Для репликации и секционирования автор книги выделил по целой главе.

К сожалению, одно и то же слово применяется как минимум в четырех различныхсмыслах.

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

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

Изоляция

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

Рис. 1 - Состояние гонки между двумя клиентами, конкурентно увеличивающимизначение счетчикаРис. 1 - Состояние гонки между двумя клиентами, конкурентно увеличивающимизначение счетчика

Изоляция в смысле ACID означает, что конкурентно выполняемые транзакции изолированы друг от друга они не могут помешать друг другу. Классические учебники по базам данных понимают под изоляцией сериализуемость (serializability).То есть каждая транзакция выполняется так, будто она единственная во всей базе.БД гарантирует, что результат фиксации транзакций такой же, как если бы они выполнялись последовательно, хотя в реальности они могутвыполняться конкурентно.

Сохраняемость

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

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

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

Выводы по ACID

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

  • Атомарность. Если посередине последовательности операций записи происходит ошибка, то транзакцию необходимо прервать, а выполненные до тогомомента операции аннулировать.

  • Изоляция. Конкурентно выполняемые транзакции не должны мешать друг другу. Например, если одна транзакция выполняет несколько операций записи, тодругая должна видеть или все их результаты, или никакие, но не какое-то подмножество.

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

Обработка ошибок и прерывание транзакций

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

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

Хотя повторение прерванных транзакций простой и эффективный механизмобработки ошибок, он имеет недостатки:

  • Если причина ошибки в перегруженности, то повтор транзакции толькоусугубит проблему.

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

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

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

Слабые уровни изоляции

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

Базы данных долгое время пытались инкапсулировать вопросы конкурентного доступа от разработчиков приложений путем изоляции транзакций(transaction isolation). Теоретически изоляция должна была облегчить жизнь разработчиков, которые смогли бы сделать вид, что никакого конкурентного выполненияне происходит: сериализуемая изоляция означает гарантию базой данных такогорежима выполнения транзакций, как будто они выполняются последовательно.

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

Автор книги не стал отдельно рассматривать уровень изоляции чтение незафиксированных данных (read uncommitted). Он предотвращает грязные операции записи,но не грязные операции чтения.

Чтение зафиксированных данных

Этот уровень изоляции обеспечивает две гарантии:

  • При чтении из БД клиент видит только зафиксированные данные (никакихгрязных операций чтения).

  • При записи в БД можно перезаписывать только зафиксированные данные (никаких грязных операций записи).

Если транзакция записала данные в базу, но еще не была зафиксирована или была прервана и другая транзакция увидела эти незафиксированные данные, то такая операция чтения называется грязной (dirty read).

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

Рис. 2 - Никаких грязных операций чтения: пользователь 2 видит новое значение x только после фиксации результатов транзакции, выполняемой пользователем 1Рис. 2 - Никаких грязных операций чтения: пользователь 2 видит новое значение x только после фиксации результатов транзакции, выполняемой пользователем 1

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

Чтение зафиксированных данных предотвращает казусы, например, как на рис. 3, связанные с грязной операцией записи.

Рис. 3 - В случае грязных операций записи конфликтующие операции записи различных транзакций могут оказаться перепутаныРис. 3 - В случае грязных операций записи конфликтующие операции записи различных транзакций могут оказаться перепутаны

Чтение зафиксированных данных очень популярный уровень изоляции. Он используется по умолчанию в Oracle 11g, PostgreSQL, SQL Server 2012, MemSQLи многих других базах данных.

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

Большинство БД предотвращают грязные операции чтения с помощьюподхода, показанного на рис. 2: база запоминает для каждого записываемого объекта как старое зафиксированное значение, так и новое, устанавливаемое транзакцией, удерживающей в данный момент блокировку записи. Во время выполнениятранзакции всем другим транзакциям, читающим объект, просто возвращаетсястарое значение. Только после фиксации нового значения транзакции начинаютполучать его при чтении.

Изоляция снимков состояния и воспроизводимое чтение

На первый взгляд уровня изоляции чтения зафиксированных данных вполнедостаточно для транзакций.

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

Рис. 4 - Асимметрия чтения: Алиса видит базу данных в несогласованном состоянииРис. 4 - Асимметрия чтения: Алиса видит базу данных в несогласованном состоянии

Подобная аномалия носит название невоспроизводимого чтения (nonrepeatable read)или асимметрии чтения (read skew): если Алиса прочитала бы баланс счета 1 опятьв конце транзакции, то увидела бы значение ($600), отличное от прочитанного предыдущим запросом. Асимметрия считается допустимой при изоляции уровнячтения зафиксированных данных: видимые Алисе балансы счетов были, безусловно, зафиксированы на момент их чтения.

В случае Алисы это лишь временная проблема. Однако в некоторых ситуациях подобные временные несоответствия недопустимы.

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

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

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

В других источниках данный уровень изоляции может называться повторяющимся чтением (repeatable read)

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

Базы данных применяют для реализации изоляции снимков состояния похожий механизм, действие которого по части предотвращения грязных операций чтения мы наблюдали на рис. 2. БД должна хранить для этого несколько различныхзафиксированных версий объекта, поскольку разным выполняемым транзакциямможет понадобиться состояние базы на различные моменты времени. Вследствиехранения одновременно нескольких версий объектов этот метод получил названиемноговерсионного управления конкурентным доступом (multiversion concurrencycontrol, MVCC).

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

Рис. 5 - Реализация изоляции снимков состоянияс помощью многоверсионных объектовРис. 5 - Реализация изоляции снимков состоянияс помощью многоверсионных объектов

В каждой строке таблицы есть поле created_by, содержащее идентификатор транзакции, вставившей эту строку в таблицу. Более того, в каждой строке таблицы естьполе deleted_by, изначально пустое. Если транзакция удаляет строку, то строка на самом деле не удаляется из базы данных, а помечается для удаления путемустановки значения этого поля в соответствии с идентификатором запросившейудаление транзакции. В дальнейшем, когда уже никакая транзакция точно не обратится к удаленным данным, процесс сборки мусора БД удалит все помеченныедля удаления строки и освободит занимаемое ими место.

Более подробно о правилах видимости для согласованных снимков состояния можно прочесть в книге.

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

Ссылки на все части

Источник: habr.com
К списку статей
Опубликовано: 16.05.2021 10:11:39
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Программирование

Анализ и проектирование систем

Хранение данных

Хранилища данных

Базы данных

Транзакции

Уровни изоляции бд

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru