@polycode-projects/the-mechanical-code-talker 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/bin/tmct.mjs +4 -5
  2. package/corpus/LICENSES.json +19 -4
  3. package/corpus/README.md +48 -0
  4. package/corpus/generated/README.md +24 -9
  5. package/corpus/generated/ace-surface-variants.jsonl +4 -1
  6. package/corpus/generated/manifest.json +4 -4
  7. package/corpus/prose/manifest.json +512 -0
  8. package/corpus/prose/sqlite/LICENSE-NOTICE +53 -0
  9. package/corpus/prose/sqlite/arch.txt +213 -0
  10. package/corpus/prose/sqlite/atomiccommit.txt +1117 -0
  11. package/corpus/prose/sqlite/faq.txt +473 -0
  12. package/corpus/prose/sqlite/fileformat.txt +1589 -0
  13. package/corpus/prose/sqlite/lang_createtable.txt +1339 -0
  14. package/corpus/prose/sqlite/lang_insert.txt +580 -0
  15. package/corpus/prose/sqlite/lang_select.txt +3293 -0
  16. package/corpus/prose/sqlite/optoverview.txt +908 -0
  17. package/corpus/prose/sqlite/queryplanner.txt +447 -0
  18. package/corpus/prose/sqlite/transactional.txt +41 -0
  19. package/corpus/prose/sqlite/wal.txt +567 -0
  20. package/corpus/prose/sqlite/whentouse.txt +300 -0
  21. package/corpus/prose/wikipedia/Apple.txt +4 -0
  22. package/corpus/prose/wikipedia/Attempto_Controlled_English.txt +169 -0
  23. package/corpus/prose/wikipedia/Automated_planning_and_scheduling.txt +67 -0
  24. package/corpus/prose/wikipedia/Bee.txt +7 -0
  25. package/corpus/prose/wikipedia/Bird.txt +8 -0
  26. package/corpus/prose/wikipedia/Bone.txt +4 -0
  27. package/corpus/prose/wikipedia/Book.txt +7 -0
  28. package/corpus/prose/wikipedia/Bread.txt +6 -0
  29. package/corpus/prose/wikipedia/Butterfly.txt +6 -0
  30. package/corpus/prose/wikipedia/Car.txt +1 -0
  31. package/corpus/prose/wikipedia/Cat.txt +1 -0
  32. package/corpus/prose/wikipedia/Child.txt +3 -0
  33. package/corpus/prose/wikipedia/City.txt +2 -0
  34. package/corpus/prose/wikipedia/Clock.txt +2 -0
  35. package/corpus/prose/wikipedia/Cooking.txt +1 -0
  36. package/corpus/prose/wikipedia/Description_logic.txt +660 -0
  37. package/corpus/prose/wikipedia/Doctor.txt +6 -0
  38. package/corpus/prose/wikipedia/Dog.txt +4 -0
  39. package/corpus/prose/wikipedia/Eagle.txt +4 -0
  40. package/corpus/prose/wikipedia/Emotion.txt +9 -0
  41. package/corpus/prose/wikipedia/Eye.txt +5 -0
  42. package/corpus/prose/wikipedia/Family.txt +3 -0
  43. package/corpus/prose/wikipedia/Farm.txt +4 -0
  44. package/corpus/prose/wikipedia/Fear.txt +4 -0
  45. package/corpus/prose/wikipedia/First-order_logic.txt +1518 -0
  46. package/corpus/prose/wikipedia/Fish.txt +10 -0
  47. package/corpus/prose/wikipedia/Flower.txt +3 -0
  48. package/corpus/prose/wikipedia/Food.txt +10 -0
  49. package/corpus/prose/wikipedia/Grass.txt +9 -0
  50. package/corpus/prose/wikipedia/Hand.txt +2 -0
  51. package/corpus/prose/wikipedia/Happiness.txt +3 -0
  52. package/corpus/prose/wikipedia/Heart.txt +4 -0
  53. package/corpus/prose/wikipedia/Horse.txt +4 -0
  54. package/corpus/prose/wikipedia/House.txt +6 -0
  55. package/corpus/prose/wikipedia/Human.txt +4 -0
  56. package/corpus/prose/wikipedia/Insect.txt +6 -0
  57. package/corpus/prose/wikipedia/Interactive_fiction.txt +112 -0
  58. package/corpus/prose/wikipedia/Knowledge.txt +5 -0
  59. package/corpus/prose/wikipedia/Knowledge_representation_and_reasoning.txt +87 -0
  60. package/corpus/prose/wikipedia/LICENSE-NOTICE +94 -0
  61. package/corpus/prose/wikipedia/Language.txt +10 -0
  62. package/corpus/prose/wikipedia/Learning.txt +4 -0
  63. package/corpus/prose/wikipedia/Mammal.txt +3 -0
  64. package/corpus/prose/wikipedia/Memory.txt +5 -0
  65. package/corpus/prose/wikipedia/Milk.txt +1 -0
  66. package/corpus/prose/wikipedia/Mountain.txt +1 -0
  67. package/corpus/prose/wikipedia/Natural_language_processing.txt +211 -0
  68. package/corpus/prose/wikipedia/Ostrich.txt +2 -0
  69. package/corpus/prose/wikipedia/Owl.txt +2 -0
  70. package/corpus/prose/wikipedia/Penguin.txt +2 -0
  71. package/corpus/prose/wikipedia/Plant.txt +5 -0
  72. package/corpus/prose/wikipedia/Rain.txt +1 -0
  73. package/corpus/prose/wikipedia/Resource_Description_Framework.txt +184 -0
  74. package/corpus/prose/wikipedia/River.txt +1 -0
  75. package/corpus/prose/wikipedia/School.txt +8 -0
  76. package/corpus/prose/wikipedia/Sea.txt +1 -0
  77. package/corpus/prose/wikipedia/Semantic_Web.txt +114 -0
  78. package/corpus/prose/wikipedia/Semantic_reasoner.txt +29 -0
  79. package/corpus/prose/wikipedia/Snow.txt +5 -0
  80. package/corpus/prose/wikipedia/Sun.txt +5 -0
  81. package/corpus/prose/wikipedia/Teacher.txt +4 -0
  82. package/corpus/prose/wikipedia/Team.txt +3 -0
  83. package/corpus/prose/wikipedia/Text-based_game.txt +17 -0
  84. package/corpus/prose/wikipedia/Tool.txt +4 -0
  85. package/corpus/prose/wikipedia/Tree.txt +7 -0
  86. package/corpus/prose/wikipedia/Weather.txt +4 -0
  87. package/corpus/prose/wikipedia/Web_Ontology_Language.txt +133 -0
  88. package/corpus/prose/wikipedia/Wind.txt +8 -0
  89. package/corpus/prose/wikipedia/Writing.txt +5 -0
  90. package/corpus/wordnet/generate.mjs +6 -7
  91. package/package.json +31 -2
  92. package/src/adapters/corpus/conceptnet.mjs +1 -1
  93. package/src/adapters/graph-build.mjs +3 -3
  94. package/src/adapters/memory/blocks.mjs +2 -2
  95. package/src/adapters/memory/core.mjs +5 -5
  96. package/src/adapters/providers/bootstrap.mjs +1 -1
  97. package/src/adapters/providers/fixture.mjs +1 -1
  98. package/src/adapters/wink-model.mjs +1 -1
  99. package/src/adapters/wordnet-source.mjs +70 -0
  100. package/src/domain/answer-variants.json +1 -1
  101. package/src/domain/ask-vocab.mjs +2 -2
  102. package/src/domain/ask.mjs +4 -4
  103. package/src/domain/codegraph.mjs +3 -3
  104. package/src/domain/corpus-matrix.mjs +87 -0
  105. package/src/domain/grammar/ace.mjs +11 -11
  106. package/src/domain/grammar/lexicon.mjs +3 -3
  107. package/src/domain/inflect.mjs +67 -0
  108. package/src/domain/interpret/fuzzy.mjs +1 -1
  109. package/src/domain/interpret/merge.mjs +1 -1
  110. package/src/domain/interpret/normalize.mjs +1 -1
  111. package/src/domain/licences.mjs +68 -0
  112. package/src/domain/memory/capability.mjs +1 -1
  113. package/src/domain/memory/trust.mjs +2 -2
  114. package/src/domain/persona/codegen.mjs +123 -0
  115. package/src/domain/persona/examples.mjs +26 -0
  116. package/src/domain/persona/tiers.mjs +270 -0
  117. package/src/domain/publish-gate.mjs +41 -0
  118. package/src/domain/router/call-validator.mjs +1 -1
  119. package/src/domain/router/drive.mjs +3 -4
  120. package/src/domain/router/registry.mjs +12 -13
  121. package/src/domain/router/resolver.mjs +18 -5
  122. package/src/domain/router/results.mjs +3 -3
  123. package/src/domain/router/taught.mjs +4 -3
  124. package/src/domain/schemaorg/turtle.mjs +25 -0
  125. package/src/domain/semcor/parse.mjs +87 -0
  126. package/src/domain/syllogise.mjs +6 -6
  127. package/src/domain/version-stamp.mjs +36 -0
  128. package/src/domain/wordnet/yaml.mjs +133 -0
  129. package/src/services/chat-session.mjs +2 -2
  130. package/src/services/chat.mjs +2 -2
  131. package/src/services/cli-args.mjs +4 -4
  132. package/src/services/finish.mjs +1 -1
  133. package/src/services/ledger-viz.mjs +2 -3
  134. package/src/services/sessions.mjs +4 -4
  135. package/src/services/viz-theme.mjs +3 -4
  136. package/src/surfaces/web/memory-ask-browser.bundle.js +1 -18
  137. package/src/domain/router/guardrail.mjs +0 -116
@@ -0,0 +1,1117 @@
1
+ Atomic Commit In SQLite
2
+ Small. Fast. Reliable.
3
+ Choose any three.
4
+ Home
5
+ Menu
6
+ About
7
+ Documentation
8
+ Download
9
+ License
10
+ Support
11
+ Purchase
12
+ Search
13
+ About
14
+ Documentation
15
+ Download
16
+ Support
17
+ Purchase
18
+ Search Documentation
19
+ Search Changelog
20
+ Atomic Commit In SQLite
21
+ Table Of Contents
22
+ 1. Introduction
23
+ 2. Hardware Assumptions
24
+ 3. Single File Commit
25
+ 3.1. Initial State
26
+ 3.2. Acquiring A Read Lock
27
+ 3.3. Reading Information Out Of The Database
28
+ 3.4. Obtaining A Reserved Lock
29
+ 3.5. Creating A Rollback Journal File
30
+ 3.6. Changing Database Pages In User Space
31
+ 3.7. Flushing The Rollback Journal File To Mass Storage
32
+ 3.8. Obtaining An Exclusive Lock
33
+ 3.9. Writing Changes To The Database File
34
+ 3.10. Flushing Changes To Mass Storage
35
+ 3.11. Deleting The Rollback Journal
36
+ 3.12. Releasing The Lock
37
+ 4. Rollback
38
+ 4.1. When Something Goes Wrong...
39
+ 4.2. Hot Rollback Journals
40
+ 4.3. Obtaining An Exclusive Lock On The Database
41
+ 4.4. Rolling Back Incomplete Changes
42
+ 4.5. Deleting The Hot Journal
43
+ 4.6. Continue As If The Uncompleted Writes Had Never Happened
44
+ 5. Multi-file Commit
45
+ 5.1. Separate Rollback Journals For Each Database
46
+ 5.2. The Super-Journal File
47
+ 5.3. Updating Rollback Journal Headers
48
+ 5.4. Updating The Database Files
49
+ 5.5. Delete The Super-Journal File
50
+ 5.6. Clean Up The Rollback Journals
51
+ 6. Additional Details Of The Commit Process
52
+ 6.1. Always Journal Complete Sectors
53
+ 6.2. Dealing With Garbage Written Into Journal Files
54
+ 6.3. Cache Spill Prior To Commit
55
+ 7. Optimizations
56
+ 7.1. Cache Retained Between Transactions
57
+ 7.2. Exclusive Access Mode
58
+ 7.3. Do Not Journal Freelist Pages
59
+ 7.4. Single Page Updates And Atomic Sector Writes
60
+ 7.5. Filesystems With Safe Append Semantics
61
+ 7.6. Persistent Rollback Journals
62
+ 8. Testing Atomic Commit Behavior
63
+ 9. Things That Can Go Wrong
64
+ 9.1. Broken Locking Implementations
65
+ 9.2. Incomplete Disk Flushes
66
+ 9.3. Partial File Deletions
67
+ 9.4. Garbage Written Into Files
68
+ 9.5. Deleting Or Renaming A Hot Journal
69
+ 10. Future Directions And Conclusion
70
+ 1. Introduction
71
+ An important feature of transactional databases like SQLite
72
+ is "atomic commit".
73
+ Atomic commit means that either all database changes within a single
74
+ transaction occur or none of them occur. With atomic commit, it
75
+ is as if many different writes to different sections of the database
76
+ file occur instantaneously and simultaneously.
77
+ Real hardware serializes writes to mass storage, and writing
78
+ a single sector takes a finite amount of time.
79
+ So it is impossible to truly write many different sectors of a
80
+ database file simultaneously and/or instantaneously.
81
+ But the atomic commit logic within
82
+ SQLite makes it appear as if the changes for a transaction
83
+ are all written instantaneously and simultaneously.
84
+ SQLite has the important property that transactions appear
85
+ to be atomic even if the transaction is interrupted by an
86
+ operating system crash or power failure.
87
+ This article describes the techniques used by SQLite to create the
88
+ illusion of atomic commit.
89
+ The information in this article applies only when SQLite is operating
90
+ in "rollback mode", or in other words when SQLite is not
91
+ using a write-ahead log . SQLite still supports atomic commit when
92
+ write-ahead logging is enabled, but it accomplishes atomic commit by
93
+ a different mechanism from the one described in this article. See
94
+ the write-ahead log documentation for additional information on how
95
+ SQLite supports atomic commit in that context.
96
+ 2. Hardware Assumptions
97
+ Throughout this article, we will call the mass storage device "disk"
98
+ even though the mass storage device might really be flash memory.
99
+ We assume that disk is written in chunks which we call a "sector".
100
+ It is not possible to modify any part of the disk smaller than a sector.
101
+ To change a part of the disk smaller than a sector, you have to read in
102
+ the full sector that contains the part you want to change, make the
103
+ change, then write back out the complete sector.
104
+ On a traditional spinning disk, a sector is the minimum unit of transfer
105
+ in both directions, both reading and writing. On flash memory, however,
106
+ the minimum size of a read is typically much smaller than a minimum write.
107
+ SQLite is only concerned with the minimum write amount and so for the
108
+ purposes of this article, when we say "sector" we mean the minimum amount
109
+ of data that can be written to mass storage in a single go.
110
+ Prior to SQLite version 3.3.14, a sector size of 512 bytes was
111
+ assumed in all cases. There was a compile-time option to change
112
+ this but the code had never been tested with a larger value. The
113
+ 512 byte sector assumption seemed reasonable since until very recently
114
+ all disk drives used a 512 byte sector internally. However, there
115
+ has recently been a push to increase the sector size of disks to
116
+ 4096 bytes. Also the sector size
117
+ for flash memory is usually larger than 512 bytes. For these reasons,
118
+ versions of SQLite beginning with 3.3.14 have a method in the OS
119
+ interface layer that interrogates the underlying filesystem to find
120
+ the true sector size. As currently implemented (version 3.5.0) this
121
+ method still returns a hard-coded value of 512 bytes, since there
122
+ is no standard way of discovering the true sector size on either
123
+ Unix or Windows. But the method is available for embedded device
124
+ manufacturers to tweak according to their own needs. And we have
125
+ left open the possibility of filling in a more meaningful implementation
126
+ on Unix and Windows in the future.
127
+ SQLite has traditionally assumed that a sector write is not atomic.
128
+ However, SQLite does always assume that a sector write is linear. By "linear"
129
+ we mean that SQLite assumes that when writing a sector, the hardware begins
130
+ at one end of the data and writes byte by byte until it gets to
131
+ the other end. The write might go from beginning to end or from
132
+ end to beginning. If a power failure occurs in the middle of a
133
+ sector write it might be that part of the sector was modified
134
+ and another part was left unchanged. The key assumption by SQLite
135
+ is that if any part of the sector gets changed, then either the
136
+ first or the last bytes will be changed. So the hardware will
137
+ never start writing a sector in the middle and work towards the
138
+ ends. We do not know if this assumption is always true but it
139
+ seems reasonable.
140
+ The previous paragraph states that SQLite does not assume that
141
+ sector writes are atomic. This is true by default. But as of
142
+ SQLite version 3.5.0, there is a new interface called the
143
+ Virtual File System ( VFS ) interface. The VFS is the only means
144
+ by which SQLite communicates to the underlying filesystem. The
145
+ code comes with default VFS implementations for Unix and Windows
146
+ and there is a mechanism for creating new custom VFS implementations
147
+ at runtime. In this new VFS interface there is a method called
148
+ xDeviceCharacteristics. This method interrogates the underlying
149
+ filesystem to discover various properties and behaviors that the
150
+ filesystem may or may not exhibit. The xDeviceCharacteristics
151
+ method might indicate that sector writes are atomic, and if it does
152
+ so indicate, SQLite will try to take advantage of that fact. But
153
+ the default xDeviceCharacteristics method for both Unix and Windows
154
+ does not indicate atomic sector writes and so these optimizations
155
+ are normally omitted.
156
+ SQLite assumes that the operating system will buffer writes and
157
+ that a write request will return before data has actually been stored
158
+ in the mass storage device.
159
+ SQLite further assumes that write operations will be reordered by
160
+ the operating system.
161
+ For this reason, SQLite does a "flush" or "fsync" operation at key
162
+ points. SQLite assumes that the flush or fsync will not return until
163
+ all pending write operations for the file that is being flushed have
164
+ completed. We are told that the flush and fsync primitives
165
+ are broken on some versions of Windows and Linux. This is unfortunate.
166
+ It opens SQLite up to the possibility of database corruption following
167
+ a power loss in the middle of a commit. However, there is nothing
168
+ that SQLite can do to test for or remedy the situation. SQLite
169
+ assumes that the operating system that it is running on works as
170
+ advertised. If that is not quite the case, well then hopefully you
171
+ will not lose power too often.
172
+ SQLite assumes that when a file grows in length that the new
173
+ file space originally contains garbage and then later is filled in
174
+ with the data actually written. In other words, SQLite assumes that
175
+ the file size is updated before the file content. This is a
176
+ pessimistic assumption and SQLite has to do some extra work to make
177
+ sure that it does not cause database corruption if power is lost
178
+ between the time when the file size is increased and when the
179
+ new content is written. The xDeviceCharacteristics method of
180
+ the VFS might indicate that the filesystem will always write the
181
+ data before updating the file size. (This is the
182
+ SQLITE_IOCAP_SAFE_APPEND property for those readers who are looking
183
+ at the code.) When the xDeviceCharacteristics method indicates
184
+ that files content is written before the file size is increased,
185
+ SQLite can forego some of its pedantic database protection steps
186
+ and thereby decrease the amount of disk I/O needed to perform a
187
+ commit. The current implementation, however, makes no such assumptions
188
+ for the default VFSes for Windows and Unix.
189
+ SQLite assumes that a file deletion is atomic from the
190
+ point of view of a user process. By this we mean that if SQLite
191
+ requests that a file be deleted and the power is lost during the
192
+ delete operation, once power is restored either the file will
193
+ exist completely with all if its original content unaltered, or
194
+ else the file will not be seen in the filesystem at all. If
195
+ after power is restored the file is only partially deleted,
196
+ if some of its data has been altered or erased,
197
+ or the file has been truncated but not completely removed, then
198
+ database corruption will likely result.
199
+ SQLite assumes that the detection and/or correction of
200
+ bit errors caused by cosmic rays, thermal noise, quantum
201
+ fluctuations, device driver bugs, or other mechanisms, is the
202
+ responsibility of the underlying hardware and operating system.
203
+ SQLite does not add any redundancy to the database file for
204
+ the purpose of detecting corruption or I/O errors.
205
+ SQLite assumes that the data it reads is exactly the same data
206
+ that it previously wrote.
207
+ By default, SQLite assumes that an operating system call to write
208
+ a range of bytes will not damage or alter any bytes outside of that range
209
+ even if a power loss or OS crash occurs during that write. We
210
+ call this the " powersafe overwrite " property.
211
+ Prior to version 3.7.9 (2011-11-01),
212
+ SQLite did not assume powersafe overwrite. But with the standard
213
+ sector size increasing from 512 to 4096 bytes on most disk drives, it
214
+ has become necessary to assume powersafe overwrite in order to maintain
215
+ historical performance levels and so powersafe overwrite is assumed by
216
+ default in recent versions of SQLite. The assumption of powersafe
217
+ overwrite property can be disabled at compile-time or at run-time if
218
+ desired. See the powersafe overwrite documentation for further
219
+ details.
220
+ 3. Single File Commit
221
+ We begin with an overview of the steps SQLite takes in order to
222
+ perform an atomic commit of a transaction against a single database
223
+ file. The details of file formats used to guard against damage from
224
+ power failures and techniques for performing an atomic commit across
225
+ multiple databases are discussed in later sections.
226
+ 3.1. Initial State
227
+ The state of the computer when a database connection is
228
+ first opened is shown conceptually by the diagram at the
229
+ right.
230
+ The area of the diagram on the extreme right (labeled "Disk") represents
231
+ information stored on the mass storage device. Each rectangle is
232
+ a sector. The blue color represents that the sectors contain
233
+ original data.
234
+ The middle area is the operating systems disk cache. At the
235
+ onset of our example, the cache is cold and this is represented
236
+ by leaving the rectangles of the disk cache empty.
237
+ The left area of the diagram shows the content of memory for
238
+ the process that is using SQLite. The database connection has
239
+ just been opened and no information has been read yet, so the
240
+ user space is empty.
241
+ 3.2. Acquiring A Read Lock
242
+ Before SQLite can write to a database, it must first read
243
+ the database to see what is there already. Even if it is just
244
+ appending new data, SQLite still has to read in the database
245
+ schema from the " sqlite_schema " table so that it can know
246
+ how to parse the INSERT statements and discover where in the
247
+ database file the new information should be stored.
248
+ The first step toward reading from the database file
249
+ is obtaining a shared lock on the database file. A "shared"
250
+ lock allows two or more database connections to read from the
251
+ database file at the same time. But a shared lock prevents
252
+ another database connection from writing to the database file
253
+ while we are reading it. This is necessary because if another
254
+ database connection were writing to the database file at the
255
+ same time we are reading from the database file, we might read
256
+ some data before the change and other data after the change.
257
+ This would make it appear as if the change made by the other
258
+ process is not atomic.
259
+ Notice that the shared lock is on the operating system
260
+ disk cache, not on the disk itself. File locks
261
+ really are just flags within the operating system kernel,
262
+ usually. (The details depend on the specific OS layer
263
+ interface.) Hence, the lock will instantly vanish if the
264
+ operating system crashes or if there is a power loss. It
265
+ is usually also the case that the lock will vanish if the
266
+ process that created the lock exits.
267
+ 3.3. Reading Information Out Of The Database
268
+ After the shared lock is acquired, we can begin reading
269
+ information from the database file. In this scenario, we
270
+ are assuming a cold cache, so information must first be
271
+ read from mass storage into the operating system cache then
272
+ transferred from operating system cache into user space.
273
+ On subsequent reads, some or all of the information might
274
+ already be found in the operating system cache and so only
275
+ the transfer to user space would be required.
276
+ Usually only a subset of the pages in the database file
277
+ are read. In this example we are showing three
278
+ pages out of eight being read. In a typical application, a
279
+ database will have thousands of pages and a query will normally
280
+ only touch a small percentage of those pages.
281
+ 3.4. Obtaining A Reserved Lock
282
+ Before making changes to the database, SQLite first
283
+ obtains a "reserved" lock on the database file. A reserved
284
+ lock is similar to a shared lock in that both a reserved lock
285
+ and shared lock allow other processes to read from the database
286
+ file. A single reserve lock can coexist with multiple shared
287
+ locks from other processes. However, there can only be a
288
+ single reserved lock on the database file. Hence only a
289
+ single process can be attempting to write to the database
290
+ at one time.
291
+ The idea behind a reserved lock is that it signals that
292
+ a process intends to modify the database file in the near
293
+ future but has not yet started to make the modifications.
294
+ And because the modifications have not yet started, other
295
+ processes can continue to read from the database. However,
296
+ no other process should also begin trying to write to the
297
+ database.
298
+ 3.5. Creating A Rollback Journal File
299
+ Prior to making any changes to the database file, SQLite first
300
+ creates a separate rollback journal file and writes into the
301
+ rollback journal the original
302
+ content of the database pages that are to be altered.
303
+ The idea behind the rollback journal is that it contains
304
+ all information needed to restore the database back to
305
+ its original state.
306
+ The rollback journal contains a small header (shown in green
307
+ in the diagram) that records the original size of the database
308
+ file. So if a change causes the database file to grow, we
309
+ will still know the original size of the database. The page
310
+ number is stored together with each database page that is
311
+ written into the rollback journal.
312
+ When a new file is created, most desktop operating systems
313
+ (Windows, Linux, Mac OS X) will not actually write anything to
314
+ disk. The new file is created in the operating systems disk
315
+ cache only. The file is not created on mass storage until sometime
316
+ later, when the operating system has a spare moment. This creates
317
+ the impression to users that I/O is happening much faster than
318
+ is possible when doing real disk I/O. We illustrate this idea in
319
+ the diagram to the right by showing that the new rollback journal
320
+ appears in the operating system disk cache only and not on the
321
+ disk itself.
322
+ 3.6. Changing Database Pages In User Space
323
+ After the original page content has been saved in the rollback
324
+ journal, the pages can be modified in user memory. Each database
325
+ connection has its own private copy of user space, so the changes
326
+ that are made in user space are only visible to the database connection
327
+ that is making the changes. Other database connections still see
328
+ the information in operating system disk cache buffers which have
329
+ not yet been changed. And so even though one process is busy
330
+ modifying the database, other processes can continue to read their
331
+ own copies of the original database content.
332
+ 3.7. Flushing The Rollback Journal File To Mass Storage
333
+ The next step is to flush the content of the rollback journal
334
+ file to nonvolatile storage.
335
+ As we will see later,
336
+ this is a critical step in insuring that the database can survive
337
+ an unexpected power loss.
338
+ This step also takes a lot of time, since writing to nonvolatile
339
+ storage is normally a slow operation.
340
+ This step is usually more complicated than simply flushing
341
+ the rollback journal to the disk. On most platforms two separate
342
+ flush (or fsync()) operations are required. The first flush writes
343
+ out the base rollback journal content. Then the header of the
344
+ rollback journal is modified to show the number of pages in the
345
+ rollback journal. Then the header is flushed to disk. The details
346
+ on why we do this header modification and extra flush are provided
347
+ in a later section of this paper.
348
+ 3.8. Obtaining An Exclusive Lock
349
+ Prior to making changes to the database file itself, we must
350
+ obtain an exclusive lock on the database file. Obtaining an
351
+ exclusive lock is really a two-step process. First SQLite obtains
352
+ a "pending" lock. Then it escalates the pending lock to an
353
+ exclusive lock.
354
+ A pending lock allows other processes that already have a
355
+ shared lock to continue reading the database file. But it
356
+ prevents new shared locks from being established. The idea
357
+ behind a pending lock is to prevent writer starvation caused
358
+ by a large pool of readers. There might be dozens, even hundreds,
359
+ of other processes trying to read the database file. Each process
360
+ acquires a shared lock before it starts reading, reads what it
361
+ needs, then releases the shared lock. If, however, there are
362
+ many different processes all reading from the same database, it
363
+ might happen that a new process always acquires its shared lock before
364
+ the previous process releases its shared lock. And so there is
365
+ never an instant when there are no shared locks on the database
366
+ file and hence there is never an opportunity for the writer to
367
+ seize the exclusive lock. A pending lock is designed to prevent
368
+ that cycle by allowing existing shared locks to proceed but
369
+ blocking new shared locks from being established. Eventually
370
+ all shared locks will clear and the pending lock will then be
371
+ able to escalate into an exclusive lock.
372
+ 3.9. Writing Changes To The Database File
373
+ Once an exclusive lock is held, we know that no other
374
+ processes are reading from the database file and it is
375
+ safe to write changes into the database file. Usually
376
+ those changes only go as far as the operating systems disk
377
+ cache and do not make it all the way to mass storage.
378
+ 3.10. Flushing Changes To Mass Storage
379
+ Another flush must occur to make sure that all the
380
+ database changes are written into nonvolatile storage.
381
+ This is a critical step to ensure that the database will
382
+ survive a power loss without damage. However, because
383
+ of the inherent slowness of writing to disk or flash memory,
384
+ this step together with the rollback journal file flush in section
385
+ 3.7 above takes up most of the time required to complete a
386
+ transaction commit in SQLite.
387
+ 3.11. Deleting The Rollback Journal
388
+ After the database changes are all safely on the mass
389
+ storage device, the rollback journal file is deleted.
390
+ This is the instant where the transaction commits.
391
+ If a power failure or system crash occurs prior to this
392
+ point, then recovery processes to be described later make
393
+ it appear as if no changes were ever made to the database
394
+ file. If a power failure or system crash occurs after
395
+ the rollback journal is deleted, then it appears as if
396
+ all changes have been written to disk. Thus, SQLite gives
397
+ the appearance of having made no changes to the database
398
+ file or having made the complete set of changes to the
399
+ database file depending on whether or not the rollback
400
+ journal file exists.
401
+ Deleting a file is not really an atomic operation, but
402
+ it appears to be from the point of view of a user process.
403
+ A process is always able to ask the operating system "does
404
+ this file exist?" and the process will get back a yes or no
405
+ answer. After a power failure that occurs during a
406
+ transaction commit, SQLite will ask the operating system
407
+ whether or not the rollback journal file exists. If the
408
+ answer is "yes" then the transaction is incomplete and is
409
+ rolled back. If the answer is "no" then it means the transaction
410
+ did commit.
411
+ The existence of a transaction depends on whether or
412
+ not the rollback journal file exists and the deletion
413
+ of a file appears to be an atomic operation from the point of
414
+ view of a user-space process. Therefore,
415
+ a transaction appears to be an atomic operation.
416
+ The act of deleting a file is expensive on many systems.
417
+ As an optimization, SQLite can be configured to truncate
418
+ the journal file to zero bytes in length
419
+ or overwrite the journal file header with zeros. In either
420
+ case, the resulting journal file is no longer capable of rolling
421
+ back and so the transaction still commits. Truncating a file
422
+ to zero length, like deleting a file, is assumed to be an atomic
423
+ operation from the point of view of a user process. Overwriting
424
+ the header of the journal with zeros is not atomic, but if any
425
+ part of the header is malformed the journal will not roll back.
426
+ Hence, one can say that the commit occurs as soon as the header
427
+ is sufficiently changed to make it invalid. Typically this happens
428
+ as soon as the first byte of the header is zeroed.
429
+ 3.12. Releasing The Lock
430
+ The last step in the commit process is to release the
431
+ exclusive lock so that other processes can once again
432
+ start accessing the database file.
433
+ In the diagram at the right, we show that the information
434
+ that was held in user space is cleared when the lock is released.
435
+ This used to be literally true for older versions of SQLite. But
436
+ more recent versions of SQLite keep the user space information
437
+ in memory in case it might be needed again at the start of the
438
+ next transaction. It is cheaper to reuse information that is
439
+ already in local memory than to transfer the information back
440
+ from the operating system disk cache or to read it off of the
441
+ disk drive again. Prior to reusing the information in user space,
442
+ we must first reacquire the shared lock and then we have to check
443
+ to make sure that no other process modified the database file while
444
+ we were not holding a lock. There is a counter in the first page
445
+ of the database that is incremented every time the database file
446
+ is modified. We can find out if another process has modified the
447
+ database by checking that counter. If the database was modified,
448
+ then the user space cache must be cleared and reread. But it is
449
+ commonly the case that no changes have been made and the user
450
+ space cache can be reused for a significant performance savings.
451
+ 4. Rollback
452
+ An atomic commit is supposed to happen instantaneously. But the processing
453
+ described above clearly takes a finite amount of time.
454
+ Suppose the power to the computer were cut
455
+ part way through the commit operation described above. In order
456
+ to maintain the illusion that the changes were instantaneous, we
457
+ have to "rollback" any partial changes and restore the database to
458
+ the state it was in prior to the beginning of the transaction.
459
+ 4.1. When Something Goes Wrong...
460
+ Suppose the power loss occurred
461
+ during step 3.10 above,
462
+ while the database changes were being written to disk.
463
+ After power is restored, the situation might be something
464
+ like what is shown to the right. We were trying to change
465
+ three pages of the database file but only one page was
466
+ successfully written. Another page was partially written
467
+ and a third page was not written at all.
468
+ The rollback journal is complete and intact on disk when
469
+ the power is restored. This is a key point. The reason for
470
+ the flush operation in step 3.7
471
+ is to make absolutely sure that
472
+ all of the rollback journal is safely on nonvolatile storage
473
+ prior to making any changes to the database file itself.
474
+ 4.2. Hot Rollback Journals
475
+ The first time that any SQLite process attempts to access
476
+ the database file, it obtains a shared lock as described in
477
+ section 3.2 above.
478
+ But then it notices that there is a
479
+ rollback journal file present. SQLite then checks to see if
480
+ the rollback journal is a "hot journal". A hot journal is
481
+ a rollback journal that needs to be played back in order to
482
+ restore the database to a sane state. A hot journal only
483
+ exists when an earlier process was in the middle of committing
484
+ a transaction when it crashed or lost power.
485
+ A rollback journal is a "hot" journal if all of the following
486
+ are true:
487
+ The rollback journal exists.
488
+ The rollback journal is not an empty file.
489
+ There is no reserved lock on the main database file.
490
+ The header of the rollback journal is well-formed and in particular
491
+ has not been zeroed out.
492
+ The rollback journal does not
493
+ contain the name of a super-journal file (see
494
+ section 5.5 below) or if does
495
+ contain the name of a super-journal, then that super-journal
496
+ file exists.
497
+ The presence of a hot journal is our indication
498
+ that a previous process was trying to commit a transaction but
499
+ it aborted for some reason prior to the completion of the
500
+ commit. A hot journal means that
501
+ the database file is in an inconsistent state and needs to
502
+ be repaired (by rollback) prior to being used.
503
+ 4.3. Obtaining An Exclusive Lock On The Database
504
+ The first step toward dealing with a hot journal is to
505
+ obtain an exclusive lock on the database file. This prevents two
506
+ or more processes from trying to rollback the same hot journal
507
+ at the same time.
508
+ 4.4. Rolling Back Incomplete Changes
509
+ Once a process obtains an exclusive lock, it is permitted
510
+ to write to the database file. It then proceeds to read the
511
+ original content of pages out of the rollback journal and write
512
+ that content back to where it came from in the database file.
513
+ Recall that the header of the rollback journal records the original
514
+ size of the database file prior to the start of the aborted
515
+ transaction. SQLite uses this information to truncate the
516
+ database file back to its original size in cases where the
517
+ incomplete transaction caused the database to grow. At the
518
+ end of this step, the database should be the same size and
519
+ contain the same information as it did before the start of
520
+ the aborted transaction.
521
+ 4.5. Deleting The Hot Journal
522
+ After all information in the rollback journal has been
523
+ played back into the database file (and flushed to disk in case
524
+ we encounter yet another power failure), the hot rollback journal
525
+ can be deleted.
526
+ As in section 3.11 , the journal
527
+ file might be truncated to zero length or its header might
528
+ be overwritten with zeros as an optimization on systems where
529
+ deleting a file is expensive. Either way, the journal is no
530
+ longer hot after this step.
531
+ 4.6. Continue As If The Uncompleted Writes Had Never Happened
532
+ The final recovery step is to reduce the exclusive lock back
533
+ to a shared lock. Once this happens, the database is back in the
534
+ state that it would have been if the aborted transaction had never
535
+ started. Since all of this recovery activity happens completely
536
+ automatically and transparently, it appears to the program using
537
+ SQLite as if the aborted transaction had never begun.
538
+ 5. Multi-file Commit
539
+ SQLite allows a single
540
+ database connection to talk to
541
+ two or more database files simultaneously through the use of
542
+ the ATTACH DATABASE command.
543
+ When multiple database files are modified within a single
544
+ transaction, all files are updated atomically.
545
+ In other words, either all of the database files are updated or
546
+ else none of them are.
547
+ Achieving an atomic commit across multiple database files is
548
+ more complex that doing so for a single file. This section
549
+ describes how SQLite works that bit of magic.
550
+ 5.1. Separate Rollback Journals For Each Database
551
+ When multiple database files are involved in a transaction,
552
+ each database has its own rollback journal and each database
553
+ is locked separately. The diagram at the right shows a scenario
554
+ where three different database files have been modified within
555
+ one transaction. The situation at this step is analogous to
556
+ the single-file transaction scenario at
557
+ step 3.6 . Each database file has
558
+ a reserved lock. For each database, the original content of pages
559
+ that are being changed have been written into the rollback journal
560
+ for that database, but the content of the journals have not yet
561
+ been flushed to disk. No changes have been made to the database
562
+ file itself yet, though presumably there are changes being held
563
+ in user memory.
564
+ For brevity, the diagrams in this section are simplified from
565
+ those that came before. Blue color still signifies original content
566
+ and pink still signifies new content. But the individual pages
567
+ in the rollback journal and the database file are not shown and
568
+ we are not making the distinction between information in the
569
+ operating system cache and information that is on disk. All of
570
+ these factors still apply in a multi-file commit scenario. They
571
+ just take up a lot of space in the diagrams and they do not add
572
+ any new information, so they are omitted here.
573
+ 5.2. The Super-Journal File
574
+ The next step in a multi-file commit is the creation of a
575
+ "super-journal" file. The name of the super-journal file is
576
+ the same name as the original database filename (the database
577
+ that was opened using the
578
+ sqlite3_open() interface,
579
+ not one of the ATTACHed auxiliary
580
+ databases) with the text " -mj HHHHHHHH " appended where
581
+ HHHHHHHH is a random 32-bit hexadecimal number. The
582
+ random HHHHHHHH suffix changes for every new super-journal.
583
+ (Nota bene: The formula for computing the super-journal filename
584
+ given in the previous paragraph corresponds to the implementation as
585
+ of SQLite version 3.5.0. But this formula is not part of the SQLite
586
+ specification and is subject to change in future releases.)
587
+ Unlike the rollback journals, the super-journal does not contain
588
+ any original database page content. Instead, the super-journal contains
589
+ the full pathnames for rollback journals for every database that is
590
+ participating in the transaction.
591
+ After the super-journal is constructed, its content is flushed
592
+ to disk before any further actions are taken. On Unix, the directory
593
+ that contains the super-journal is also synced in order to make sure
594
+ the super-journal file will appear in the directory following a
595
+ power failure.
596
+ The purpose of the super-journal is to ensure that multi-file
597
+ transactions are atomic across a power-loss. But if the database files
598
+ have other settings that compromise integrity across a power-loss event
599
+ (such as PRAGMA synchronous=OFF or PRAGMA journal_mode=MEMORY ) then
600
+ the creation of the super-journal is omitted, as an optimization.
601
+ 5.3. Updating Rollback Journal Headers
602
+ The next step is to record the full pathname of the super-journal file
603
+ in the header of every rollback journal. Space to hold the
604
+ super-journal filename was reserved at the beginning of each rollback journal
605
+ as the rollback journals were created.
606
+ The content of each rollback journal is flushed to disk both before
607
+ and after the super-journal filename is written into the rollback
608
+ journal header. It is important to do both of these flushes. Fortunately,
609
+ the second flush is usually inexpensive since typically only a single
610
+ page of the journal file (the first page) has changed.
611
+ This step is analogous to
612
+ step 3.7 in the single-file commit
613
+ scenario described above.
614
+ 5.4. Updating The Database Files
615
+ Once all rollback journal files have been flushed to disk, it
616
+ is safe to begin updating database files. We have to obtain an
617
+ exclusive lock on all database files before writing the changes.
618
+ After all the changes are written, it is important to flush the
619
+ changes to disk so that they will be preserved in the event of
620
+ a power failure or operating system crash.
621
+ This step corresponds to steps
622
+ 3.8 ,
623
+ 3.9 , and
624
+ 3.10 in the single-file commit
625
+ scenario described previously.
626
+ 5.5. Delete The Super-Journal File
627
+ The next step is to delete the super-journal file.
628
+ This is the point where the multi-file transaction commits.
629
+ This step corresponds to
630
+ step 3.11 in the single-file
631
+ commit scenario where the rollback journal is deleted.
632
+ If a power failure or operating system crash occurs at this
633
+ point, the transaction will not rollback when the system reboots
634
+ even though there are rollback journals present. The
635
+ difference is the super-journal pathname in the header of the
636
+ rollback journal. Upon restart, SQLite only considers a journal
637
+ to be hot and will only playback the journal if there is no
638
+ super-journal filename in the header (which is the case for
639
+ a single-file commit) or if the super-journal file still
640
+ exists on disk.
641
+ 5.6. Clean Up The Rollback Journals
642
+ The final step in a multi-file commit is to delete the
643
+ individual rollback journals and drop the exclusive locks on
644
+ the database files so that other processes can see the changes.
645
+ This corresponds to
646
+ step 3.12 in the single-file
647
+ commit sequence.
648
+ The transaction has already committed at this point so timing
649
+ is not critical in the deletion of the rollback journals.
650
+ The current implementation deletes a single rollback journal
651
+ then unlocks the corresponding database file before proceeding
652
+ to the next rollback journal. But in the future we might change
653
+ this so that all rollback journals are deleted before any database
654
+ files are unlocked. As long as the rollback journal is deleted before
655
+ its corresponding database file is unlocked it does not matter in what
656
+ order the rollback journals are deleted or the database files are
657
+ unlocked.
658
+ 6. Additional Details Of The Commit Process
659
+ Section 3.0 above provides an overview of
660
+ how atomic commit works in SQLite. But it glosses over a number of
661
+ important details. The following subsections will attempt to fill
662
+ in the gaps.
663
+ 6.1. Always Journal Complete Sectors
664
+ When the original content of a database page is written into
665
+ the rollback journal (as shown in section 3.5 ),
666
+ SQLite always writes a complete sector of data, even if the
667
+ page size of the database is smaller than the sector size.
668
+ Historically, the sector size in SQLite has been hard coded to 512
669
+ bytes and since the minimum page size is also 512 bytes, this has never
670
+ been an issue. But beginning with SQLite version 3.3.14, it is possible
671
+ for SQLite to use mass storage devices with a sector size larger than 512
672
+ bytes. So, beginning with version 3.3.14, whenever any page within a
673
+ sector is written into the journal file, all pages in that same sector
674
+ are stored with it.
675
+ It is important to store all pages of a sector in the rollback
676
+ journal in order to prevent database corruption following a power
677
+ loss while writing the sector. Suppose that pages 1, 2, 3, and 4 are
678
+ all stored in sector 1 and that page 2 is modified. In order to write
679
+ the changes to page 2, the underlying hardware must also rewrite the
680
+ content of pages 1, 3, and 4 since the hardware must write the complete
681
+ sector. If this write operation is interrupted by a power outage,
682
+ one or more of the pages 1, 3, or 4 might be left with incorrect data.
683
+ Hence, to avoid lasting corruption to the database, the original content
684
+ of all of those pages must be contained in the rollback journal.
685
+ 6.2. Dealing With Garbage Written Into Journal Files
686
+ When data is appended to the end of the rollback journal,
687
+ SQLite normally makes the pessimistic assumption that the file
688
+ is first extended with invalid "garbage" data and that afterwards
689
+ the correct data replaces the garbage. In other words, SQLite assumes
690
+ that the file size is increased first and then afterwards the content
691
+ is written into the file. If a power failure occurs after the file
692
+ size has been increased but before the file content has been written,
693
+ the rollback journal can be left containing garbage data. If after
694
+ power is restored, another SQLite process sees the rollback journal
695
+ containing the garbage data and tries to roll it back into the original
696
+ database file, it might copy some of the garbage into the database file
697
+ and thus corrupt the database file.
698
+ SQLite uses two defenses against this problem. In the first place,
699
+ SQLite records the number of pages in the rollback journal in the header
700
+ of the rollback journal. This number is initially zero. So during an
701
+ attempt to rollback an incomplete (and possibly corrupt) rollback
702
+ journal, the process doing the rollback will see that the journal
703
+ contains zero pages and will thus make no changes to the database. Prior
704
+ to a commit, the rollback journal is flushed to disk to ensure that
705
+ all content has been synced to disk and there is no "garbage" left
706
+ in the file, and only then is the page count in the header changed from
707
+ zero to the number of pages in the rollback journal. The rollback journal
708
+ header is always kept in a separate sector from any page data so that
709
+ it can be overwritten and flushed without risking damage to a data
710
+ page if a power outage occurs. Notice that the rollback journal
711
+ is flushed to disk twice: once to write the page content and a second
712
+ time to write the page count in the header.
713
+ The previous paragraph describes what happens when the
714
+ synchronous pragma setting is "full".
715
+ PRAGMA synchronous=FULL;
716
+ The default synchronous setting is full so the above is what usually
717
+ happens. However, if the synchronous setting is lowered to "normal",
718
+ SQLite only flushes the rollback journal once, after the page count has
719
+ been written.
720
+ This carries a risk of corruption because it might happen that the
721
+ modified (non-zero) page count reaches the disk surface before all
722
+ of the data does. The data will have been written first, but SQLite
723
+ assumes that the underlying filesystem can reorder write requests and
724
+ that the page count can be burned into oxide first even though its
725
+ write request occurred last. So as a second line of defense, SQLite
726
+ also uses a 32-bit checksum on every page of data in the rollback
727
+ journal. This checksum is evaluated for each page during rollback
728
+ while rolling back a journal as described in
729
+ section 4.4 . If an incorrect checksum
730
+ is seen, the rollback is abandoned. Note that the checksum does
731
+ not guarantee that the page data is correct since there is a small
732
+ but finite probability that the checksum might be right even if the data is
733
+ corrupt. But the checksum does at least make such an error unlikely.
734
+ Note that the checksums in the rollback journal are not necessary
735
+ if the synchronous setting is FULL. We only depend on the checksums
736
+ when synchronous is lowered to NORMAL. Nevertheless, the checksums
737
+ never hurt and so they are included in the rollback journal regardless
738
+ of the synchronous setting.
739
+ 6.3. Cache Spill Prior To Commit
740
+ The commit process shown in section 3.0
741
+ assumes that all database changes fit in memory until it is time to
742
+ commit. This is the common case. But sometimes a larger change will
743
+ overflow the user-space cache prior to transaction commit. In those
744
+ cases, the cache must spill to the database before the transaction
745
+ is complete.
746
+ At the beginning of a cache spill, the status of the database
747
+ connection is as shown in step 3.6 .
748
+ Original page content has been saved in the rollback journal and
749
+ modifications of the pages exist in user memory. To spill the cache,
750
+ SQLite executes steps 3.7 through
751
+ 3.9 . In other words, the rollback journal
752
+ is flushed to disk, an exclusive lock is acquired, and changes are
753
+ written into the database. But the remaining steps are deferred
754
+ until the transaction really commits. A new journal header is
755
+ appended to the end of the rollback journal (in its own sector)
756
+ and the exclusive database lock is retained, but otherwise processing
757
+ returns to step 3.6 . When the transaction
758
+ commits, or if another cache spill occurs, steps
759
+ 3.7 and 3.9 are
760
+ repeated. (Step 3.8 is omitted on second
761
+ and subsequent passes since an exclusive database lock is already held
762
+ due to the first pass.)
763
+ A cache spill causes the lock on the database file to
764
+ escalate from reserved to exclusive. This reduces concurrency.
765
+ A cache spill also causes extra disk flush or fsync operations to
766
+ occur and these operations are slow, hence a cache spill can
767
+ seriously reduce performance.
768
+ For these reasons a cache spill is avoided whenever possible.
769
+ 7. Optimizations
770
+ Profiling indicates that for most systems and in most circumstances
771
+ SQLite spends most of its time doing disk I/O. It follows then that
772
+ anything we can do to reduce the amount of disk I/O will likely have a
773
+ large positive impact on the performance of SQLite. This section
774
+ describes some of the techniques used by SQLite to try to reduce the
775
+ amount of disk I/O to a minimum while still preserving atomic commit.
776
+ 7.1. Cache Retained Between Transactions
777
+ Step 3.12 of the commit process shows
778
+ that once the shared lock has been released, all user-space cache
779
+ images of database content must be discarded. This is done because
780
+ without a shared lock, other processes are free to modify the database
781
+ file content and so any user-space image of that content might become
782
+ obsolete. Consequently, each new transaction would begin by rereading
783
+ data which had previously been read. This is not as bad as it sounds
784
+ at first since the data being read is still likely in the operating
785
+ systems file cache. So the "read" is really just a copy of data
786
+ from kernel space into user space. But even so, it still takes time.
787
+ Beginning with SQLite version 3.3.14 a mechanism has been added
788
+ to try to reduce the needless rereading of data. In newer versions
789
+ of SQLite, the data in the user-space pager cache is retained when
790
+ the lock on the database file is released. Later, after the
791
+ shared lock is acquired at the beginning of the next transaction,
792
+ SQLite checks to see if any other process has modified the database
793
+ file. If the database has been changed in any way since the lock
794
+ was last released, the user-space cache is erased at that point.
795
+ But commonly the database file is unchanged and the user-space cache
796
+ can be retained, and some unnecessary read operations can be avoided.
797
+ In order to determine whether or not the database file has changed,
798
+ SQLite uses a counter in the database header (in bytes 24 through 27)
799
+ which is incremented during every change operation. SQLite saves a copy
800
+ of this counter prior to releasing its database lock. Then after
801
+ acquiring the next database lock it compares the saved counter value
802
+ against the current counter value and erases the cache if the values
803
+ are different, or reuses the cache if they are the same.
804
+ 7.2. Exclusive Access Mode
805
+ SQLite version 3.3.14 adds the concept of "Exclusive Access Mode".
806
+ In exclusive access mode, SQLite retains the exclusive
807
+ database lock at the conclusion of each transaction. This prevents
808
+ other processes from accessing the database, but in many deployments
809
+ only a single process is using a database so this is not a
810
+ serious problem. The advantage of exclusive access mode is that
811
+ disk I/O can be reduced in three ways:
812
+ It is not necessary to increment the change counter in the
813
+ database header for transactions after the first transaction. This
814
+ will often save a write of page one to both the rollback
815
+ journal and the main database file.
816
+ No other processes can change the database so there is never
817
+ a need to check the change counter and clear the user-space cache
818
+ at the beginning of a transaction.
819
+ Each transaction can be committed by overwriting the rollback
820
+ journal header with zeros rather than deleting the journal file.
821
+ This avoids having to modify the directory entry for the journal file
822
+ and it avoids having to deallocate disk sectors associated with the
823
+ journal. Furthermore, the next transaction will overwrite existing
824
+ journal file content rather than append new content and on most systems
825
+ overwriting is much faster than appending.
826
+ The third optimization, zeroing the journal file header rather than
827
+ deleting the rollback journal file,
828
+ does not depend on holding an exclusive lock at all times.
829
+ This optimization can be set independently of exclusive lock mode
830
+ using the journal_mode pragma
831
+ as described in section 7.6 below.
832
+ 7.3. Do Not Journal Freelist Pages
833
+ When information is deleted from an SQLite database, the pages used
834
+ to hold the deleted information are added to a " freelist ". Subsequent
835
+ inserts will draw pages off of this freelist rather than expanding the
836
+ database file.
837
+ Some freelist pages contain critical data; specifically the locations
838
+ of other freelist pages. But most freelist pages contain nothing useful.
839
+ These latter freelist pages are called "leaf" pages. We are free to
840
+ modify the content of a leaf freelist page in the database without
841
+ changing the meaning of the database in any way.
842
+ Because the content of leaf freelist pages is unimportant, SQLite
843
+ avoids storing leaf freelist page content in the rollback journal
844
+ in step 3.5 of the commit process.
845
+ If a leaf freelist page is changed and that change does not get rolled back
846
+ during a transaction recovery, the database is not harmed by the omission.
847
+ Similarly, the content of a new freelist page is never written back
848
+ into the database at step 3.9 nor
849
+ read from the database at step 3.3 .
850
+ These optimizations can greatly reduce the amount of I/O that occurs
851
+ when making changes to a database file that contains free space.
852
+ 7.4. Single Page Updates And Atomic Sector Writes
853
+ Beginning in SQLite version 3.5.0, the new Virtual File System (VFS)
854
+ interface contains a method named xDeviceCharacteristics which reports
855
+ on special properties that the underlying mass storage device
856
+ might have. Among the special properties that
857
+ xDeviceCharacteristics might report is the ability to do an
858
+ atomic sector write.
859
+ Recall that by default SQLite assumes that sector writes are
860
+ linear but not atomic. A linear write starts at one end of the
861
+ sector and changes information byte by byte until it gets to the
862
+ other end of the sector. If a power loss occurs in the middle of
863
+ a linear write then part of the sector might be modified while the
864
+ other end is unchanged. In an atomic sector write, either the entire
865
+ sector is overwritten or else nothing in the sector is changed.
866
+ We believe that most modern disk drives implement atomic sector
867
+ writes. When power is lost, the drive uses energy stored in capacitors
868
+ and/or the angular momentum of the disk platter to provide power to
869
+ complete any operation in progress. Nevertheless, there are so many
870
+ layers in between the write system call and the on-board disk drive
871
+ electronics that we take the safe approach in both Unix and w32 VFS
872
+ implementations and assume that sector writes are not atomic. On the
873
+ other hand, device
874
+ manufacturers with more control over their filesystems might want
875
+ to consider enabling the atomic write property of xDeviceCharacteristics
876
+ if their hardware really does do atomic writes.
877
+ When sector writes are atomic and the page size of a database is
878
+ the same as a sector size, and when there is a database change that
879
+ only touches a single database page, then SQLite skips the whole
880
+ journaling and syncing process and simply writes the modified page
881
+ directly into the database file. The change counter in the first
882
+ page of the database file is modified separately since no harm is
883
+ done if power is lost before the change counter can be updated.
884
+ 7.5. Filesystems With Safe Append Semantics
885
+ Another optimization introduced in SQLite version 3.5.0 makes
886
+ use of "safe append" behavior of the underlying disk.
887
+ Recall that SQLite assumes that when data is appended to a file
888
+ (specifically to the rollback journal) that the size of the file
889
+ is increased first and that the content is written second. So
890
+ if power is lost after the file size is increased but before the
891
+ content is written, the file is left containing invalid "garbage"
892
+ data. The xDeviceCharacteristics method of the VFS might, however,
893
+ indicate that the filesystem implements "safe append" semantics.
894
+ This means that the content is written before the file size is
895
+ increased so that it is impossible for garbage to be introduced
896
+ into the rollback journal by a power loss or system crash.
897
+ When safe append semantics are indicated for a filesystem,
898
+ SQLite always stores the special value of -1 for the page count
899
+ in the header of the rollback journal. The -1 page count value
900
+ tells any process attempting to rollback the journal that the
901
+ number of pages in the journal should be computed from the journal
902
+ size. This -1 value is never changed. So that when a commit
903
+ occurs, we save a single flush operation and a sector write of
904
+ the first page of the journal file. Furthermore, when a cache
905
+ spill occurs we no longer need to append a new journal header
906
+ to the end of the journal; we can simply continue appending
907
+ new pages to the end of the existing journal.
908
+ 7.6. Persistent Rollback Journals
909
+ Deleting a file is an expensive operation on many systems.
910
+ So as an optimization, SQLite can be configured to avoid the
911
+ delete operation of section 3.11 .
912
+ Instead of deleting the journal file in order to commit a transaction,
913
+ the file is either truncated to zero bytes in length or its
914
+ header is overwritten with zeros. Truncating the file to zero
915
+ length saves having to make modifications to the directory containing
916
+ the file since the file is not removed from the directory.
917
+ Overwriting the header has the additional savings of not having
918
+ to update the length of the file (in the "inode" on many systems)
919
+ and not having to deal with newly freed disk sectors. Furthermore,
920
+ at the next transaction the journal will be created by overwriting
921
+ existing content rather than appending new content onto the end
922
+ of a file, and overwriting is often much faster than appending.
923
+ SQLite can be configured to commit transactions by overwriting
924
+ the journal header with zeros instead of deleting the journal file
925
+ by setting the "PERSIST" journaling mode using the
926
+ journal_mode PRAGMA.
927
+ For example:
928
+ The use of persistent journal mode provides a noticeable performance
929
+ improvement on many systems. Of course, the drawback is that the
930
+ journal files remain on the disk, using disk space and cluttering
931
+ directories, long after the transaction commits. The only safe way
932
+ to delete a persistent journal file is to commit a transaction
933
+ with journaling mode set to DELETE:
934
+ Beware of deleting persistent journal files by any other means
935
+ since the journal file might be hot, in which case deleting it will
936
+ corrupt the corresponding database file.
937
+ Beginning in SQLite version 3.6.4 (2008-10-15),
938
+ the TRUNCATE journal mode is
939
+ also supported:
940
+ In truncate journal mode, the transaction is committed by truncating
941
+ the journal file to zero length rather than deleting the journal file
942
+ (as in DELETE mode) or by zeroing the header (as in PERSIST mode).
943
+ TRUNCATE mode shares the advantage of PERSIST mode that the directory
944
+ that contains the journal file and database does not need to be updated.
945
+ Hence truncating a file is often faster than deleting it. TRUNCATE has
946
+ the additional advantage that it is not followed by a
947
+ system call (ex: fsync()) to synchronize the change to disk. It might
948
+ be safer if it did.
949
+ But on many modern filesystems, a truncate is an atomic and
950
+ synchronous operation and so we think that TRUNCATE will usually be safe
951
+ in the face of power failures. If you are uncertain about whether or
952
+ not TRUNCATE will be synchronous and atomic on your filesystem and it is
953
+ important to you that your database survive a power loss or operating
954
+ system crash that occurs during the truncation operation, then you might
955
+ consider using a different journaling mode.
956
+ On embedded systems with synchronous filesystems, TRUNCATE results
957
+ in slower behavior than PERSIST. The commit operation is the same speed.
958
+ But subsequent transactions are slower following a TRUNCATE because it is
959
+ faster to overwrite existing content than to append to the end of a file.
960
+ New journal file entries will always be appended following a TRUNCATE but
961
+ will usually overwrite with PERSIST.
962
+ 8. Testing Atomic Commit Behavior
963
+ The developers of SQLite are confident that it is robust
964
+ in the face of power failures and system crashes because the
965
+ automatic test procedures do extensive checks on
966
+ the ability of SQLite to recover from simulated power loss.
967
+ We call these the "crash tests".
968
+ Crash tests in SQLite use a modified VFS that can simulate
969
+ the kinds of filesystem damage that occur during a power
970
+ loss or operating system crash. The crash-test VFS can simulate
971
+ incomplete sector writes, pages filled with garbage data because
972
+ a write has not completed, and out of order writes, all occurring
973
+ at varying points during a test scenario. Crash tests execute
974
+ transactions over and over, varying the time at which a simulated
975
+ power loss occurs and the properties of the damage inflicted.
976
+ Each test then reopens the database after the simulated crash and
977
+ verifies that the transaction either occurred completely
978
+ or not at all and that the database is in a completely
979
+ consistent state.
980
+ The crash tests in SQLite have discovered a number of very
981
+ subtle bugs (now fixed) in the recovery mechanism. Some of
982
+ these bugs were very obscure and unlikely to have been found
983
+ using only code inspection and analysis techniques. From this
984
+ experience, the developers of SQLite feel confident that any other
985
+ database system that does not use a similar crash test system
986
+ likely contains undetected bugs that will lead to database
987
+ corruption following a system crash or power failure.
988
+ 9. Things That Can Go Wrong
989
+ The atomic commit mechanism in SQLite has proven to be robust,
990
+ but it can be circumvented by a sufficiently creative
991
+ adversary or a sufficiently broken operating system implementation.
992
+ This section describes a few of the ways in which an SQLite database
993
+ might be corrupted by a power failure or system crash.
994
+ (See also: How To Corrupt Your Database Files .)
995
+ 9.1. Broken Locking Implementations
996
+ SQLite uses filesystem locks to make sure that only one
997
+ process and database connection is trying to modify the database
998
+ at a time. The filesystem locking mechanism is implemented
999
+ in the VFS layer and is different for every operating system.
1000
+ SQLite depends on this implementation being correct. If something
1001
+ goes wrong and two or more processes are able to write the same
1002
+ database file at the same time, severe damage can result.
1003
+ We have received reports of implementations of both
1004
+ Windows network filesystems and NFS in which locking was
1005
+ subtly broken. We can not verify these reports, but as
1006
+ locking is difficult to get right on a network filesystem
1007
+ we have no reason to doubt them. You are advised to
1008
+ avoid using SQLite on a network filesystem in the first place,
1009
+ since performance will be slow. But if you must use a
1010
+ network filesystem to store SQLite database files, consider
1011
+ using a secondary locking mechanism to prevent simultaneous
1012
+ writes to the same database even if the native filesystem
1013
+ locking mechanism malfunctions.
1014
+ The versions of SQLite that come preinstalled on Apple
1015
+ Mac OS X computers contain a version of SQLite that has been
1016
+ extended to use alternative locking strategies that work on
1017
+ all network filesystems that Apple supports. These extensions
1018
+ used by Apple work great as long as all processes are accessing
1019
+ the database file in the same way. Unfortunately, the locking
1020
+ mechanisms do not exclude one another, so if one process is
1021
+ accessing a file using (for example) AFP locking and another
1022
+ process (perhaps on a different machine) is using dot-file locks,
1023
+ the two processes might collide because AFP locks do not exclude
1024
+ dot-file locks or vice versa.
1025
+ 9.2. Incomplete Disk Flushes
1026
+ SQLite uses the fsync() system call on Unix and the FlushFileBuffers()
1027
+ system call on w32 in order to sync the file system buffers onto disk
1028
+ oxide as shown in step 3.7 and
1029
+ step 3.10 . Unfortunately, we have received
1030
+ reports that neither of these interfaces works as advertised on many
1031
+ systems. We hear that FlushFileBuffers() can be completely disabled
1032
+ using registry settings on some Windows versions. Some historical
1033
+ versions of Linux contain versions of fsync() which are no-ops on
1034
+ some filesystems, we are told. Even on systems where
1035
+ FlushFileBuffers() and fsync() are said to be working, often
1036
+ the IDE disk control lies and says that data has reached oxide
1037
+ while it is still held only in the volatile control cache.
1038
+ On the Mac, you can set this pragma:
1039
+ PRAGMA fullfsync=ON;
1040
+ Setting fullfsync on a Mac will guarantee that data really does
1041
+ get pushed out to the disk platter on a flush. But the implementation
1042
+ of fullfsync involves resetting the disk controller. And so not only
1043
+ is it profoundly slow, it also slows down other unrelated disk I/O.
1044
+ So its use is not recommended.
1045
+ 9.3. Partial File Deletions
1046
+ SQLite assumes that file deletion is an atomic operation from the
1047
+ point of view of a user process. If power fails in the middle of
1048
+ a file deletion, then after power is restored SQLite expects to see
1049
+ either the entire file with all of its original data intact, or it
1050
+ expects not to find the file at all. Transactions may not be atomic
1051
+ on systems that do not work this way.
1052
+ 9.4. Garbage Written Into Files
1053
+ SQLite database files are ordinary disk files that can be
1054
+ opened and written by ordinary user processes. A rogue process
1055
+ can open an SQLite database and fill it with corrupt data.
1056
+ Corrupt data might also be introduced into an SQLite database
1057
+ by bugs in the operating system or disk controller; especially
1058
+ bugs triggered by a power failure. There is nothing SQLite can
1059
+ do to defend against these kinds of problems.
1060
+ 9.5. Deleting Or Renaming A Hot Journal
1061
+ If a crash or power loss does occur and a hot journal is left on
1062
+ the disk, it is essential that the original database file and the hot
1063
+ journal remain on disk with their original names until the database
1064
+ file is opened by another SQLite process and rolled back.
1065
+ During recovery at step 4.2 SQLite locates
1066
+ the hot journal by looking for a file in the same directory as the
1067
+ database being opened and whose name is derived from the name of the
1068
+ file being opened. If either the original database file or the
1069
+ hot journal have been moved or renamed, then the hot journal will
1070
+ not be seen and the database will not be rolled back.
1071
+ We suspect that a common failure mode for SQLite recovery happens
1072
+ like this: A power failure occurs. After power is restored, a well-meaning
1073
+ user or system administrator begins looking around on the disk for
1074
+ damage. They see their database file named "important.data". This file
1075
+ is perhaps familiar to them. But after the crash, there is also a
1076
+ hot journal named "important.data-journal". The user then deletes
1077
+ the hot journal, thinking that they are helping to cleanup the system.
1078
+ We know of no way to prevent this other than user education.
1079
+ If there are multiple (hard or symbolic) links to a database file,
1080
+ the journal will be created using the name of the link through which
1081
+ the file was opened. If a crash occurs and the database is opened again
1082
+ using a different link, the hot journal will not be located and no
1083
+ rollback will occur.
1084
+ Sometimes a power failure will cause a filesystem to be corrupted
1085
+ such that recently changed filenames are forgotten and the file is
1086
+ moved into a "/lost+found" directory. When that happens, the hot
1087
+ journal will not be found and recovery will not occur.
1088
+ SQLite tries to prevent this
1089
+ by opening and syncing the directory containing the rollback journal
1090
+ at the same time it syncs the journal file itself. However, the
1091
+ movement of files into /lost+found can be caused by unrelated processes
1092
+ creating unrelated files in the same directory as the main database file.
1093
+ And since this is out from under the control of SQLite, there is nothing
1094
+ that SQLite can do to prevent it. If you are running on a system that
1095
+ is vulnerable to this kind of filesystem namespace corruption (most
1096
+ modern journalling filesystems are immune, we believe) then you might
1097
+ want to consider putting each SQLite database file in its own private
1098
+ subdirectory.
1099
+ 10. Future Directions And Conclusion
1100
+ Every now and then someone discovers a new failure mode for
1101
+ the atomic commit mechanism in SQLite and the developers have to
1102
+ put in a patch. This is happening less and less and the
1103
+ failure modes are becoming more and more obscure. But it would
1104
+ still be foolish to suppose that the atomic commit logic of
1105
+ SQLite is entirely bug-free. The developers are committed to fixing
1106
+ these bugs as quickly as they might be found.
1107
+ The developers are also on the lookout for new ways to
1108
+ optimize the commit mechanism. The current VFS implementations
1109
+ for Unix (Linux and Mac OS X) and Windows make pessimistic assumptions about
1110
+ the behavior of those systems. After consultation with experts
1111
+ on how these systems work, we might be able to relax some of the
1112
+ assumptions on these systems and allow them to run faster. In
1113
+ particular, we suspect that most modern filesystems exhibit the
1114
+ safe append property and that many of them might support atomic
1115
+ sector writes. But until this is known for certain, SQLite will
1116
+ take the conservative approach and assume the worst.
1117
+ This page was last updated on 2026-04-21 10:28:59Z