1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00
Files
postgres/src/include/access/gistxlog.h
Heikki Linnakangas 7df159a620 Delete empty pages during GiST VACUUM.
To do this, we scan GiST two times. In the first pass we make note of
empty leaf pages and internal pages. At second pass we scan through
internal pages, looking for downlinks to the empty pages.

Deleting internal pages is still not supported, like in nbtree, the last
child of an internal page is never deleted. That means that if you have a
workload where new keys are always inserted to different area than where
old keys are removed, the index will still grow without bound. But the rate
of growth will be an order of magnitude slower than before.

Author: Andrey Borodin
Discussion: https://www.postgresql.org/message-id/B1E4DF12-6CD3-4706-BDBD-BF3283328F60@yandex-team.ru
2019-03-22 13:21:45 +02:00

113 lines
3.3 KiB
C

/*-------------------------------------------------------------------------
*
* gistxlog.h
* gist xlog routines
*
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/access/gistxlog.h
*
*-------------------------------------------------------------------------
*/
#ifndef GIST_XLOG_H
#define GIST_XLOG_H
#include "access/gist.h"
#include "access/xlogreader.h"
#include "lib/stringinfo.h"
#define XLOG_GIST_PAGE_UPDATE 0x00
#define XLOG_GIST_DELETE 0x10 /* delete leaf index tuples for a page */
#define XLOG_GIST_PAGE_REUSE 0x20 /* old page is about to be reused from
* FSM */
#define XLOG_GIST_PAGE_SPLIT 0x30
/* #define XLOG_GIST_INSERT_COMPLETE 0x40 */ /* not used anymore */
#define XLOG_GIST_CREATE_INDEX 0x50
#define XLOG_GIST_PAGE_DELETE 0x60
/*
* Backup Blk 0: updated page.
* Backup Blk 1: If this operation completes a page split, by inserting a
* downlink for the split page, the left half of the split
*/
typedef struct gistxlogPageUpdate
{
/* number of deleted offsets */
uint16 ntodelete;
uint16 ntoinsert;
/*
* In payload of blk 0 : 1. todelete OffsetNumbers 2. tuples to insert
*/
} gistxlogPageUpdate;
/*
* Backup Blk 0: Leaf page, whose index tuples are deleted.
*/
typedef struct gistxlogDelete
{
RelFileNode hnode; /* RelFileNode of the heap the index currently
* points at */
uint16 ntodelete; /* number of deleted offsets */
/*
* In payload of blk 0 : todelete OffsetNumbers
*/
} gistxlogDelete;
#define SizeOfGistxlogDelete (offsetof(gistxlogDelete, ntodelete) + sizeof(uint16))
/*
* Backup Blk 0: If this operation completes a page split, by inserting a
* downlink for the split page, the left half of the split
* Backup Blk 1 - npage: split pages (1 is the original page)
*/
typedef struct gistxlogPageSplit
{
BlockNumber origrlink; /* rightlink of the page before split */
GistNSN orignsn; /* NSN of the page before split */
bool origleaf; /* was splitted page a leaf page? */
uint16 npage; /* # of pages in the split */
bool markfollowright; /* set F_FOLLOW_RIGHT flags */
/*
* follow: 1. gistxlogPage and array of IndexTupleData per page
*/
} gistxlogPageSplit;
/*
* Backup Blk 0: page that was deleted.
* Backup Blk 1: parent page, containing the downlink to the deleted page.
*/
typedef struct gistxlogPageDelete
{
TransactionId deleteXid; /* last Xid which could see page in scan */
OffsetNumber downlinkOffset; /* Offset of downlink referencing this page */
} gistxlogPageDelete;
#define SizeOfGistxlogPageDelete (offsetof(gistxlogPageDelete, downlinkOffset) + sizeof(OffsetNumber))
/*
* This is what we need to know about page reuse, for hot standby.
*/
typedef struct gistxlogPageReuse
{
RelFileNode node;
BlockNumber block;
TransactionId latestRemovedXid;
} gistxlogPageReuse;
#define SizeOfGistxlogPageReuse (offsetof(gistxlogPageReuse, latestRemovedXid) + sizeof(TransactionId))
extern void gist_redo(XLogReaderState *record);
extern void gist_desc(StringInfo buf, XLogReaderState *record);
extern const char *gist_identify(uint8 info);
extern void gist_xlog_startup(void);
extern void gist_xlog_cleanup(void);
extern void gist_mask(char *pagedata, BlockNumber blkno);
#endif