mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
Disallow COPY FREEZE on partitioned tables
This didn't actually work: COPY would fail to flush the right files, and instead would try to flush a non-existing file, causing the whole transaction to fail. Cope by raising an error as soon as the command is sent instead, to avoid a nasty later surprise. Of course, it would be much better to make it work, but we don't have a patch for that yet, and we don't know if we'll want to backpatch one when we do. Reported-by: Tomas Vondra Author: David Rowley Reviewed-by: Amit Langote, Steve Singer, Tomas Vondra
This commit is contained in:
parent
fc47e99a15
commit
5c9a5513a3
@ -1535,8 +1535,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
|
||||
needs to be written, because in case of an error, the files
|
||||
containing the newly loaded data will be removed anyway.
|
||||
However, this consideration only applies when
|
||||
<xref linkend="guc-wal-level"/> is <literal>minimal</literal> as all commands
|
||||
must write WAL otherwise.
|
||||
<xref linkend="guc-wal-level"/> is <literal>minimal</literal> for
|
||||
non-partitioned tables as all commands must write WAL otherwise.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
@ -224,7 +224,9 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
|
||||
This is intended as a performance option for initial data loading.
|
||||
Rows will be frozen only if the table being loaded has been created
|
||||
or truncated in the current subtransaction, there are no cursors
|
||||
open and there are no older snapshots held by this transaction.
|
||||
open and there are no older snapshots held by this transaction. It is
|
||||
currently not possible to perform a <command>COPY FREEZE</command> on
|
||||
a partitioned table.
|
||||
</para>
|
||||
<para>
|
||||
Note that all other sessions will immediately be able to see the data
|
||||
|
@ -2416,11 +2416,20 @@ CopyFrom(CopyState cstate)
|
||||
* go into pages containing tuples from any other transactions --- but this
|
||||
* must be the case if we have a new table or new relfilenode, so we need
|
||||
* no additional work to enforce that.
|
||||
*
|
||||
* We currently don't support this optimization if the COPY target is a
|
||||
* partitioned table as we currently only lazily initialize partition
|
||||
* information when routing the first tuple to the partition. We cannot
|
||||
* know at this stage if we can perform this optimization. It should be
|
||||
* possible to improve on this, but it does mean maintaining heap insert
|
||||
* option flags per partition and setting them when we first open the
|
||||
* partition.
|
||||
*----------
|
||||
*/
|
||||
/* createSubid is creation check, newRelfilenodeSubid is truncation check */
|
||||
if (cstate->rel->rd_createSubid != InvalidSubTransactionId ||
|
||||
cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId)
|
||||
if (cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
|
||||
(cstate->rel->rd_createSubid != InvalidSubTransactionId ||
|
||||
cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId))
|
||||
{
|
||||
hi_options |= HEAP_INSERT_SKIP_FSM;
|
||||
if (!XLogIsNeeded())
|
||||
@ -2440,6 +2449,22 @@ CopyFrom(CopyState cstate)
|
||||
*/
|
||||
if (cstate->freeze)
|
||||
{
|
||||
/*
|
||||
* We currently disallow COPY FREEZE on partitioned tables. The
|
||||
* reason for this is that we've simply not yet opened the partitions
|
||||
* to determine if the optimization can be applied to them. We could
|
||||
* go and open them all here, but doing so may be quite a costly
|
||||
* overhead for small copies. In any case, we may just end up routing
|
||||
* tuples to a small number of partitions. It seems better just to
|
||||
* raise an ERROR for partitioned tables.
|
||||
*/
|
||||
if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot perform FREEZE on a partitioned table")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tolerate one registration for the benefit of FirstXactSnapshot.
|
||||
* Scan-bearing queries generally create at least two registrations,
|
||||
|
@ -159,6 +159,12 @@ truncate parted_copytest;
|
||||
|
||||
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv';
|
||||
|
||||
-- Ensure COPY FREEZE errors for partitioned tables.
|
||||
begin;
|
||||
truncate parted_copytest;
|
||||
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv' (freeze);
|
||||
rollback;
|
||||
|
||||
select tableoid::regclass,count(*),sum(a) from parted_copytest
|
||||
group by tableoid order by tableoid::regclass::name;
|
||||
|
||||
|
@ -113,6 +113,12 @@ insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x;
|
||||
copy (select * from parted_copytest order by a) to '@abs_builddir@/results/parted_copytest.csv';
|
||||
truncate parted_copytest;
|
||||
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv';
|
||||
-- Ensure COPY FREEZE errors for partitioned tables.
|
||||
begin;
|
||||
truncate parted_copytest;
|
||||
copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv' (freeze);
|
||||
ERROR: cannot perform FREEZE on a partitioned table
|
||||
rollback;
|
||||
select tableoid::regclass,count(*),sum(a) from parted_copytest
|
||||
group by tableoid order by tableoid::regclass::name;
|
||||
tableoid | count | sum
|
||||
|
Loading…
Reference in New Issue
Block a user