1.0 Introduction
An important feature of transactional databases like SQLite is "atomic commit". Atomic commit means that either all database changes within a single transaction occur or none of them occur. With atomic commit, it is as if many different writes to different sections of the database file occur instantaneously and simultaneously. Real hardware serializes writes to mass storage, and writing a single sector takes a finite amount of time. So it is impossible to truly write many different sectors of a database file simultaneously and/or instantaneously. But the atomic commit logic within SQLite makes it appear as if the changes for a transaction are all written instantaneously and simultaneously.
SQLite has the important property that transactions appear to be atomic even if the transaction is interrupted by an operating system crash or power failure.
This article describes the techniques used by SQLite to create the illusion of atomic commit.
The information in this article applies only when SQLite is operating in "rollback mode", or in other words when SQLite is not using a write-ahead log. SQLite still supports atomic commit when write-ahead logging is enabled, but it accomplishes atomic commit by a different mechanism from the one describe in this article. See the write-ahead log documentation for additional information on how SQLite supports atomic commit in that context.
2.0 Hardware Assumptions
Throughout this article, we will call the mass storage device "disk" even though the mass storage device might really be flash memory.
We assume that disk is written in chunks which we call a "sector". It is not possible to modify any part of the disk smaller than a sector. To change a part of the disk smaller than a sector, you have to read in the full sector that contains the part you want to change, make the change, then write back out the complete sector.