Асинхронная фиксация — это опция, позволяющая транзакциям завершаться быстрее, ценой того, что последние транзакции могут быть потеряны при сбое базы данных. Во многих приложениях это приемлемый компромисс.
Как описано в предыдущем разделе, фиксация транзакции обычно является синхронной: сервер ожидает сброса записей WAL (журнала предварительной записи) транзакции в постоянное хранилище, прежде чем вернуть клиенту уведомление об успехе. Клиенту таким образом гарантируется, что транзакция, о которой сообщено как о зафиксированной, будет сохранена даже в случае сбоя сервера сразу после этого. Однако для коротких транзакций эта задержка является основной составляющей общего времени транзакции. Выбор режима асинхронной фиксации означает, что сервер возвращает успех сразу после того, как транзакция логически завершена, до того, как сгенерированные ею записи в журнале предварительной записи фактически попадут на диск. Это может обеспечить значительный прирост пропускной способности для небольших транзакций.
Асинхронная фиксация вносит риск потери данных. Существует короткое окно времени между отчетом о завершении транзакции клиенту и моментом, когда транзакция действительно зафиксирована (то есть гарантированно не будет потеряна при сбое сервера). Таким образом, асинхронную фиксацию не следует использовать, если клиент будет предпринимать внешние действия, опирающиеся на предположение, что транзакция будет сохранена. В качестве примера, банк определенно не стал бы использовать асинхронную фиксацию для транзакции, регистрирующей выдачу наличных банкоматом. Но во многих сценариях, таких как ведение журнала событий, нет необходимости в строгой гарантии такого рода.
Риск, возникающий при использовании асинхронной фиксации, заключается в потере данных, а не в их повреждении. Если база данных выйдет из строя, она восстановится путем воспроизведения журнала предварительной записи (WAL) до последней записи, которая была сброшена. Таким образом, база данных будет восстановлена до самосогласованного состояния, но любые транзакции, которые еще не были сброшены на диск, не будут отражены в этом состоянии. Чистый эффект — потеря последних нескольких транзакций. Поскольку транзакции воспроизводятся в порядке фиксации, никакая несогласованность не может возникнуть — например, если транзакция B внесла изменения, полагаясь на эффекты предыдущей транзакции A, невозможно, чтобы эффекты A были потеряны, а эффекты B сохранены.
Пользователь может выбирать режим фиксации для каждой транзакции, так что
возможно одновременное выполнение транзакций с синхронной и асинхронной фиксацией. Это позволяет гибко балансировать между производительностью и гарантией долговечности транзакций.
Режим фиксации контролируется устанавливаемым пользователем параметром
synchronous_commit, который может быть изменен любым из
способов установки параметров конфигурации. Режим, используемый для
любой конкретной транзакции, зависит от значения
synchronous_commit на момент начала фиксации транзакции.
Некоторые служебные команды, например DROP TABLE,
принудительно фиксируются синхронно независимо от настройки
synchronous_commit. Это необходимо для обеспечения согласованности
между файловой системой сервера и логическим состоянием базы данных.
Команды, поддерживающие двухфазную фиксацию, такие как PREPARE
TRANSACTION, также всегда синхронны.
Если база данных выйдет из строя в течение окна риска между
асинхронной фиксацией и записью данных транзакции в журнал предварительной записи
(WAL), то изменения, сделанные в ходе этой транзакции, будут потеряны.
Продолжительность
окна риска ограничена, поскольку фоновый процесс (процесс записи журнала — «WAL writer») сбрасывает незаписанные записи в журнал на диск
каждые wal_writer_delay миллисекунд.
Фактическая максимальная продолжительность окна риска в три раза превышает
wal_writer_delay, так как процесс записи журнала
спроектирован так, чтобы в периоды высокой нагрузки отдавать приоритет записи целых страниц за один раз.
Выключение в режиме immediate эквивалентно сбою сервера и, следовательно, приведет к потере всех несброшенных асинхронных фиксаций.
Асинхронная фиксация обеспечивает поведение, отличное от установки
fsync = off.
fsync — это настройка на уровне всего сервера,
которая изменит поведение всех транзакций. Она отключает
всю логику внутри Digital Q.DataBase, которая пытается синхронизировать
записи в различные части базы данных, и поэтому сбой системы
(то есть сбой оборудования или операционной системы, а не сбой самого
Digital Q.DataBase) может привести к произвольно серьезному
повреждению состояния базы данных. Во многих сценариях асинхронная
фиксация обеспечивает большую часть улучшения производительности, которое могло бы быть
получено при отключении fsync, но без риска
повреждения данных.
Параметр commit_delay также звучит очень похоже на
асинхронную фиксацию, но на самом деле это метод синхронной фиксации
(фактически, commit_delay игнорируется при
асинхронной фиксации). commit_delay вызывает задержку
непосредственно перед тем, как транзакция сбросит журнал предварительной записи (WAL) на диск, в
надежде, что один сброс, выполненный одной такой транзакцией, также сможет
обслужить другие транзакции, фиксирующиеся примерно в то же время. Эту
настройку можно рассматривать как способ увеличения окна времени, в
котором транзакции могут присоединиться к группе, собирающейся участвовать в одном
сбросе, чтобы распределить стоимость сброса между несколькими транзакциями.