From edc69f750fa13e252bff67f4aa615d4fdcec2b5e Mon Sep 17 00:00:00 2001 From: kommih Date: Mon, 22 Oct 2018 17:58:27 +1100 Subject: [PATCH 3/3] init fork API API to create INIT_FORKNUM file with wrapper table_create_init_fork. --- src/backend/access/heap/heapam_handler.c | 27 +++++++++++++++++++++++- src/backend/catalog/heap.c | 24 ++------------------- src/backend/commands/tablecmds.c | 4 ++-- src/include/access/tableam.h | 10 +++++++++ src/include/catalog/heap.h | 2 -- 5 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index c3960dc91f..c0cfbe74b1 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -30,6 +30,7 @@ #include "catalog/catalog.h" #include "catalog/index.h" #include "catalog/pg_am_d.h" +#include "catalog/storage_xlog.h" #include "executor/executor.h" #include "pgstat.h" #include "storage/lmgr.h" @@ -2116,6 +2117,28 @@ heap_copy_for_cluster(Relation OldHeap, Relation NewHeap, Relation OldIndex, pfree(isnull); } +/* + * Set up an init fork for an unlogged table so that it can be correctly + * reinitialized on restart. An immediate sync is required even if the + * page has been logged, because the write did not go through + * shared_buffers and therefore a concurrent checkpoint may have moved + * the redo pointer past our xlog record. Recovery may as well remove it + * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE + * record. Therefore, logging is necessary even if wal_level=minimal. + */ +static void +heap_create_init_fork(Relation rel) +{ + Assert(rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_MATVIEW || + rel->rd_rel->relkind == RELKIND_TOASTVALUE); + RelationOpenSmgr(rel); + smgrcreate(rel->rd_smgr, INIT_FORKNUM, false); + log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM); + smgrimmedsync(rel->rd_smgr, INIT_FORKNUM); +} + + static const TableAmRoutine heapam_methods = { .type = T_TableAmRoutine, @@ -2163,7 +2186,9 @@ static const TableAmRoutine heapam_methods = { .index_build_range_scan = IndexBuildHeapRangeScan, - .index_validate_scan = validate_index_heapscan + .index_validate_scan = validate_index_heapscan, + + .CreateInitFork = heap_create_init_fork }; const TableAmRoutine * diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 38b368f916..8e7c8ce684 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -32,6 +32,7 @@ #include "access/htup_details.h" #include "access/multixact.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "access/xlog.h" @@ -1425,7 +1426,7 @@ heap_create_with_catalog(const char *relname, */ if (relpersistence == RELPERSISTENCE_UNLOGGED && relkind != RELKIND_PARTITIONED_TABLE) - heap_create_init_fork(new_rel_desc); + table_create_init_fork(new_rel_desc); /* * ok, the relation has been cataloged, so close our relations and return @@ -1437,27 +1438,6 @@ heap_create_with_catalog(const char *relname, return relid; } -/* - * Set up an init fork for an unlogged table so that it can be correctly - * reinitialized on restart. An immediate sync is required even if the - * page has been logged, because the write did not go through - * shared_buffers and therefore a concurrent checkpoint may have moved - * the redo pointer past our xlog record. Recovery may as well remove it - * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE - * record. Therefore, logging is necessary even if wal_level=minimal. - */ -void -heap_create_init_fork(Relation rel) -{ - Assert(rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_MATVIEW || - rel->rd_rel->relkind == RELKIND_TOASTVALUE); - RelationOpenSmgr(rel); - smgrcreate(rel->rd_smgr, INIT_FORKNUM, false); - log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM); - smgrimmedsync(rel->rd_smgr, INIT_FORKNUM); -} - /* * RelationRemoveInheritance * diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f3526b267d..3c46a48882 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1649,7 +1649,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence, RecentXmin, minmulti); if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED) - heap_create_init_fork(rel); + table_create_init_fork(rel); heap_relid = RelationGetRelid(rel); toast_relid = rel->rd_rel->reltoastrelid; @@ -1663,7 +1663,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence, RecentXmin, minmulti); if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED) - heap_create_init_fork(rel); + table_create_init_fork(rel); heap_close(rel, NoLock); } diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 7fe6ff6c22..79c71b06e5 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -194,6 +194,8 @@ struct SampleScanState; typedef bool (*SampleScanNextBlock_function)(TableScanDesc scan, struct SampleScanState *scanstate); typedef bool (*SampleScanNextTuple_function)(TableScanDesc scan, struct SampleScanState *scanstate, TupleTableSlot *slot); +typedef void (*CreateInitFork_function)(Relation rel); + /* * API struct for a table AM. Note this must be allocated in a * server-lifetime manner, typically as a static const struct. @@ -250,6 +252,8 @@ typedef struct TableAmRoutine IndexBuildRangeScan_function index_build_range_scan; IndexValidateScan_function index_validate_scan; + + CreateInitFork_function CreateInitFork; } TableAmRoutine; static inline const TupleTableSlotOps* @@ -741,6 +745,12 @@ table_index_build_range_scan(Relation heapRelation, scan); } +static inline void +table_create_init_fork(Relation relation) +{ + relation->rd_tableamroutine->CreateInitFork(relation); +} + extern BlockNumber table_parallelscan_nextpage(TableScanDesc scan); extern void table_parallelscan_startblock_init(TableScanDesc scan); extern Size table_parallelscan_estimate(Snapshot snapshot); diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 4584b3473c..c0e706ecc9 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -77,8 +77,6 @@ extern Oid heap_create_with_catalog(const char *relname, Oid relrewrite, ObjectAddress *typaddress); -extern void heap_create_init_fork(Relation rel); - extern void heap_drop_with_catalog(Oid relid); extern void heap_truncate(List *relids); -- 2.18.0.windows.1