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