mirror of
https://github.com/postgres/postgres.git
synced 2025-10-24 01:29:19 +03:00
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user