Документация по PostgreSQL 8.4.2 | ||||
---|---|---|---|---|
Prev | Fast Backward | Chapter 28. Надёжность и журнал опережающей записи (WAL) | Fast Forward | Next |
Асинхронное сохранение транзакций (asynchronous commit) — это опция, которая позволяет транзакциям выполняться более быстро, за счёт того, что наиболее свежие транзакции могут быть потеряны, если произойдёт отказ базы данных. Во многих приложениях это является допустимыми издержками.
Как было описано выше, сохранение транзакции обычно синхронное: сервер ожидает пока данные транзакции в WAL будут физически записаны на диск перед тем как возвратить клиенту подтверждение об успешном окончании операции. Клиенту, таким образом, гарантруется, что транзакция, которая отмечена как завершённая будет защищена, даже если сразу после этого случится отказ сервера. Однако, для коротких транзакций данная задержка является значимой по сравнению с общим временем транзакции. Выбор режима ансинхронного сохранения транзакций означает, что сервер возвращает подтверждение об успешном окончании операции сразу после того как транзакция выполнена логически, перед тем как данные об этой транзакции в WAL будут физически записаны на диск. Такой режим даёт значительное ускорение для маленьких транзакций.
Асинхронное сохранение транзакций приводит к риску потери данных. Есть короткий временной промежуток между отчётом об окончании транзакции клиенту и физическим сохранением транзакции на диск (так что нет гарантии, что данные не будут потеряны если произойдёт отказ сервера). Поэтому асинхронные транзакции не должны использоваться, если клиент будет выполнять внешние действия, надеясь на то, что транзакция будет запомнена (на диск -- прим.пер.). В качестве пример, банк безусловно не должен использовать асинхронное сохранение транзакций для выдачи наличных через банкоматы. Но во многих случаях, таких как журналирование событий, нет надобности в строгой гарантии сохранения транзакции.
Риск, который есть при использовании асинхронного сохранения транзакций состоит в возможной потере данных, но не повреждении данных. Если произойдёт крах базы данных, она будет восстановлена путём наката WAL к последней сохранённой записи. База данных таким образом будет восстановлена на последнее целостное состояние, но любые транзакции, которые не были сброшены на диск, не будут отражены в этом состоянии. Сетевой эффект таким образом состоит в потере нескольких последних транзакций. Поскольку транзакции накатываются в том же порядке, в котором они сохранялись, нецелостное состояние возникнуть не может; например, если транзакция B сделала изменения, на которые оказывает эффект предыдущая транзакцию A, то невозможно чтобы эффект транзакции A был потерян, но при этом эффект транзакции B сохранился.
The user can select the commit mode of each transaction, so that it is possible to have both synchronous and asynchronous commit transactions running concurrently. This allows flexible trade-offs between performance and certainty of transaction durability. The commit mode is controlled by the user-settable parameter synchronous_commit, which can be changed in any of the ways that a configuration parameter can be set. The mode used for any one transaction depends on the value of synchronous_commit when transaction commit begins.
Certain utility commands, for instance DROP TABLE, are forced to commit synchronously regardless of the setting of synchronous_commit. This is to ensure consistency between the server's file system and the logical state of the database. The commands supporting two-phase commit, such as PREPARE TRANSACTION, are also always synchronous.
If the database crashes during the risk window between an asynchronous commit and the writing of the transaction's WAL records, then changes made during that transaction will be lost. The duration of the risk window is limited because a background process (the "WAL writer") flushes unwritten WAL records to disk every wal_writer_delay milliseconds. The actual maximum duration of the risk window is three times wal_writer_delay because the WAL writer is designed to favor writing whole pages at a time during busy periods.
Caution |
An immediate-mode shutdown is equivalent to a server crash, and will therefore cause loss of any unflushed asynchronous commits. |
Asynchronous commit provides behavior different from setting fsync = off. fsync is a server-wide setting that will alter the behavior of all transactions. It disables all logic within PostgreSQL that attempts to synchronize writes to different portions of the database, and therefore a system crash (that is, a hardware or operating system crash, not a failure of PostgreSQL itself) could result in arbitrarily bad corruption of the database state. In many scenarios, asynchronous commit provides most of the performance improvement that could be obtained by turning off fsync, but without the risk of data corruption.
commit_delay also sounds very similar to asynchronous commit, but it is actually a synchronous commit method (in fact, commit_delay is ignored during an asynchronous commit). commit_delay causes a delay just before a synchronous commit attempts to flush WAL to disk, in the hope that a single flush executed by one such transaction can also serve other transactions committing at about the same time. Setting commit_delay can only help when there are many concurrently committing transactions, and it is difficult to tune it to a value that actually helps rather than hurting throughput.