On Mac OS X, LevelDB can become corrupt and fail to re-open the database. This issue can prevent users from storing the block chain and participating in the Bitcoin network. Users affected by the bug will typically see an error to the effect of Corruption: block checksum mismatch or missing start of fragmented record(2) . These log messages both stem from the same underlying problem within LevelDB.
For efficiency, LevelDB always performs I/O in a sequential fashion: every write generated by LevelDB appends data to a disk. Consequently, data is never overwritten, only recreated in another file. In a straightforward implementation, this mechanism could be accomplished using the write system call sequentially.
The write call can be costly when under contention by multiple threads, so the LevelDB developers implemented a user-space buffering mechanism using memory-mapped I/O. This buffering mechanism maps regions of fixed size such that the number of pages mapped in any one file will never exceed a particular constant. At any given time, the writing process is filling whichever region is mapped. It then unmaps the region before moving onto the next.
Of course, it's possible for a user's write to straddle the boundary between the current region and the next region to be mapped. When such an overlap occurs, the writer places whatever it can from the user's write into the current region, unmaps the current region, maps the next region and finishes placing the data.
On Linux, this sequence of operations is safe because the virtual memory subsystem will keep these pages around until they can be written to disk. Programmers refer to these pages with unwritten data as being "dirty". As far as we are aware, POSIX imposes no requirements on the handling of dirty pages after an unmap. It's entirely possible for a POSIX-conformant system to simply discard any dirty pages that the user unmapped.
And therein lies the problem. On Mac OS X the dirty pages seem to be discarded without being flushed to disk.