Re: Unlogged materialized views

From: Jim Jones <jim(dot)jones(at)uni-muenster(dot)de>
To: Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org, Adam Brusselback <adambrusselback(at)gmail(dot)com>
Subject: Re: Unlogged materialized views
Date: 2026-10-15 17:46:11
Message-ID: 999c81c2-77ca-4903-883b-e01a31d12aab@uni-muenster.de
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 14/10/2026 17:29, Zsolt Parragi wrote:
> What is missing is the relispopulated boolean from pg_class, and I
> don't see how that could stay with this approach.

Right.

> pg_class.relispopulated could only stay if we could update it after
> recovery, but before accepting connections (as otherwise it could
> become stale for unlogged matviews), and I don't see an easy way to do
> that, that's why I implemented this patch in a different way.
> Otherwise, it could become stale, that's why the patch removes it.
>
> But looking at pgadmin, it would be easy to patch it in a way that
> works with both all earlier versions and this patch.

Right. I'm pretty sure things like this already happened in past
releases, I just thought I should bring it up in case it is avoidable --
pgAdmin certainly isn't the only tool relying on it.

I took another look and the only thing that caught my attention some
error messages:

/*
* An unlogged matview has no storage on a standby, though its
* relpopulated may still carry an epoch stamp from the primary. The
* generic recovery guard just below would reject it too, but reporting it
* as unpopulated matches what the same matview does on the primary once a
* crash has invalidated its stamp. Permanent matviews are excluded so
* plan-time behavior is unchanged. No REFRESH hint, as that cannot run
* during recovery.
*/
if (relation->rd_rel->relkind == RELKIND_MATVIEW &&
!RelationIsPermanent(relation) &&
RecoveryInProgress() &&
!RelationIsPopulated(relation))
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("materialized view \"%s\" has not been populated",
RelationGetRelationName(relation))));

I realise it is a matter of taste, but I find the generic error message
more accurate than this new one.

-- from a standby.
-- umv1 is an unlogged matview, and ut1 is an unlogged table
postgres=# select * from umv1;
ERROR: materialized view "umv1" has not been populated
postgres=# select * from ut1;
ERROR: cannot access temporary or unlogged relations during recovery

The hint in copy is not very accurate during a recovery session.

postgres=# copy umv1 to stdout;
ERROR: cannot copy from unpopulated materialized view "umv1"
HINT: Use the REFRESH MATERIALIZED VIEW command.

Other than that, I don't have anything else to add at this point. Thanks
for the patch.

BTW, while testing it I may have found a bug in unlogged tables with copy:

postgres=# copy ut1 to stdout;
ERROR: could not open file "base/5/16420": No such file or directory

.. but I will report it in another thread.

Jim

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Greg Burd 2026-10-15 17:58:44 Re: UNDO with FILEOPS, and the FLUX table AM
Previous Message Masahiko Sawada 2026-10-15 17:40:06 Re: [PG19] Promotion hangs behind a backend blocked on a stuck client