mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 11:11:16 +02:00
258 lines
7.3 KiB
C
258 lines
7.3 KiB
C
|
/*-------------------------------------------------------------------------
|
||
|
*
|
||
|
* spgxlog.h
|
||
|
* xlog declarations for SP-GiST access method.
|
||
|
*
|
||
|
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
|
||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||
|
*
|
||
|
* src/include/access/spgxlog.h
|
||
|
*
|
||
|
*-------------------------------------------------------------------------
|
||
|
*/
|
||
|
#ifndef SPGXLOG_H
|
||
|
#define SPGXLOG_H
|
||
|
|
||
|
#include "access/xlogreader.h"
|
||
|
#include "lib/stringinfo.h"
|
||
|
#include "storage/off.h"
|
||
|
|
||
|
/* XLOG record types for SPGiST */
|
||
|
#define XLOG_SPGIST_CREATE_INDEX 0x00
|
||
|
#define XLOG_SPGIST_ADD_LEAF 0x10
|
||
|
#define XLOG_SPGIST_MOVE_LEAFS 0x20
|
||
|
#define XLOG_SPGIST_ADD_NODE 0x30
|
||
|
#define XLOG_SPGIST_SPLIT_TUPLE 0x40
|
||
|
#define XLOG_SPGIST_PICKSPLIT 0x50
|
||
|
#define XLOG_SPGIST_VACUUM_LEAF 0x60
|
||
|
#define XLOG_SPGIST_VACUUM_ROOT 0x70
|
||
|
#define XLOG_SPGIST_VACUUM_REDIRECT 0x80
|
||
|
|
||
|
/*
|
||
|
* Some redo functions need an SpGistState, although only a few of its fields
|
||
|
* need to be valid. spgxlogState carries the required info in xlog records.
|
||
|
* (See fillFakeState in spgxlog.c for more comments.)
|
||
|
*/
|
||
|
typedef struct spgxlogState
|
||
|
{
|
||
|
TransactionId myXid;
|
||
|
bool isBuild;
|
||
|
} spgxlogState;
|
||
|
|
||
|
/*
|
||
|
* Backup Blk 0: destination page for leaf tuple
|
||
|
* Backup Blk 1: parent page (if any)
|
||
|
*/
|
||
|
typedef struct spgxlogAddLeaf
|
||
|
{
|
||
|
bool newPage; /* init dest page? */
|
||
|
bool storesNulls; /* page is in the nulls tree? */
|
||
|
OffsetNumber offnumLeaf; /* offset where leaf tuple gets placed */
|
||
|
OffsetNumber offnumHeadLeaf; /* offset of head tuple in chain, if any */
|
||
|
|
||
|
OffsetNumber offnumParent; /* where the parent downlink is, if any */
|
||
|
uint16 nodeI;
|
||
|
|
||
|
/* new leaf tuple follows (unaligned!) */
|
||
|
} spgxlogAddLeaf;
|
||
|
|
||
|
/*
|
||
|
* Backup Blk 0: source leaf page
|
||
|
* Backup Blk 1: destination leaf page
|
||
|
* Backup Blk 2: parent page
|
||
|
*/
|
||
|
typedef struct spgxlogMoveLeafs
|
||
|
{
|
||
|
uint16 nMoves; /* number of tuples moved from source page */
|
||
|
bool newPage; /* init dest page? */
|
||
|
bool replaceDead; /* are we replacing a DEAD source tuple? */
|
||
|
bool storesNulls; /* pages are in the nulls tree? */
|
||
|
|
||
|
/* where the parent downlink is */
|
||
|
OffsetNumber offnumParent;
|
||
|
uint16 nodeI;
|
||
|
|
||
|
spgxlogState stateSrc;
|
||
|
|
||
|
/*----------
|
||
|
* data follows:
|
||
|
* array of deleted tuple numbers, length nMoves
|
||
|
* array of inserted tuple numbers, length nMoves + 1 or 1
|
||
|
* list of leaf tuples, length nMoves + 1 or 1 (unaligned!)
|
||
|
*
|
||
|
* Note: if replaceDead is true then there is only one inserted tuple
|
||
|
* number and only one leaf tuple in the data, because we are not copying
|
||
|
* the dead tuple from the source
|
||
|
*----------
|
||
|
*/
|
||
|
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
|
||
|
} spgxlogMoveLeafs;
|
||
|
|
||
|
#define SizeOfSpgxlogMoveLeafs offsetof(spgxlogMoveLeafs, offsets)
|
||
|
|
||
|
/*
|
||
|
* Backup Blk 0: original page
|
||
|
* Backup Blk 1: where new tuple goes, if not same place
|
||
|
* Backup Blk 2: where parent downlink is, if updated and different from
|
||
|
* the old and new
|
||
|
*/
|
||
|
typedef struct spgxlogAddNode
|
||
|
{
|
||
|
/*
|
||
|
* Offset of the original inner tuple, in the original page (on backup
|
||
|
* block 0).
|
||
|
*/
|
||
|
OffsetNumber offnum;
|
||
|
|
||
|
/*
|
||
|
* Offset of the new tuple, on the new page (on backup block 1). Invalid,
|
||
|
* if we overwrote the old tuple in the original page).
|
||
|
*/
|
||
|
OffsetNumber offnumNew;
|
||
|
bool newPage; /* init new page? */
|
||
|
|
||
|
/*----
|
||
|
* Where is the parent downlink? parentBlk indicates which page it's on,
|
||
|
* and offnumParent is the offset within the page. The possible values for
|
||
|
* parentBlk are:
|
||
|
*
|
||
|
* 0: parent == original page
|
||
|
* 1: parent == new page
|
||
|
* 2: parent == different page (blk ref 2)
|
||
|
* -1: parent not updated
|
||
|
*----
|
||
|
*/
|
||
|
int8 parentBlk;
|
||
|
OffsetNumber offnumParent; /* offset within the parent page */
|
||
|
|
||
|
uint16 nodeI;
|
||
|
|
||
|
spgxlogState stateSrc;
|
||
|
|
||
|
/*
|
||
|
* updated inner tuple follows (unaligned!)
|
||
|
*/
|
||
|
} spgxlogAddNode;
|
||
|
|
||
|
/*
|
||
|
* Backup Blk 0: where the prefix tuple goes
|
||
|
* Backup Blk 1: where the postfix tuple goes (if different page)
|
||
|
*/
|
||
|
typedef struct spgxlogSplitTuple
|
||
|
{
|
||
|
/* where the prefix tuple goes */
|
||
|
OffsetNumber offnumPrefix;
|
||
|
|
||
|
/* where the postfix tuple goes */
|
||
|
OffsetNumber offnumPostfix;
|
||
|
bool newPage; /* need to init that page? */
|
||
|
bool postfixBlkSame; /* was postfix tuple put on same page as
|
||
|
* prefix? */
|
||
|
|
||
|
/*
|
||
|
* new prefix inner tuple follows, then new postfix inner tuple (both are
|
||
|
* unaligned!)
|
||
|
*/
|
||
|
} spgxlogSplitTuple;
|
||
|
|
||
|
/*
|
||
|
* Buffer references in the rdata array are:
|
||
|
* Backup Blk 0: Src page (only if not root)
|
||
|
* Backup Blk 1: Dest page (if used)
|
||
|
* Backup Blk 2: Inner page
|
||
|
* Backup Blk 3: Parent page (if any, and different from Inner)
|
||
|
*/
|
||
|
typedef struct spgxlogPickSplit
|
||
|
{
|
||
|
bool isRootSplit;
|
||
|
|
||
|
uint16 nDelete; /* n to delete from Src */
|
||
|
uint16 nInsert; /* n to insert on Src and/or Dest */
|
||
|
bool initSrc; /* re-init the Src page? */
|
||
|
bool initDest; /* re-init the Dest page? */
|
||
|
|
||
|
/* where to put new inner tuple */
|
||
|
OffsetNumber offnumInner;
|
||
|
bool initInner; /* re-init the Inner page? */
|
||
|
|
||
|
bool storesNulls; /* pages are in the nulls tree? */
|
||
|
|
||
|
/* where the parent downlink is, if any */
|
||
|
bool innerIsParent; /* is parent the same as inner page? */
|
||
|
OffsetNumber offnumParent;
|
||
|
uint16 nodeI;
|
||
|
|
||
|
spgxlogState stateSrc;
|
||
|
|
||
|
/*----------
|
||
|
* data follows:
|
||
|
* array of deleted tuple numbers, length nDelete
|
||
|
* array of inserted tuple numbers, length nInsert
|
||
|
* array of page selector bytes for inserted tuples, length nInsert
|
||
|
* new inner tuple (unaligned!)
|
||
|
* list of leaf tuples, length nInsert (unaligned!)
|
||
|
*----------
|
||
|
*/
|
||
|
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
|
||
|
} spgxlogPickSplit;
|
||
|
|
||
|
#define SizeOfSpgxlogPickSplit offsetof(spgxlogPickSplit, offsets)
|
||
|
|
||
|
typedef struct spgxlogVacuumLeaf
|
||
|
{
|
||
|
uint16 nDead; /* number of tuples to become DEAD */
|
||
|
uint16 nPlaceholder; /* number of tuples to become PLACEHOLDER */
|
||
|
uint16 nMove; /* number of tuples to move */
|
||
|
uint16 nChain; /* number of tuples to re-chain */
|
||
|
|
||
|
spgxlogState stateSrc;
|
||
|
|
||
|
/*----------
|
||
|
* data follows:
|
||
|
* tuple numbers to become DEAD
|
||
|
* tuple numbers to become PLACEHOLDER
|
||
|
* tuple numbers to move from (and replace with PLACEHOLDER)
|
||
|
* tuple numbers to move to (replacing what is there)
|
||
|
* tuple numbers to update nextOffset links of
|
||
|
* tuple numbers to insert in nextOffset links
|
||
|
*----------
|
||
|
*/
|
||
|
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
|
||
|
} spgxlogVacuumLeaf;
|
||
|
|
||
|
#define SizeOfSpgxlogVacuumLeaf offsetof(spgxlogVacuumLeaf, offsets)
|
||
|
|
||
|
typedef struct spgxlogVacuumRoot
|
||
|
{
|
||
|
/* vacuum a root page when it is also a leaf */
|
||
|
uint16 nDelete; /* number of tuples to delete */
|
||
|
|
||
|
spgxlogState stateSrc;
|
||
|
|
||
|
/* offsets of tuples to delete follow */
|
||
|
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
|
||
|
} spgxlogVacuumRoot;
|
||
|
|
||
|
#define SizeOfSpgxlogVacuumRoot offsetof(spgxlogVacuumRoot, offsets)
|
||
|
|
||
|
typedef struct spgxlogVacuumRedirect
|
||
|
{
|
||
|
uint16 nToPlaceholder; /* number of redirects to make placeholders */
|
||
|
OffsetNumber firstPlaceholder; /* first placeholder tuple to remove */
|
||
|
TransactionId newestRedirectXid; /* newest XID of removed redirects */
|
||
|
|
||
|
/* offsets of redirect tuples to make placeholders follow */
|
||
|
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
|
||
|
} spgxlogVacuumRedirect;
|
||
|
|
||
|
#define SizeOfSpgxlogVacuumRedirect offsetof(spgxlogVacuumRedirect, offsets)
|
||
|
|
||
|
extern void spg_redo(XLogReaderState *record);
|
||
|
extern void spg_desc(StringInfo buf, XLogReaderState *record);
|
||
|
extern const char *spg_identify(uint8 info);
|
||
|
extern void spg_xlog_startup(void);
|
||
|
extern void spg_xlog_cleanup(void);
|
||
|
extern void spg_mask(char *pagedata, BlockNumber blkno);
|
||
|
|
||
|
#endif /* SPGXLOG_H */
|