29.4. Асинхронный коммит#

29.4. Асинхронный коммит

29.4. Асинхронный коммит

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

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

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

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

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

Некоторые утилитарные команды, например DROP TABLE, принудительно коммитятся синхронно, независимо от установки synchronous_commit. Это сделано для обеспечения согласованности между файловой системой сервера и логическим состоянием базы данных. Команды, поддерживающие двухфазный коммит, такие как PREPARE TRANSACTION, также всегда синхронны.

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

Предостережение

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

Асинхронный коммит обеспечивает поведение, отличное от установки fsync = off. fsync - это настройка на уровне сервера, которая изменяет поведение всех транзакций. Она отключает всю логику внутри Tantor SE, которая пытается синхронизировать записи в различные части базы данных, и поэтому сбой системы (то есть сбой аппаратного или операционной системы, а не сбой Tantor SE самого по себе) может привести к произвольному повреждению состояния базы данных. Во многих сценариях асинхронный коммит обеспечивает большую часть улучшения производительности, которое можно получить, отключив fsync, но без риска повреждения данных.

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