2017-02-14 21:37:59 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* gistxlog.h
|
|
|
|
* gist xlog routines
|
|
|
|
*
|
2019-01-02 18:44:25 +01:00
|
|
|
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
|
2017-02-14 21:37:59 +01:00
|
|
|
* 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
|
2019-05-22 18:55:34 +02:00
|
|
|
#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 */
|
2017-02-14 21:37:59 +01:00
|
|
|
#define XLOG_GIST_PAGE_SPLIT 0x30
|
|
|
|
/* #define XLOG_GIST_INSERT_COMPLETE 0x40 */ /* not used anymore */
|
Generate less WAL during GiST, GIN and SP-GiST index build.
Instead of WAL-logging every modification during the build separately,
first build the index without any WAL-logging, and make a separate pass
through the index at the end, to write all pages to the WAL. This
significantly reduces the amount of WAL generated, and is usually also
faster, despite the extra I/O needed for the extra scan through the index.
WAL generated this way is also faster to replay.
For GiST, the LSN-NSN interlock makes this a little tricky. All pages must
be marked with a valid (i.e. non-zero) LSN, so that the parent-child
LSN-NSN interlock works correctly. We now use magic value 1 for that during
index build. Change the fake LSN counter to begin from 1000, so that 1 is
safely smaller than any real or fake LSN. 2 would've been enough for our
purposes, but let's reserve a bigger range, in case we need more special
values in the future.
Author: Anastasia Lubennikova, Andrey V. Lepikhov
Reviewed-by: Heikki Linnakangas, Dmitry Dolgov
2019-04-03 16:03:15 +02:00
|
|
|
/* #define XLOG_GIST_CREATE_INDEX 0x50 */ /* not used anymore */
|
2019-03-22 12:21:20 +01:00
|
|
|
#define XLOG_GIST_PAGE_DELETE 0x60
|
2017-02-14 21:37:59 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2018-12-21 00:37:37 +01:00
|
|
|
/*
|
|
|
|
* Backup Blk 0: Leaf page, whose index tuples are deleted.
|
|
|
|
*/
|
|
|
|
typedef struct gistxlogDelete
|
|
|
|
{
|
2019-04-22 23:28:30 +02:00
|
|
|
TransactionId latestRemovedXid;
|
2018-12-21 00:37:37 +01:00
|
|
|
uint16 ntodelete; /* number of deleted offsets */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In payload of blk 0 : todelete OffsetNumbers
|
|
|
|
*/
|
|
|
|
} gistxlogDelete;
|
|
|
|
|
|
|
|
#define SizeOfGistxlogDelete (offsetof(gistxlogDelete, ntodelete) + sizeof(uint16))
|
|
|
|
|
2017-02-14 21:37:59 +01:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2019-03-22 12:21:20 +01:00
|
|
|
/*
|
|
|
|
* 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 */
|
2019-05-22 18:55:34 +02:00
|
|
|
OffsetNumber downlinkOffset; /* Offset of downlink referencing this
|
|
|
|
* page */
|
2019-03-22 12:21:20 +01:00
|
|
|
} 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))
|
|
|
|
|
2017-02-14 21:37:59 +01:00
|
|
|
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
|