Re: "unexpected duplicate for tablespace" problem in logical replication
Kyotaro Horiguchi <horikyota.ntt@gmail.com>
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
To: wangsh.fnst@fujitsu.com
Cc: osumi.takamichi@fujitsu.com, pgsql-bugs@lists.postgresql.org
Date: 2022-04-12T02:45:39Z
Lists: pgsql-bugs
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Ignore temporary relations in RelidByRelfilenumber()
- 30b32b08c9e9 13.23 landed
- 222130edd81f 14.20 landed
- ec471008c8fc 15.15 landed
- ab874faaa1f3 16.11 landed
- dcdc95cb4d4c 17.7 landed
- 86831952ad60 18.0 landed
- ef03ea01fe47 19 (unreleased) landed
Attachments
- generate_same_relfilenode.txt (text/plain)
- allow_dup_relfilenodeid_PoC.txt (text/plain)
At Mon, 11 Apr 2022 10:24:26 +0000, "wangsh.fnst@fujitsu.com" <wangsh.fnst@fujitsu.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