diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-02-11 22:50:15 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-02-11 23:07:09 +0200 |
commit | 62401db45c4feff9be296fa78a8bb7b9947d69de (patch) | |
tree | 5d572267b5a2eae75049ba720bc1faf9f6a6694d /src/backend/storage/buffer/bufmgr.c | |
parent | b669f416cee77ef9025b80f9c4201688578447d1 (diff) | |
download | postgresql-62401db45c4feff9be296fa78a8bb7b9947d69de.tar.gz postgresql-62401db45c4feff9be296fa78a8bb7b9947d69de.zip |
Support unlogged GiST index.
The reason this wasn't supported before was that GiST indexes need an
increasing sequence to detect concurrent page-splits. In a regular WAL-
logged GiST index, the LSN of the page-split record is used for that
purpose, and in a temporary index, we can get away with a backend-local
counter. Neither of those methods works for an unlogged relation.
To provide such an increasing sequence of numbers, create a "fake LSN"
counter that is saved and restored across shutdowns. On recovery, unlogged
relations are blown away, so the counter doesn't need to survive that
either.
Jeevan Chalke, based on discussions with Robert Haas, Tom Lane and me.
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 |