diff options
author | Simon Riggs <simon@2ndQuadrant.com> | 2012-12-01 12:54:20 +0000 |
---|---|---|
committer | Simon Riggs <simon@2ndQuadrant.com> | 2012-12-01 12:54:20 +0000 |
commit | 8de72b66a2edcf12c812de0a73bd50b6b7d81d62 (patch) | |
tree | 3cb4fc55c3d70b7b972910cfeb22cbb7c704875a /src/backend/commands/copy.c | |
parent | 44c03efee3d15a1db3d64bc5a2da91c145a91873 (diff) | |
download | postgresql-8de72b66a2edcf12c812de0a73bd50b6b7d81d62.tar.gz postgresql-8de72b66a2edcf12c812de0a73bd50b6b7d81d62.zip |
COPY FREEZE and mark committed on fresh tables.
When a relfilenode is created in this subtransaction or
a committed child transaction and it cannot otherwise
be seen by our own process, mark tuples committed ahead
of transaction commit for all COPY commands in same
transaction. If FREEZE specified on COPY
and pre-conditions met then rows will also be frozen.
Both options designed to avoid revisiting rows after commit,
increasing performance of subsequent commands after
data load and upgrade. pg_restore changes later.
Simon Riggs, review comments from Heikki Linnakangas, Noah Misch and design
input from Tom Lane, Robert Haas and Kevin Grittner
Diffstat (limited to 'src/backend/commands/copy.c')
-rw-r--r-- | src/backend/commands/copy.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 10c89c79b91..479c4cb17d6 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -44,6 +44,7 @@ #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/portal.h" #include "utils/rel.h" #include "utils/snapmgr.h" @@ -109,6 +110,7 @@ typedef struct CopyStateData char *filename; /* filename, or NULL for STDIN/STDOUT */ bool binary; /* binary format? */ bool oids; /* include OIDs? */ + bool freeze; /* freeze rows on loading? */ bool csv_mode; /* Comma Separated Value format? */ bool header_line; /* CSV header line? */ char *null_print; /* NULL marker string (server encoding!) */ @@ -895,6 +897,14 @@ ProcessCopyOptions(CopyState cstate, errmsg("conflicting or redundant options"))); cstate->oids = defGetBoolean(defel); } + else if (strcmp(defel->defname, "freeze") == 0) + { + if (cstate->freeze) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + cstate->freeze = defGetBoolean(defel); + } else if (strcmp(defel->defname, "delimiter") == 0) { if (cstate->delim) @@ -1974,8 +1984,31 @@ CopyFrom(CopyState cstate) hi_options |= HEAP_INSERT_SKIP_FSM; if (!XLogIsNeeded()) hi_options |= HEAP_INSERT_SKIP_WAL; + + /* + * Optimize if new relfilenode was created in this subxact or + * one of its committed children and we won't see those rows later + * as part of an earlier scan or command. This ensures that if this + * subtransaction aborts then the frozen rows won't be visible + * after xact cleanup. Note that the stronger test of exactly + * which subtransaction created it is crucial for correctness + * of this optimisation. + */ + if (ThereAreNoPriorRegisteredSnapshots() && + ThereAreNoReadyPortals() && + cstate->rel->rd_newRelfilenodeSubid == GetCurrentSubTransactionId()) + { + hi_options |= HEAP_INSERT_COMMITTED; + if (cstate->freeze) + hi_options |= HEAP_INSERT_FROZEN; + } } + if (cstate->freeze && (hi_options & HEAP_INSERT_FROZEN) == 0) + ereport(NOTICE, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("FREEZE option specified but pre-conditions not met"))); + /* * We need a ResultRelInfo so we can use the regular executor's * index-entry-making machinery. (There used to be a huge amount of code |