1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Reject COPY TO of unlogged tables during recovery.

Unlogged tables have no data on a standby, so reading one there must
fail. SELECT and COPY (SELECT ...) TO already report a clear error,
but COPY with a table name read the table directly and failed with a
low-level error instead:

ERROR:  could not open file "base/5/16384": No such file or directory

Check for this case in COPY TO and report the same error as SELECT. On
v19 and later, also check each partition when copying from a
partitioned table, so that an unlogged partition is reported too.

Backpatch to all supported versions, since the low-level error looks
like data corruption.

Author: Jim Jones <jim.jones@uni-muenster.de>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Discussion: https://postgr.es/m/b6d71815-d362-4579-bf07-73eca01aee6d@uni-muenster.de
Backpatch-through: 14
This commit is contained in:
Masahiko Sawada
2026-10-21 10:44:17 -07:00
parent 59f48ad955
commit c517dbb31b
2 changed files with 19 additions and 0 deletions

View File

@@ -399,6 +399,11 @@ BeginCopyTo(ParseState *pstate,
RelationGetRelationName(rel))));
}
/* Temporary and unlogged relations are inaccessible during recovery. */
if (rel != NULL && !RelationIsPermanent(rel) && RecoveryInProgress())
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary or unlogged relations during recovery")));
/* Allocate workspace and zero all fields */
cstate = (CopyToStateData *) palloc0(sizeof(CopyToStateData));

View File

@@ -87,6 +87,20 @@ is($node_standby_1->safe_psql('postgres',
"SELECT pg_sequence_last_value('ulseq'::regclass) IS NULL"),
't', 'pg_sequence_last_value() on unlogged sequence on standby 1');
# Check that COPY TO rejects unlogged tables on standby
$node_primary->safe_psql(
'postgres', q{
CREATE UNLOGGED TABLE ultab (a int);
});
$node_primary->wait_for_catchup($node_standby_1, 'replay',
$node_primary->lsn('flush'));
my ($copy_ret, $copy_stdout, $copy_stderr) =
$node_standby_1->psql('postgres', 'COPY ultab TO STDOUT');
like(
$copy_stderr,
qr/cannot access temporary or unlogged relations during recovery/,
'COPY TO of unlogged table on standby 1');
# Check that only READ-only queries can run on standbys
is($node_standby_1->psql('postgres', 'INSERT INTO tab_int VALUES (1)'),
3, 'read-only queries on standby 1');