We don't "write" to a "read-only" database. We write to the writable write-ahead-log file. This is like purely functional data structures (in particular purely functional btrees). You can build a new structure, leave the old one unmodified, and share nodes for common data. Except in this case, we are building the new structure in a separate file, in the WAL.