mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
add323da40 consolidated visibility map updates into XLOG_HEAP2_PRUNE
records. It assumed that a record setting the visibility map would
always modify the VM page during replay. That is not true when the
requested bits are already set on the standby.
Primary and standby visibility maps can diverge for several reasons.
This issue was exposed by a CREATE DATABASE ... STRATEGY WAL_LOG bug.
After a standby with an out-of-date VM is promoted, VACUUM may set bits
that were already present on the former primary. When the former primary
later replays that record as a standby, visibilitymap_set() is a no-op.
Restore visibilitymap_set()'s former API, which returns the state of the
VM bits before setting the requested flags. Use that result to set the
VM page LSN only when the visibilitymap_set() updates the page.
Reported-by: Rogers Wang <rogers.ww@qq.com>
Discussion: https://postgr.es/m/tencent_2E870046716FD94285045E96505A2D4E2908%40qq.com
Backpatch-through: 19
44 lines
1.6 KiB
C
44 lines
1.6 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* visibilitymap.h
|
|
* visibility map interface
|
|
*
|
|
*
|
|
* Portions Copyright (c) 2007-2026, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/access/visibilitymap.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef VISIBILITYMAP_H
|
|
#define VISIBILITYMAP_H
|
|
|
|
#include "access/visibilitymapdefs.h"
|
|
#include "storage/block.h"
|
|
#include "storage/buf.h"
|
|
#include "storage/relfilelocator.h"
|
|
#include "utils/relcache.h"
|
|
|
|
/* Macros for visibilitymap test */
|
|
#define VM_ALL_VISIBLE(r, b, v) \
|
|
((visibilitymap_get_status((r), (b), (v)) & VISIBILITYMAP_ALL_VISIBLE) != 0)
|
|
#define VM_ALL_FROZEN(r, b, v) \
|
|
((visibilitymap_get_status((r), (b), (v)) & VISIBILITYMAP_ALL_FROZEN) != 0)
|
|
|
|
extern bool visibilitymap_clear(Relation rel, BlockNumber heapBlk,
|
|
Buffer vmbuf, uint8 flags);
|
|
extern void visibilitymap_pin(Relation rel, BlockNumber heapBlk,
|
|
Buffer *vmbuf);
|
|
extern bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf);
|
|
extern uint8 visibilitymap_set(BlockNumber heapBlk,
|
|
Buffer vmBuf, uint8 flags,
|
|
const RelFileLocator rlocator);
|
|
extern uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *vmbuf);
|
|
extern void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen);
|
|
extern BlockNumber visibilitymap_prepare_truncate(Relation rel,
|
|
BlockNumber nheapblocks);
|
|
extern BlockNumber visibilitymap_truncation_length(BlockNumber nheapblocks);
|
|
|
|
#endif /* VISIBILITYMAP_H */
|