82
Why not malloc( )?
Using libpmem seems simple. You need to flush anything you have written and use
discipline when ordering such that data needs to be persisted before any pointers to it
go live.
If only persistent memory programming were so simple. Apart from some specific
patterns that can be done in a simpler way, such as append-only records that can be
efficiently handled by libpmemlog, any new piece of data needs to have its memory
allocated. When and how should the allocator mark the memory as in use? Should the
allocator mark the memory as allocated before writing data or after? Neither approach
works for these reasons:
• If the allocator marks the memory as allocated before the data is
written, a power outage during the write can cause torn updates and
a so-called “persistent leak.”
• If the allocator writes the data, then marks it as allocated, a power
outage that occurs between the write completing and the allocator
marking it as allocated can overwrite the data when the application
restarts since the allocator believes the block is available.
Another problem is that a significant number of data structures include cyclical
references and thus do not form a tree. They could be implemented as a tree, but this
approach is usually harder to implement.
Byte-addressable memory guarantees atomicity of only a single write. For current
processors, that is generally one 64-bit word (8-bytes) that should be aligned, but this is
not a requirement in practice.
All of the preceding problems could be solved if multiple writes occurred
simultaneously. In the event of a power failure, any incomplete writes should either
be replayed as though the power failure never happened or discarded as though the
write never occurred. Applications solve this in different ways using atomic operations,
transactions, redo/undo logging, etc. Using libpmemobj can solve those problems
because it uses atomic transactions and redo/undo logs.
Chapter 7 libpmemobj: a Native traNsaCtioNal objeCt store
Précédent

- 109/457

Suivant