diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:28:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:28:19 +0000 |
commit | 18657a960e125336f704ea058e25c27bd3900dcb (patch) | |
tree | 17b438b680ed45a996d7b59951e6aa34023783f2 /doc/wal-lock.md | |
parent | Initial commit. (diff) | |
download | sqlite3-upstream.tar.xz sqlite3-upstream.zip |
Adding upstream version 3.40.1.upstream/3.40.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/wal-lock.md')
-rw-r--r-- | doc/wal-lock.md | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/doc/wal-lock.md b/doc/wal-lock.md new file mode 100644 index 0000000..d74bb88 --- /dev/null +++ b/doc/wal-lock.md @@ -0,0 +1,88 @@ +# Wal-Mode Blocking Locks + +On some Unix-like systems, SQLite may be configured to use POSIX blocking locks +by: + + * building the library with SQLITE\_ENABLE\_SETLK\_TIMEOUT defined, and + * configuring a timeout in ms using the sqlite3\_busy\_timeout() API. + +Blocking locks may be advantageous as (a) waiting database clients do not +need to continuously poll the database lock, and (b) using blocking locks +facilitates transfer of OS priority between processes when a high priority +process is blocked by a lower priority one. + +Only read/write clients use blocking locks. Clients that have read-only access +to the \*-shm file nevery use blocking locks. + +Threads or processes that access a single database at a time never deadlock as +a result of blocking database locks. But it is of course possible for threads +that lock multiple databases simultaneously to do so. In most cases the OS will +detect the deadlock and return an error. + +## Wal Recovery + +Wal database "recovery" is a process required when the number of connected +database clients changes from zero to one. In this case, a client is +considered to connect to the database when it first reads data from it. +Before recovery commences, an exclusive WRITER lock is taken. + +Without blocking locks, if two clients attempt recovery simultaneously, one +fails to obtain the WRITER lock and either invokes the busy-handler callback or +returns SQLITE\_BUSY to the user. With blocking locks configured, the second +client blocks on the WRITER lock. + +## Database Readers + +Usually, read-only are not blocked by any other database clients, so they +have no need of blocking locks. + +If a read-only transaction is being opened on a snapshot, the CHECKPOINTER +lock is required briefly as part of opening the transaction (to check that a +checkpointer is not currently overwriting the snapshot being opened). A +blocking lock is used to obtain the CHECKPOINTER lock in this case. A snapshot +opener may therefore block on and transfer priority to a checkpointer in some +cases. + +## Database Writers + +A database writer must obtain the exclusive WRITER lock. It uses a blocking +lock to do so if any of the following are true: + + * the transaction is an implicit one consisting of a single DML or DDL + statement, or + * the transaction is opened using BEGIN IMMEDIATE or BEGIN EXCLUSIVE, or + * the first SQL statement executed following the BEGIN command is a DML or + DDL statement (not a read-only statement like a SELECT). + +In other words, in all cases except when an open read-transaction is upgraded +to a write-transaction. In that case a non-blocking lock is used. + +## Database Checkpointers + +Database checkpointers takes the following locks, in order: + + * The exclusive CHECKPOINTER lock. + * The exclusive WRITER lock (FULL, RESTART and TRUNCATE only). + * Exclusive lock on read-mark slots 1-N. These are immediately released after being taken. + * Exclusive lock on read-mark 0. + * Exclusive lock on read-mark slots 1-N again. These are immediately released + after being taken (RESTART and TRUNCATE only). + +All of the above use blocking locks. + +## Summary + +With blocking locks configured, the only cases in which clients should see an +SQLITE\_BUSY error are: + + * if the OS does not grant a blocking lock before the configured timeout + expires, and + * when an open read-transaction is upgraded to a write-transaction. + +In all other cases the blocking locks implementation should prevent clients +from having to handle SQLITE\_BUSY errors and facilitate appropriate transfer +of priorities between competing clients. + +Clients that lock multiple databases simultaneously must be wary of deadlock. + + |