Асинхронное подтвержение транзакций

29.3. Асинхронное подтвержение транзакций

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

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

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

Риск потери данных при использовании асинхронного подтверждения транзакций — это не риск их повреждения. Если случился крах СУБД, она будет восстановлена с помощью наката WAL к последней записи, которая была записана на диск. Таким образом, СУБД будет восстановлена к целостному состоянию, но любые транзакции, которые ещё не были сохранены на диск, не будут откражены в этом состоянии. Чистый эффект будет заключаться в потере нескольких последних транзакций. Поскольку транзакции накатываются в том же порядке, в котором подтверждались, накат не приводит к нецелостности — например, если транзакция B выполнила изменения, которые влияют на предыдущую транзакцию A, не может быть такого, что изменения, выполненные A были потеряны, а изменения, внесённые B сохранены.

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

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

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

Caution

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

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

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

Back to top

(С) Виктор Вислобоков, 2008-2023