TransactionIdSetPageStatus() calls TransactionIdSetStatusBit(), which writes an 8 byte variable (the lsn). That's not safe.
This point was the main sticking point here.
It turns out that we don't need to store the LSN (8 bytes).
WAL is fsynced every time we finish writing a file, so we only actually need to store the byte position within each file, so no more than 16MB. That fits within a 4 byte value, so can be written atomically.
So I have a valid way forward for this approach. Cool.
--
Simon Riggs http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services