aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2011-06-21 23:04:40 -0400
committerRobert Haas <rhaas@postgresql.org>2011-06-21 23:04:40 -0400
commit503c7305a1e379f95649eef1a694d0c1dbdc674a (patch)
tree39bb67975f3419f76d6973e86d5517c8e55f9853 /src/include
parent431ab0e82819b31fcd1e33ecb52c2cd3b4b41da7 (diff)
downloadpostgresql-503c7305a1e379f95649eef1a694d0c1dbdc674a.tar.gz
postgresql-503c7305a1e379f95649eef1a694d0c1dbdc674a.zip
Make the visibility map crash-safe.
This involves two main changes from the previous behavior. First, when we set a bit in the visibility map, emit a new WAL record of type XLOG_HEAP2_VISIBLE. Replay sets the page-level PD_ALL_VISIBLE bit and the visibility map bit. Second, when inserting, updating, or deleting a tuple, we can no longer get away with clearing the visibility map bit after releasing the lock on the corresponding heap page, because an intervening crash might leave the visibility map bit set and the page-level bit clear. Making this work requires a bit of interface refactoring. In passing, a few minor but related cleanups: change the test in visibilitymap_set and visibilitymap_clear to throw an error if the wrong page (or no page) is pinned, rather than silently doing nothing; this case should never occur. Also, remove duplicate definitions of InvalidXLogRecPtr. Patch by me, review by Noah Misch.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/access/heapam.h2
-rw-r--r--src/include/access/hio.h3
-rw-r--r--src/include/access/htup.h10
-rw-r--r--src/include/access/transam.h3
-rw-r--r--src/include/access/visibilitymap.h6
-rw-r--r--src/include/access/xlog_internal.h2
6 files changed, 22 insertions, 4 deletions
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 4dbc3937099..fc657612ed0 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -136,6 +136,8 @@ extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer,
TransactionId cutoff_xid,
OffsetNumber *offsets, int offcnt);
+extern XLogRecPtr log_heap_visible(RelFileNode rnode, BlockNumber block,
+ Buffer vm_buffer);
extern XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum,
BlockNumber blk, Page page);
diff --git a/src/include/access/hio.h b/src/include/access/hio.h
index 6b661a3e870..7ae879788cf 100644
--- a/src/include/access/hio.h
+++ b/src/include/access/hio.h
@@ -38,6 +38,7 @@ extern void RelationPutHeapTuple(Relation relation, Buffer buffer,
HeapTuple tuple);
extern Buffer RelationGetBufferForTuple(Relation relation, Size len,
Buffer otherBuffer, int options,
- struct BulkInsertStateData * bistate);
+ struct BulkInsertStateData * bistate,
+ Buffer *vmbuffer);
#endif /* HIO_H */
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index c1477071697..ba5d9b28ef1 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -606,6 +606,7 @@ typedef HeapTupleData *HeapTuple;
#define XLOG_HEAP2_CLEAN 0x10
/* 0x20 is free, was XLOG_HEAP2_CLEAN_MOVE */
#define XLOG_HEAP2_CLEANUP_INFO 0x30
+#define XLOG_HEAP2_VISIBLE 0x40
/*
* All what we need to find changed tuple
@@ -750,6 +751,15 @@ typedef struct xl_heap_freeze
#define SizeOfHeapFreeze (offsetof(xl_heap_freeze, cutoff_xid) + sizeof(TransactionId))
+/* This is what we need to know about setting a visibility map bit */
+typedef struct xl_heap_visible
+{
+ RelFileNode node;
+ BlockNumber block;
+} xl_heap_visible;
+
+#define SizeOfHeapVisible (offsetof(xl_heap_visible, block) + sizeof(BlockNumber))
+
extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
TransactionId *latestRemovedXid);
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index c5e6ab0ca49..c038fd9a52d 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -135,6 +135,9 @@ extern bool TransactionStartedDuringRecovery(void);
/* in transam/varsup.c */
extern PGDLLIMPORT VariableCache ShmemVariableCache;
+/* in transam/transam.c */
+extern const XLogRecPtr InvalidXLogRecPtr;
+
/*
* prototypes for functions in transam/transam.c
diff --git a/src/include/access/visibilitymap.h b/src/include/access/visibilitymap.h
index 689060bc159..7d62c126407 100644
--- a/src/include/access/visibilitymap.h
+++ b/src/include/access/visibilitymap.h
@@ -19,11 +19,13 @@
#include "storage/buf.h"
#include "utils/relcache.h"
-extern void visibilitymap_clear(Relation rel, BlockNumber heapBlk);
+extern void visibilitymap_clear(Relation rel, BlockNumber heapBlk,
+ Buffer vmbuf);
extern void visibilitymap_pin(Relation rel, BlockNumber heapBlk,
Buffer *vmbuf);
+extern bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf);
extern void visibilitymap_set(Relation rel, BlockNumber heapBlk,
- XLogRecPtr recptr, Buffer *vmbuf);
+ XLogRecPtr recptr, Buffer vmbuf);
extern bool visibilitymap_test(Relation rel, BlockNumber heapBlk, Buffer *vmbuf);
extern void visibilitymap_truncate(Relation rel, BlockNumber heapblk);
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 7e39630c1bf..34316fffeba 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -71,7 +71,7 @@ typedef struct XLogContRecord
/*
* Each page of XLOG file has a header like this:
*/
-#define XLOG_PAGE_MAGIC 0xD066 /* can be used as WAL version indicator */
+#define XLOG_PAGE_MAGIC 0xD067 /* can be used as WAL version indicator */
typedef struct XLogPageHeaderData
{