• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1The 5 states of an historical rollback lock as implemented by the
2xLock, xUnlock, and xCheckReservedLock methods of the sqlite3_io_methods
3objec are:
4
5   UNLOCKED
6   SHARED
7   RESERVED
8   PENDING
9   EXCLUSIVE
10
11The wal-index file has a similar locking hierarchy implemented using
12the xShmLock method of the sqlite3_vfs object, but with 7
13states.  Each connection to a wal-index file must be in one of
14the following 7 states:
15
16   UNLOCKED
17   READ
18   READ_FULL
19   WRITE
20   PENDING
21   CHECKPOINT
22   RECOVER
23
24These roughly correspond to the 5 states of a rollback lock except
25that SHARED is split out into 2 states: READ and READ_FULL and
26there is an extra RECOVER state used for wal-index reconstruction.
27
28The meanings of the various wal-index locking states is as follows:
29
30   UNLOCKED    - The wal-index is not in use.
31
32   READ        - Some prefix of the wal-index is being read. Additional
33                 wal-index information can be appended at any time.  The
34                 newly appended content will be ignored by the holder of
35                 the READ lock.
36
37   READ_FULL   - The entire wal-index is being read.  No new information
38                 can be added to the wal-index.  The holder of a READ_FULL
39                 lock promises never to read pages from the database file
40                 that are available anywhere in the wal-index.
41
42   WRITE       - It is OK to append to the wal-index file and to adjust
43                 the header to indicate the new "last valid frame".
44
45   PENDING     - Waiting on all READ locks to clear so that a
46                 CHECKPOINT lock can be acquired.
47
48   CHECKPOINT  - It is OK to write any WAL data into the database file
49                 and zero the last valid frame field of the wal-index
50                 header.  The wal-index file itself may not be changed
51                 other than to zero the last valid frame field in the
52                 header.
53
54   RECOVER     - Held during wal-index recovery.  Used to prevent a
55                 race if multiple clients try to recover a wal-index at
56                 the same time.
57
58
59A particular lock manager implementation may coalesce one or more of
60the wal-index locking states, though with a reduction in concurrency.
61For example, an implemention might implement only exclusive locking,
62in which case all states would be equivalent to CHECKPOINT, meaning that
63only one reader or one writer or one checkpointer could be active at a
64time.  Or, an implementation might combine READ and READ_FULL into
65a single state equivalent to READ, meaning that a writer could
66coexist with a reader, but no reader or writers could coexist with a
67checkpointer.
68
69The lock manager must obey the following rules:
70
71(1)  A READ cannot coexist with CHECKPOINT.
72(2)  A READ_FULL cannot coexist with WRITE.
73(3)  None of WRITE, PENDING, CHECKPOINT, or RECOVER can coexist.
74
75The SQLite core will obey the next set of rules.  These rules are
76assertions on the behavior of the SQLite core which might be verified
77during testing using an instrumented lock manager.
78
79(5)  No part of the wal-index will be read without holding either some
80     kind of SHM lock or an EXCLUSIVE lock on the original database.
81     The original database is the file named in the 2nd parameter to
82     the xShmOpen method.
83
84(6)  A holder of a READ_FULL will never read any page of the database
85     file that is contained anywhere in the wal-index.
86
87(7)  No part of the wal-index other than the header will be written nor
88     will the size of the wal-index grow without holding a WRITE or
89     an EXCLUSIVE on the original database file.
90
91(8)  The wal-index header will not be written without holding one of
92     WRITE, CHECKPOINT, or RECOVER on the wal-index or an EXCLUSIVE on
93     the original database files.
94
95(9)  A CHECKPOINT or RECOVER must be held on the wal-index, or an
96     EXCLUSIVE on the original database file, in order to reset the
97     last valid frame counter in the header of the wal-index back to zero.
98
99(10) A WRITE can only increase the last valid frame pointer in the header.
100
101The SQLite core will only ever send requests for UNLOCK, READ, WRITE,
102CHECKPOINT, or RECOVER to the lock manager.   The SQLite core will never
103request a READ_FULL or PENDING lock though the lock manager may deliver
104those locking states in response to READ and CHECKPOINT requests,
105respectively, if and only if the requested READ or CHECKPOINT cannot
106be delivered.
107
108The following are the allowed lock transitions:
109
110       Original-State     Request         New-State
111       --------------     ----------      ----------
112(11a)  UNLOCK             READ            READ
113(11b)  UNLOCK             READ            READ_FULL
114(11c)  UNLOCK             CHECKPOINT      PENDING
115(11d)  UNLOCK             CHECKPOINT      CHECKPOINT
116(11e)  READ               UNLOCK          UNLOCK
117(11f)  READ               WRITE           WRITE
118(11g)  READ               RECOVER         RECOVER
119(11h)  READ_FULL          UNLOCK          UNLOCK
120(11i)  READ_FULL          WRITE           WRITE
121(11j)  READ_FULL          RECOVER         RECOVER
122(11k)  WRITE              READ            READ
123(11l)  PENDING            UNLOCK          UNLOCK
124(11m)  PENDING            CHECKPOINT      CHECKPOINT
125(11n)  CHECKPOINT         UNLOCK          UNLOCK
126(11o)  RECOVER            READ            READ
127
128These 15 transitions are all that needs to be supported.  The lock
129manager implementation can assert that fact.  The other 27 possible
130transitions among the 7 locking states will never occur.
131