Skip to content

Commit d45e401

Browse files
committed
tableam: Add table_finish_bulk_insert().
This replaces the previous calls of heap_sync() in places using bulk-insert. By passing in the flags used for bulk-insert the AM can decide (first at insert time and then during the finish call) which of the optimizations apply to it, and what operations are necessary to finish a bulk insert operation. Also change HEAP_INSERT_* flags to TABLE_INSERT, and rename hi_options to ti_options. These changes are made even in copy.c, which hasn't yet been converted to tableam. There's no harm in doing so. Author: Andres Freund Discussion: https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
1 parent 26a76cb commit d45e401

File tree

6 files changed

+78
-46
lines changed

6 files changed

+78
-46
lines changed

src/backend/access/heap/heapam_handler.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,17 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
540540
return result;
541541
}
542542

543+
static void
544+
heapam_finish_bulk_insert(Relation relation, int options)
545+
{
546+
/*
547+
* If we skipped writing WAL, then we need to sync the heap (but not
548+
* indexes since those use WAL anyway / don't go through tableam)
549+
*/
550+
if (options & HEAP_INSERT_SKIP_WAL)
551+
heap_sync(relation);
552+
}
553+
543554

544555
/* ------------------------------------------------------------------------
545556
* DDL related callbacks for heap AM.
@@ -2401,6 +2412,7 @@ static const TableAmRoutine heapam_methods = {
24012412
.tuple_delete = heapam_tuple_delete,
24022413
.tuple_update = heapam_tuple_update,
24032414
.tuple_lock = heapam_tuple_lock,
2415+
.finish_bulk_insert = heapam_finish_bulk_insert,
24042416

24052417
.tuple_fetch_row_version = heapam_fetch_row_version,
24062418
.tuple_get_latest_tid = heap_get_latest_tid,

src/backend/commands/copy.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ static uint64 CopyTo(CopyState cstate);
319319
static void CopyOneRowTo(CopyState cstate,
320320
Datum *values, bool *nulls);
321321
static void CopyFromInsertBatch(CopyState cstate, EState *estate,
322-
CommandId mycid, int hi_options,
322+
CommandId mycid, int ti_options,
323323
ResultRelInfo *resultRelInfo, TupleTableSlot *myslot,
324324
BulkInsertState bistate,
325325
int nBufferedTuples, HeapTuple *bufferedTuples,
@@ -2328,7 +2328,7 @@ CopyFrom(CopyState cstate)
23282328
PartitionTupleRouting *proute = NULL;
23292329
ErrorContextCallback errcallback;
23302330
CommandId mycid = GetCurrentCommandId(true);
2331-
int hi_options = 0; /* start with default heap_insert options */
2331+
int ti_options = 0; /* start with default table_insert options */
23322332
BulkInsertState bistate;
23332333
CopyInsertMethod insertMethod;
23342334
uint64 processed = 0;
@@ -2392,8 +2392,8 @@ CopyFrom(CopyState cstate)
23922392
* - data is being written to relfilenode created in this transaction
23932393
* then we can skip writing WAL. It's safe because if the transaction
23942394
* doesn't commit, we'll discard the table (or the new relfilenode file).
2395-
* If it does commit, we'll have done the heap_sync at the bottom of this
2396-
* routine first.
2395+
* If it does commit, we'll have done the table_finish_bulk_insert() at
2396+
* the bottom of this routine first.
23972397
*
23982398
* As mentioned in comments in utils/rel.h, the in-same-transaction test
23992399
* is not always set correctly, since in rare cases rd_newRelfilenodeSubid
@@ -2437,9 +2437,9 @@ CopyFrom(CopyState cstate)
24372437
(cstate->rel->rd_createSubid != InvalidSubTransactionId ||
24382438
cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId))
24392439
{
2440-
hi_options |= HEAP_INSERT_SKIP_FSM;
2440+
ti_options |= TABLE_INSERT_SKIP_FSM;
24412441
if (!XLogIsNeeded())
2442-
hi_options |= HEAP_INSERT_SKIP_WAL;
2442+
ti_options |= TABLE_INSERT_SKIP_WAL;
24432443
}
24442444

24452445
/*
@@ -2491,7 +2491,7 @@ CopyFrom(CopyState cstate)
24912491
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
24922492
errmsg("cannot perform FREEZE because the table was not created or truncated in the current subtransaction")));
24932493

2494-
hi_options |= HEAP_INSERT_FROZEN;
2494+
ti_options |= TABLE_INSERT_FROZEN;
24952495
}
24962496

24972497
/*
@@ -2755,7 +2755,7 @@ CopyFrom(CopyState cstate)
27552755
{
27562756
MemoryContext oldcontext;
27572757

2758-
CopyFromInsertBatch(cstate, estate, mycid, hi_options,
2758+
CopyFromInsertBatch(cstate, estate, mycid, ti_options,
27592759
prevResultRelInfo, myslot, bistate,
27602760
nBufferedTuples, bufferedTuples,
27612761
firstBufferedLineNo);
@@ -2978,7 +2978,7 @@ CopyFrom(CopyState cstate)
29782978
if (nBufferedTuples == MAX_BUFFERED_TUPLES ||
29792979
bufferedTuplesSize > 65535)
29802980
{
2981-
CopyFromInsertBatch(cstate, estate, mycid, hi_options,
2981+
CopyFromInsertBatch(cstate, estate, mycid, ti_options,
29822982
resultRelInfo, myslot, bistate,
29832983
nBufferedTuples, bufferedTuples,
29842984
firstBufferedLineNo);
@@ -3015,7 +3015,7 @@ CopyFrom(CopyState cstate)
30153015
{
30163016
tuple = ExecFetchSlotHeapTuple(slot, true, NULL);
30173017
heap_insert(resultRelInfo->ri_RelationDesc, tuple,
3018-
mycid, hi_options, bistate);
3018+
mycid, ti_options, bistate);
30193019
ItemPointerCopy(&tuple->t_self, &slot->tts_tid);
30203020
slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
30213021
}
@@ -3050,13 +3050,13 @@ CopyFrom(CopyState cstate)
30503050
{
30513051
if (insertMethod == CIM_MULTI_CONDITIONAL)
30523052
{
3053-
CopyFromInsertBatch(cstate, estate, mycid, hi_options,
3053+
CopyFromInsertBatch(cstate, estate, mycid, ti_options,
30543054
prevResultRelInfo, myslot, bistate,
30553055
nBufferedTuples, bufferedTuples,
30563056
firstBufferedLineNo);
30573057
}
30583058
else
3059-
CopyFromInsertBatch(cstate, estate, mycid, hi_options,
3059+
CopyFromInsertBatch(cstate, estate, mycid, ti_options,
30603060
resultRelInfo, myslot, bistate,
30613061
nBufferedTuples, bufferedTuples,
30623062
firstBufferedLineNo);
@@ -3106,12 +3106,7 @@ CopyFrom(CopyState cstate)
31063106

31073107
FreeExecutorState(estate);
31083108

3109-
/*
3110-
* If we skipped writing WAL, then we need to sync the heap (but not
3111-
* indexes since those use WAL anyway)
3112-
*/
3113-
if (hi_options & HEAP_INSERT_SKIP_WAL)
3114-
heap_sync(cstate->rel);
3109+
table_finish_bulk_insert(cstate->rel, ti_options);
31153110

31163111
return processed;
31173112
}
@@ -3123,7 +3118,7 @@ CopyFrom(CopyState cstate)
31233118
*/
31243119
static void
31253120
CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid,
3126-
int hi_options, ResultRelInfo *resultRelInfo,
3121+
int ti_options, ResultRelInfo *resultRelInfo,
31273122
TupleTableSlot *myslot, BulkInsertState bistate,
31283123
int nBufferedTuples, HeapTuple *bufferedTuples,
31293124
uint64 firstBufferedLineNo)
@@ -3149,7 +3144,7 @@ CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid,
31493144
bufferedTuples,
31503145
nBufferedTuples,
31513146
mycid,
3152-
hi_options,
3147+
ti_options,
31533148
bistate);
31543149
MemoryContextSwitchTo(oldcontext);
31553150

src/backend/commands/createas.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
#include "access/heapam.h"
2828
#include "access/reloptions.h"
2929
#include "access/htup_details.h"
30-
#include "access/tableam.h"
3130
#include "access/sysattr.h"
31+
#include "access/tableam.h"
3232
#include "access/xact.h"
3333
#include "access/xlog.h"
3434
#include "catalog/namespace.h"
@@ -60,7 +60,7 @@ typedef struct
6060
Relation rel; /* relation to write to */
6161
ObjectAddress reladdr; /* address of rel, for ExecCreateTableAs */
6262
CommandId output_cid; /* cmin to insert in output tuples */
63-
int hi_options; /* heap_insert performance options */
63+
int ti_options; /* table_insert performance options */
6464
BulkInsertState bistate; /* bulk insert state */
6565
} DR_intorel;
6666

@@ -558,8 +558,8 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
558558
* We can skip WAL-logging the insertions, unless PITR or streaming
559559
* replication is in use. We can skip the FSM in any case.
560560
*/
561-
myState->hi_options = HEAP_INSERT_SKIP_FSM |
562-
(XLogIsNeeded() ? 0 : HEAP_INSERT_SKIP_WAL);
561+
myState->ti_options = TABLE_INSERT_SKIP_FSM |
562+
(XLogIsNeeded() ? 0 : TABLE_INSERT_SKIP_WAL);
563563
myState->bistate = GetBulkInsertState();
564564

565565
/* Not using WAL requires smgr_targblock be initially invalid */
@@ -586,7 +586,7 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self)
586586
table_insert(myState->rel,
587587
slot,
588588
myState->output_cid,
589-
myState->hi_options,
589+
myState->ti_options,
590590
myState->bistate);
591591

592592
/* We know this is a newly created relation, so there are no indexes */
@@ -604,9 +604,7 @@ intorel_shutdown(DestReceiver *self)
604604

605605
FreeBulkInsertState(myState->bistate);
606606

607-
/* If we skipped using WAL, must heap_sync before commit */
608-
if (myState->hi_options & HEAP_INSERT_SKIP_WAL)
609-
heap_sync(myState->rel);
607+
table_finish_bulk_insert(myState->rel, myState->ti_options);
610608

611609
/* close rel, but keep lock until commit */
612610
table_close(myState->rel, NoLock);

src/backend/commands/matview.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "access/heapam.h"
1919
#include "access/htup_details.h"
2020
#include "access/multixact.h"
21+
#include "access/tableam.h"
2122
#include "access/xact.h"
2223
#include "access/xlog.h"
2324
#include "catalog/catalog.h"
@@ -53,7 +54,7 @@ typedef struct
5354
/* These fields are filled by transientrel_startup: */
5455
Relation transientrel; /* relation to write to */
5556
CommandId output_cid; /* cmin to insert in output tuples */
56-
int hi_options; /* heap_insert performance options */
57+
int ti_options; /* table_insert performance options */
5758
BulkInsertState bistate; /* bulk insert state */
5859
} DR_transientrel;
5960

@@ -257,7 +258,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
257258
* as open scans.
258259
*
259260
* NB: We count on this to protect us against problems with refreshing the
260-
* data using HEAP_INSERT_FROZEN.
261+
* data using TABLE_INSERT_FROZEN.
261262
*/
262263
CheckTableNotInUse(matviewRel, "REFRESH MATERIALIZED VIEW");
263264

@@ -461,9 +462,9 @@ transientrel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
461462
* We can skip WAL-logging the insertions, unless PITR or streaming
462463
* replication is in use. We can skip the FSM in any case.
463464
*/
464-
myState->hi_options = HEAP_INSERT_SKIP_FSM | HEAP_INSERT_FROZEN;
465+
myState->ti_options = TABLE_INSERT_SKIP_FSM | TABLE_INSERT_FROZEN;
465466
if (!XLogIsNeeded())
466-
myState->hi_options |= HEAP_INSERT_SKIP_WAL;
467+
myState->ti_options |= TABLE_INSERT_SKIP_WAL;
467468
myState->bistate = GetBulkInsertState();
468469

469470
/* Not using WAL requires smgr_targblock be initially invalid */
@@ -490,7 +491,7 @@ transientrel_receive(TupleTableSlot *slot, DestReceiver *self)
490491
table_insert(myState->transientrel,
491492
slot,
492493
myState->output_cid,
493-
myState->hi_options,
494+
myState->ti_options,
494495
myState->bistate);
495496

496497
/* We know this is a newly created relation, so there are no indexes */
@@ -508,9 +509,7 @@ transientrel_shutdown(DestReceiver *self)
508509

509510
FreeBulkInsertState(myState->bistate);
510511

511-
/* If we skipped using WAL, must heap_sync before commit */
512-
if (myState->hi_options & HEAP_INSERT_SKIP_WAL)
513-
heap_sync(myState->transientrel);
512+
table_finish_bulk_insert(myState->transientrel, myState->ti_options);
514513

515514
/* close transientrel, but keep lock until commit */
516515
table_close(myState->transientrel, NoLock);

src/backend/commands/tablecmds.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4687,7 +4687,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
46874687
EState *estate;
46884688
CommandId mycid;
46894689
BulkInsertState bistate;
4690-
int hi_options;
4690+
int ti_options;
46914691
ExprState *partqualstate = NULL;
46924692

46934693
/*
@@ -4704,7 +4704,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
47044704
newrel = NULL;
47054705

47064706
/*
4707-
* Prepare a BulkInsertState and options for heap_insert. Because we're
4707+
* Prepare a BulkInsertState and options for table_insert. Because we're
47084708
* building a new heap, we can skip WAL-logging and fsync it to disk at
47094709
* the end instead (unless WAL-logging is required for archiving or
47104710
* streaming replication). The FSM is empty too, so don't bother using it.
@@ -4714,16 +4714,16 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
47144714
mycid = GetCurrentCommandId(true);
47154715
bistate = GetBulkInsertState();
47164716

4717-
hi_options = HEAP_INSERT_SKIP_FSM;
4717+
ti_options = TABLE_INSERT_SKIP_FSM;
47184718
if (!XLogIsNeeded())
4719-
hi_options |= HEAP_INSERT_SKIP_WAL;
4719+
ti_options |= TABLE_INSERT_SKIP_WAL;
47204720
}
47214721
else
47224722
{
47234723
/* keep compiler quiet about using these uninitialized */
47244724
mycid = 0;
47254725
bistate = NULL;
4726-
hi_options = 0;
4726+
ti_options = 0;
47274727
}
47284728

47294729
/*
@@ -4977,7 +4977,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
49774977

49784978
/* Write the tuple out to the new relation */
49794979
if (newrel)
4980-
table_insert(newrel, insertslot, mycid, hi_options, bistate);
4980+
table_insert(newrel, insertslot, mycid, ti_options, bistate);
49814981

49824982
ResetExprContext(econtext);
49834983

@@ -5000,9 +5000,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
50005000
{
50015001
FreeBulkInsertState(bistate);
50025002

5003-
/* If we skipped writing WAL, then we need to sync the heap. */
5004-
if (hi_options & HEAP_INSERT_SKIP_WAL)
5005-
heap_sync(newrel);
5003+
table_finish_bulk_insert(newrel, ti_options);
50065004

50075005
table_close(newrel, NoLock);
50085006
}

src/include/access/tableam.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,21 @@ typedef struct TableAmRoutine
380380
uint8 flags,
381381
TM_FailureData *tmfd);
382382

383+
/*
384+
* Perform operations necessary to complete insertions made via
385+
* tuple_insert and multi_insert with a BulkInsertState specified. This
386+
* e.g. may e.g. used to flush the relation when inserting with
387+
* TABLE_INSERT_SKIP_WAL specified.
388+
*
389+
* Typically callers of tuple_insert and multi_insert will just pass all
390+
* the flags the apply to them, and each AM has to decide which of them
391+
* make sense for it, and then only take actions in finish_bulk_insert
392+
* that make sense for a specific AM.
393+
*
394+
* Optional callback.
395+
*/
396+
void (*finish_bulk_insert) (Relation rel, int options);
397+
383398

384399
/* ------------------------------------------------------------------------
385400
* DDL related functionality.
@@ -1011,7 +1026,8 @@ table_compute_xid_horizon_for_tuples(Relation rel,
10111026
*
10121027
*
10131028
* The BulkInsertState object (if any; bistate can be NULL for default
1014-
* behavior) is also just passed through to RelationGetBufferForTuple.
1029+
* behavior) is also just passed through to RelationGetBufferForTuple. If
1030+
* `bistate` is provided, table_finish_bulk_insert() needs to be called.
10151031
*
10161032
* On return the slot's tts_tid and tts_tableOid are updated to reflect the
10171033
* insertion. But note that any toasting of fields within the slot is NOT
@@ -1185,6 +1201,20 @@ table_lock_tuple(Relation rel, ItemPointer tid, Snapshot snapshot,
11851201
flags, tmfd);
11861202
}
11871203

1204+
/*
1205+
* Perform operations necessary to complete insertions made via
1206+
* tuple_insert and multi_insert with a BulkInsertState specified. This
1207+
* e.g. may e.g. used to flush the relation when inserting with
1208+
* TABLE_INSERT_SKIP_WAL specified.
1209+
*/
1210+
static inline void
1211+
table_finish_bulk_insert(Relation rel, int options)
1212+
{
1213+
/* optional callback */
1214+
if (rel->rd_tableam && rel->rd_tableam->finish_bulk_insert)
1215+
rel->rd_tableam->finish_bulk_insert(rel, options);
1216+
}
1217+
11881218

11891219
/* ------------------------------------------------------------------------
11901220
* DDL related functionality.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy