Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 1 addition & 80 deletions src/backend/access/heap/heapam_xlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,26 +147,9 @@ heap_xlog_prune_freeze(XLogReaderState *record)
MarkBufferDirty(buffer);
}

/*
* If we released any space or line pointers, update the free space map.
*
* Do this regardless of a full-page image being applied, since the FSM
* data is not in the page anyway.
*/
if (BufferIsValid(buffer))
{
if (xlrec.flags & (XLHP_HAS_REDIRECTIONS |
XLHP_HAS_DEAD_ITEMS |
XLHP_HAS_NOW_UNUSED_ITEMS))
{
Size freespace = PageGetHeapFreeSpace(BufferGetPage(buffer));

UnlockReleaseBuffer(buffer);

XLogRecordPageWithFreeSpace(rlocator, blkno, freespace);
}
else
UnlockReleaseBuffer(buffer);
UnlockReleaseBuffer(buffer);
}
}

Expand Down Expand Up @@ -246,26 +229,6 @@ heap_xlog_visible(XLogReaderState *record)
Size space = PageGetFreeSpace(BufferGetPage(buffer));

UnlockReleaseBuffer(buffer);

/*
* Since FSM is not WAL-logged and only updated heuristically, it
* easily becomes stale in standbys. If the standby is later promoted
* and runs VACUUM, it will skip updating individual free space
* figures for pages that became all-visible (or all-frozen, depending
* on the vacuum mode,) which is troublesome when FreeSpaceMapVacuum
* propagates too optimistic free space values to upper FSM layers;
* later inserters try to use such pages only to find out that they
* are unusable. This can cause long stalls when there are many such
* pages.
*
* Forestall those problems by updating FSM's idea about a page that
* is becoming all-visible or all-frozen.
*
* Do this regardless of a full-page image being applied, since the
* FSM data is not in the page anyway.
*/
if (xlrec->flags & VISIBILITYMAP_VALID_BITS)
XLogRecordPageWithFreeSpace(rlocator, blkno, space);
}

/*
Expand Down Expand Up @@ -515,18 +478,6 @@ heap_xlog_insert(XLogReaderState *record)
}
if (BufferIsValid(buffer))
UnlockReleaseBuffer(buffer);

/*
* If the page is running low on free space, update the FSM as well.
* Arbitrarily, our definition of "low" is less than 20%. We can't do much
* better than that without knowing the fill-factor for the table.
*
* XXX: Don't do this if the page was restored from full page image. We
* don't bother to update the FSM in that case, it doesn't need to be
* totally accurate anyway.
*/
if (action == BLK_NEEDS_REDO && freespace < BLCKSZ / 5)
XLogRecordPageWithFreeSpace(target_locator, blkno, freespace);
}

/*
Expand Down Expand Up @@ -662,18 +613,6 @@ heap_xlog_multi_insert(XLogReaderState *record)
}
if (BufferIsValid(buffer))
UnlockReleaseBuffer(buffer);

/*
* If the page is running low on free space, update the FSM as well.
* Arbitrarily, our definition of "low" is less than 20%. We can't do much
* better than that without knowing the fill-factor for the table.
*
* XXX: Don't do this if the page was restored from full page image. We
* don't bother to update the FSM in that case, it doesn't need to be
* totally accurate anyway.
*/
if (action == BLK_NEEDS_REDO && freespace < BLCKSZ / 5)
XLogRecordPageWithFreeSpace(rlocator, blkno, freespace);
}

/*
Expand Down Expand Up @@ -931,24 +870,6 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
UnlockReleaseBuffer(nbuffer);
if (BufferIsValid(obuffer))
UnlockReleaseBuffer(obuffer);

/*
* If the new page is running low on free space, update the FSM as well.
* Arbitrarily, our definition of "low" is less than 20%. We can't do much
* better than that without knowing the fill-factor for the table.
*
* However, don't update the FSM on HOT updates, because after crash
* recovery, either the old or the new tuple will certainly be dead and
* prunable. After pruning, the page will have roughly as much free space
* as it did before the update, assuming the new tuple is about the same
* size as the old one.
*
* XXX: Don't do this if the page was restored from full page image. We
* don't bother to update the FSM in that case, it doesn't need to be
* totally accurate anyway.
*/
if (newaction == BLK_NEEDS_REDO && !hot_update && freespace < BLCKSZ / 5)
XLogRecordPageWithFreeSpace(rlocator, newblk, freespace);
}

/*
Expand Down
1 change: 1 addition & 0 deletions src/backend/access/rmgrdesc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ OBJS = \
clogdesc.o \
committsdesc.o \
dbasedesc.o \
fsmdesc.o \
genericdesc.o \
gindesc.o \
gistdesc.o \
Expand Down
48 changes: 48 additions & 0 deletions src/backend/access/rmgrdesc/fsmdesc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*-------------------------------------------------------------------------
*
* fsmdesc.c
* rmgr descriptor routines for storage/freespace/freespace.c
*
*
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/backend/access/rmgrdesc/fsmdesc.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"

#include "access/fsm_xlog.h"
#include "lib/stringinfo.h"


const char *
fsm_identify(uint8 info)
{
if ((info & ~XLR_INFO_MASK) == XLOG_FSM_UPDATE)
return "FSM_UPDATE";

return NULL;
}

void
fsm_desc(StringInfo buf, XLogReaderState *record)
{
int i;
char *rec = XLogRecGetData(record);
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;

if (info == XLOG_FSM_UPDATE)
{
xl_fsm_update *xlrec = (xl_fsm_update *) rec;

appendStringInfo(buf, "nevent: %d ", xlrec->nchanges);

for (i = 0; i < xlrec->nchanges; ++i)
{
appendStringInfo(buf, ", offset %d value %d", xlrec->ev[2 * i], xlrec->ev[2 * i + 1]);
}
}
}

1 change: 1 addition & 0 deletions src/backend/access/rmgrdesc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ rmgr_desc_sources = files(
'clogdesc.c',
'committsdesc.c',
'dbasedesc.c',
'fsmdesc.c',
'genericdesc.c',
'gindesc.c',
'gistdesc.c',
Expand Down
1 change: 1 addition & 0 deletions src/backend/access/transam/rmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "access/brin_xlog.h"
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/fsm_xlog.h"
#include "access/generic_xlog.h"
#include "access/ginxlog.h"
#include "access/gistxlog.h"
Expand Down
Loading