Re: Temporary tables versus wraparound... again - Mailing list pgsql-hackers

From Greg Stark
Subject Re: Temporary tables versus wraparound... again
Date
Msg-id CAM-w4HM-sb5+tWEE6H4WGMgVbHWcCG0rJaCjJ0iWvvMf=krXag@mail.gmail.com
Whole thread Raw
In response to Re: Temporary tables versus wraparound... again  (Noah Misch <noah@leadboat.com>)
Responses Re: Temporary tables versus wraparound... again  (Masahiko Sawada <sawada.mshk@gmail.com>)
List pgsql-hackers
On Mon, 9 Nov 2020 at 00:17, Noah Misch <noah@leadboat.com> wrote:
>
> > 2) adding the dependency on heapam.h to heap.c makes sense because of
> > heap_inplace_update bt it may be a bit annoying because I suspect
> > that's a useful sanity check that the tableam stuff hasn't been
> > bypassed
>
> That is not terrible.  How plausible would it be to call vac_update_relstats()
> for this, instead of reimplementing part of it?

It didn't seem worth it to change its API to add boolean flags to skip
setting some of the variables (I was originally only doing
relfrozenxid and minmmxid). Now that I'm doing most of the variables
maybe it makes a bit more sense.

> > @@ -3340,6 +3383,7 @@ heap_truncate_one_rel(Relation rel)
> >
> >       /* Truncate the underlying relation */
> >       table_relation_nontransactional_truncate(rel);
> > +     ResetVacStats(rel);
>
> I didn't test, but I expect this will cause a stats reset for the second
> TRUNCATE here:
>
> CREATE TABLE t ();
> ...
> BEGIN;
> TRUNCATE t;
> TRUNCATE t;  -- inplace relfrozenxid reset
> ROLLBACK;  -- inplace reset survives
>
> Does that indeed happen?

Apparently no, see below.  I have to say I was pretty puzzled by the
actual behaviour which is that the rollback actually does roll back
the inplace update. But I *think* what is happening is that the first
truncate does an MVCC update so the inplace update happens only to the
newly created tuple which is never commited.

Thinking about things a bit this does worry me a bit. I wonder if
inplace update is really safe outside of vacuum where we know we're
not in a transaction that can be rolled back. But IIRC doing a
non-inplace update on pg_class for these columns breaks other things.
I don't know if that's still true.

Also, in checking this question I realized I had missed 3d351d91. I
should be initializing reltuples to -1 not 0.


postgres=# vacuum t;
VACUUM
postgres=# select
relname,relpages,reltuples,relallvisible,relfrozenxid from pg_class
where oid='t'::regclass;
 relname | relpages | reltuples | relallvisible | relfrozenxid
---------+----------+-----------+---------------+--------------
 t       |        9 |      2000 |             9 |        15557
(1 row)

postgres=# begin;
BEGIN
postgres=*# truncate t;
TRUNCATE TABLE
postgres=*# truncate t;
TRUNCATE TABLE
postgres=*# select
relname,relpages,reltuples,relallvisible,relfrozenxid from pg_class
where oid='t'::regclass;
 relname | relpages | reltuples | relallvisible | relfrozenxid
---------+----------+-----------+---------------+--------------
 t       |        0 |         0 |             0 |        15562
(1 row)

postgres=*# abort;
ROLLBACK
postgres=# select
relname,relpages,reltuples,relallvisible,relfrozenxid from pg_class
where oid='t'::regclass;
 relname | relpages | reltuples | relallvisible | relfrozenxid
---------+----------+-----------+---------------+--------------
 t       |        9 |      2000 |             9 |        15557
(1 row)




-- 
greg



pgsql-hackers by date:

Previous
From: Fujii Masao
Date:
Subject: Re: document pg_settings view doesn't display custom options
Next
From: Peter Smith
Date:
Subject: Re: [HACKERS] logical decoding of two-phase transactions