diff options
Diffstat (limited to 'src/backend/storage/buffer/bufmgr.c')
-rw-r--r-- | src/backend/storage/buffer/bufmgr.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 13b80aefc5b..405ff61130e 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1922,9 +1922,24 @@ FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln) * Force XLOG flush up to buffer's LSN. This implements the basic WAL * rule that log updates must hit disk before any of the data-file changes * they describe do. + * + * However, this rule does not apply to unlogged relations, which will be + * lost after a crash anyway. Most unlogged relation pages do not bear + * LSNs since we never emit WAL records for them, and therefore flushing + * up through the buffer LSN would be useless, but harmless. However, GiST + * indexes use LSNs internally to track page-splits, and therefore unlogged + * GiST pages bear "fake" LSNs generated by GetFakeLSNForUnloggedRel. It + * is unlikely but possible that the fake LSN counter could advance past + * the WAL insertion point; and if it did happen, attempting to flush WAL + * through that location would fail, with disastrous system-wide + * consequences. To make sure that can't happen, skip the flush if the + * buffer isn't permanent. */ - recptr = BufferGetLSN(buf); - XLogFlush(recptr); + if (buf->flags & BM_PERMANENT) + { + recptr = BufferGetLSN(buf); + XLogFlush(recptr); + } /* * Now it's safe to write buffer to disk. Note that no one else should |