mirror of
https://github.com/postgres/postgres.git
synced 2025-11-24 00:23:06 +03:00
Introduce a new smgr bulk loading facility.
The new facility makes it easier to optimize bulk loading, as the logic for buffering, WAL-logging, and syncing the relation only needs to be implemented once. It's also less error-prone: We have had a number of bugs in how a relation is fsync'd - or not - at the end of a bulk loading operation. By centralizing that logic to one place, we only need to write it correctly once. The new facility is faster for small relations: Instead of of calling smgrimmedsync(), we register the fsync to happen at next checkpoint, which avoids the fsync latency. That can make a big difference if you are e.g. restoring a schema-only dump with lots of relations. It is also slightly more efficient with large relations, as the WAL logging is performed multiple pages at a time. That avoids some WAL header overhead. The sorted GiST index build did that already, this moves the buffering to the new facility. The changes to pageinspect GiST test needs an explanation: Before this patch, the sorted GiST index build set the LSN on every page to the special GistBuildLSN value, not the LSN of the WAL record, even though they were WAL-logged. There was no particular need for it, it just happened naturally when we wrote out the pages before WAL-logging them. Now we WAL-log the pages first, like in B-tree build, so the pages are stamped with the record's real LSN. When the build is not WAL-logged, we still use GistBuildLSN. To make the test output predictable, use an unlogged index. Reviewed-by: Andres Freund Discussion: https://www.postgresql.org/message-id/30e8f366-58b3-b239-c521-422122dd5150%40iki.fi
This commit is contained in:
40
src/include/storage/bulk_write.h
Normal file
40
src/include/storage/bulk_write.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* bulk_write.h
|
||||
* Efficiently and reliably populate a new relation
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/storage/bulk_write.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef BULK_WRITE_H
|
||||
#define BULK_WRITE_H
|
||||
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
typedef struct BulkWriteState BulkWriteState;
|
||||
|
||||
/*
|
||||
* Temporary buffer to hold a page to until it's written out. Use
|
||||
* smgr_bulk_get_buf() to reserve one of these. This is a separate typedef to
|
||||
* distinguish it from other block-sized buffers passed around in the system.
|
||||
*/
|
||||
typedef PGIOAlignedBlock *BulkWriteBuffer;
|
||||
|
||||
/* forward declared from smgr.h */
|
||||
struct SMgrRelationData;
|
||||
|
||||
extern BulkWriteState *smgr_bulk_start_rel(Relation rel, ForkNumber forknum);
|
||||
extern BulkWriteState *smgr_bulk_start_smgr(struct SMgrRelationData *smgr, ForkNumber forknum, bool use_wal);
|
||||
|
||||
extern BulkWriteBuffer smgr_bulk_get_buf(BulkWriteState *bulkstate);
|
||||
extern void smgr_bulk_write(BulkWriteState *bulkstate, BlockNumber blocknum, BulkWriteBuffer buf, bool page_std);
|
||||
|
||||
extern void smgr_bulk_finish(BulkWriteState *bulkstate);
|
||||
|
||||
#endif /* BULK_WRITE_H */
|
||||
@@ -43,6 +43,7 @@ extern BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum);
|
||||
extern void mdtruncate(SMgrRelation reln, ForkNumber forknum,
|
||||
BlockNumber nblocks);
|
||||
extern void mdimmedsync(SMgrRelation reln, ForkNumber forknum);
|
||||
extern void mdregistersync(SMgrRelation reln, ForkNumber forknum);
|
||||
|
||||
extern void ForgetDatabaseSyncRequests(Oid dbid);
|
||||
extern void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo);
|
||||
|
||||
@@ -106,6 +106,7 @@ extern BlockNumber smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum);
|
||||
extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum,
|
||||
int nforks, BlockNumber *nblocks);
|
||||
extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum);
|
||||
extern void smgrregistersync(SMgrRelation reln, ForkNumber forknum);
|
||||
extern void AtEOXact_SMgr(void);
|
||||
extern bool ProcessBarrierSmgrRelease(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user