Re: "unexpected duplicate for tablespace" problem in logical replication

From: Kyotaro Horiguchi <horikyota(dot)ntt(at)gmail(dot)com>
To: wangsh(dot)fnst(at)fujitsu(dot)com
Cc: osumi(dot)takamichi(at)fujitsu(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: "unexpected duplicate for tablespace" problem in logical replication
Date: 2022-04-12 02:45:39
Message-ID: 20220412.114539.151610727144113536.horikyota.ntt@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

At Mon, 11 Apr 2022 10:24:26 +0000, "wangsh(dot)fnst(at)fujitsu(dot)com" <wangsh(dot)fnst(at)fujitsu(dot)com> wrote in
> Please see the attachment

Sorry for being late, but this seems to be in the wrong direction.

In the problem case, as you know, GetNewRelFileNode does *not* check
oid uniqueness in pg_class. The on-catalog duplicate check is done
only when the result is to be used as the *table oid* at creation. In
other cases it chooses a relfilenode that does not duplicate in
storage file names irrelevantly to the relation oid. As the result
Non-temporary and temporary tables have separate relfilenode oid
spaces, either intentional or not..

Thus, I think we don't want GetNewRelFileNode to check for duplicate
oid on pg_class if pg_class is not passed since that significantly
narrow the oid space for relfilenode. If we did something like that,
we might do check the existence of file names of the both non-temp and
temp in GetNewRelFileNode(), but that also narrows the relfilenode oid
space.

RelidByRelfilenode is called by autoprewarm, logical replication, and
pg_filenode_relation. In the autoprewarm and logical replication
cases, it is called only for non-temprary relations so letting the
function ignore (oid duplicating) temp tables works.
pg_relfilienode_relation is somewhat dubious. It is affected by this
bug. In the attached PoC, to avoid API change (in case for
back-patching), RelidByRelfilenode ignores duplcates of differernt
persistence. Also the PoC prioritize on persistent tables to
temporary ones but I'm not sure it's good decision, but otherwise we
need to change the signature of pg_filenode_relation.

The attached is an PoC of that. The first one is a reproduction-aid
code. With it applied, the following steps create duplicate
relfilenode relations.

(apply the first diff)
$ rm /tmp/hoge
$ (start postgres)
# touch /tmp/hoge
$ psql
=# create table xp (a int);
=# truncate xp;
=# create temp table xt (a int);
=# truncate xt;
=# select oid, relname, relfilenode from pg_class where relname like 'x%';
oid | relname | relfilenode
-------+---------+-------------
16384 | xp | 55555
55558 | xt | 55555
(2 rows)
=# select pg_filenode_relation(0, 55555);
ERROR: unexpected duplicate for tablespace 0, relfilenode 55555

(apply the second diff)
=# create temp table xt (a int);
=# truncate xt;
=# select pg_filenode_relation(0, 55555);
pg_filenode_relation
----------------------
xp
(1 row)

What do you think about this direction?

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachment Content-Type Size
generate_same_relfilenode.txt text/plain 557 bytes
allow_dup_relfilenodeid_PoC.txt text/plain 1.7 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message David G. Johnston 2022-04-12 02:46:29 Re: Docs for psql regarding default database name are incorrect
Previous Message Tom Lane 2022-04-11 23:07:31 Re: BUG #17462: Invalid memory access in heapam_tuple_lock