mirror of
https://github.com/postgres/postgres.git
synced 2025-08-24 09:27:52 +03:00
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
This commit is contained in:
@@ -71,6 +71,7 @@ extern int gin_pending_list_limit;
|
||||
|
||||
/* ginutil.c */
|
||||
extern void ginGetStats(Relation index, GinStatsData *stats);
|
||||
extern void ginUpdateStats(Relation index, const GinStatsData *stats);
|
||||
extern void ginUpdateStats(Relation index, const GinStatsData *stats,
|
||||
bool is_build);
|
||||
|
||||
#endif /* GIN_H */
|
||||
|
@@ -16,8 +16,6 @@
|
||||
#include "lib/stringinfo.h"
|
||||
#include "storage/off.h"
|
||||
|
||||
#define XLOG_GIN_CREATE_INDEX 0x00
|
||||
|
||||
#define XLOG_GIN_CREATE_PTREE 0x10
|
||||
|
||||
typedef struct ginxlogCreatePostingTree
|
||||
|
@@ -49,6 +49,13 @@
|
||||
|
||||
typedef XLogRecPtr GistNSN;
|
||||
|
||||
/*
|
||||
* A bogus LSN / NSN value used during index build. Must be smaller than any
|
||||
* real or fake unlogged LSN, so that after an index build finishes, all the
|
||||
* splits are considered completed.
|
||||
*/
|
||||
#define GistBuildLSN ((XLogRecPtr) 1)
|
||||
|
||||
/*
|
||||
* For on-disk compatibility with pre-9.3 servers, NSN is stored as two
|
||||
* 32-bit fields on disk, same as LSNs.
|
||||
|
@@ -244,6 +244,7 @@ typedef struct
|
||||
Relation r;
|
||||
Relation heapRel;
|
||||
Size freespace; /* free space to be left */
|
||||
bool is_build;
|
||||
|
||||
GISTInsertStack *stack;
|
||||
} GISTInsertState;
|
||||
@@ -393,7 +394,8 @@ extern void gistdoinsert(Relation r,
|
||||
IndexTuple itup,
|
||||
Size freespace,
|
||||
GISTSTATE *GISTstate,
|
||||
Relation heapRel);
|
||||
Relation heapRel,
|
||||
bool is_build);
|
||||
|
||||
/* A List of these is returned from gistplacetopage() in *splitinfo */
|
||||
typedef struct
|
||||
@@ -409,7 +411,8 @@ extern bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
|
||||
Buffer leftchildbuf,
|
||||
List **splitinfo,
|
||||
bool markleftchild,
|
||||
Relation heapRel);
|
||||
Relation heapRel,
|
||||
bool is_build);
|
||||
|
||||
extern SplitedPageLayout *gistSplit(Relation r, Page page, IndexTuple *itup,
|
||||
int len, GISTSTATE *giststate);
|
||||
|
@@ -23,7 +23,7 @@
|
||||
* 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_CREATE_INDEX 0x50 */ /* not used anymore */
|
||||
#define XLOG_GIST_PAGE_DELETE 0x60
|
||||
|
||||
/*
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#include "storage/off.h"
|
||||
|
||||
/* XLOG record types for SPGiST */
|
||||
#define XLOG_SPGIST_CREATE_INDEX 0x00
|
||||
/* #define XLOG_SPGIST_CREATE_INDEX 0x00 */ /* not used anymore */
|
||||
#define XLOG_SPGIST_ADD_LEAF 0x10
|
||||
#define XLOG_SPGIST_MOVE_LEAFS 0x20
|
||||
#define XLOG_SPGIST_ADD_NODE 0x30
|
||||
|
@@ -28,6 +28,13 @@ typedef uint64 XLogRecPtr;
|
||||
#define InvalidXLogRecPtr 0
|
||||
#define XLogRecPtrIsInvalid(r) ((r) == InvalidXLogRecPtr)
|
||||
|
||||
/*
|
||||
* First LSN to use for "fake" LSNs.
|
||||
*
|
||||
* Values smaller than this can be used for special per-AM purposes.
|
||||
*/
|
||||
#define FirstNormalUnloggedLSN ((XLogRecPtr) 1000)
|
||||
|
||||
/*
|
||||
* XLogSegNo - physical log file sequence number.
|
||||
*/
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "storage/block.h"
|
||||
#include "storage/buf.h"
|
||||
#include "storage/relfilenode.h"
|
||||
#include "utils/relcache.h"
|
||||
|
||||
/*
|
||||
* The minimum size of the WAL construction working area. If you need to
|
||||
@@ -54,6 +55,8 @@ extern bool XLogCheckBufferNeedsBackup(Buffer buffer);
|
||||
extern XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum,
|
||||
BlockNumber blk, char *page, bool page_std);
|
||||
extern XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std);
|
||||
extern void log_newpage_range(Relation rel, ForkNumber forkNum,
|
||||
BlockNumber startblk, BlockNumber endblk, bool page_std);
|
||||
extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std);
|
||||
|
||||
extern void InitXLogInsert(void);
|
||||
|
Reference in New Issue
Block a user