Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8683195

Browse files
committed
Ignore temporary relations in RelidByRelfilenumber()
Temporary relations may share the same RelFileNumber with a permanentrelation, or other temporary relations associated with other sessions.Being able to uniquely identify a temporary relation would requireRelidByRelfilenumber() to know about the proc number of the temporaryrelation it wants to identify, something it is not designed for sinceits introduction inf01d1ae.There are currently three callers of RelidByRelfilenumber():- autoprewarm.- Logical decoding, reorder buffer.- pg_filenode_relation(), that attempts to find a relation OID based ona tablespace OID and a RelFileNumber.This makes the situation problematic particularly for the first twocases, leading to the possibility of random ERRORs due toinconsistencies that temporary relations can create in the cachemaintained by RelidByRelfilenumber(). The third case should be less ofan issue, as I suspect that there are few direct callers ofpg_filenode_relation().The window where the ERRORs are happen is very narrow, requiring an OIDwraparound to create a lookup conflict in RelidByRelfilenumber() with atemporary table reusing the same OID as another relation already cached.The problem is easier to reach in workloads with a high OID consumptionrate, especially with a higher number of temporary relations created.We could get pg_filenode_relation() and RelidByRelfilenumber() to workwith temporary relations if provided the means to identify them with anoptional proc number given in input, but the years have also shown thatwe do not have a use case for it, yet. Note that this could not bebackpatched if pg_filenode_relation() needs changes. It is simpler toignore temporary relations.Reported-by: Shenhao Wang <wangsh.fnst@fujitsu.com>Author: Vignesh C <vignesh21@gmail.com>Reviewed-By: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>Reviewed-By: Robert Haas <robertmhaas@gmail.com>Reviewed-By: Kyotaro Horiguchi <horikyota.ntt@gmail.com>Reviewed-By: Takamichi Osumi <osumi.takamichi@fujitsu.com>Reviewed-By: Michael Paquier <michael@paquier.xyz>Reviewed-By: Masahiko Sawada <sawada.mshk@gmail.com>Reported-By: Shenhao Wang <wangsh.fnst@fujitsu.com>Discussion:https://postgr.es/m/bbaaf9f9-ebb2-645f-54bb-34d6efc7ac42@fujitsu.comBackpatch-through: 13
1 parentb942360 commit8683195

File tree

7 files changed

+41
-4
lines changed

7 files changed

+41
-4
lines changed

‎doc/src/sgml/func.sgml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30362,7 +30362,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
3036230362
<function>pg_relation_filepath</function>. For a relation in the
3036330363
database's default tablespace, the tablespace can be specified as zero.
3036430364
Returns <literal>NULL</literal> if no relation in the current database
30365-
is associated with the given values.
30365+
is associated with the given values, or if dealing with a temporary
30366+
relation.
3036630367
</para></entry>
3036730368
</row>
3036830369
</tbody>

‎src/backend/utils/adt/dbsize.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,9 @@ pg_relation_filenode(PG_FUNCTION_ARGS)
938938
*
939939
* We don't fail but return NULL if we cannot find a mapping.
940940
*
941+
* Temporary relations are not detected, returning NULL (see
942+
* RelidByRelfilenumber() for the reasons).
943+
*
941944
* InvalidOid can be passed instead of the current database's default
942945
* tablespace.
943946
*/

‎src/backend/utils/cache/relfilenumbermap.c‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ InitializeRelfilenumberMap(void)
130130
* Map a relation's (tablespace, relfilenumber) to a relation's oid and cache
131131
* the result.
132132
*
133+
* A temporary relation may share its relfilenumber with a permanent relation
134+
* or temporary relations created in other backends. Being able to uniquely
135+
* identify a temporary relation would require a backend's proc number, which
136+
* we do not know about. Hence, this function ignores this case.
137+
*
133138
* Returns InvalidOid if no relation matching the criteria could be found.
134139
*/
135140
Oid
@@ -208,6 +213,9 @@ RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)
208213
{
209214
Form_pg_classclassform= (Form_pg_class)GETSTRUCT(ntp);
210215

216+
if (classform->relpersistence==RELPERSISTENCE_TEMP)
217+
continue;
218+
211219
if (found)
212220
elog(ERROR,
213221
"unexpected duplicate for tablespace %u, relfilenumber %u",

‎src/test/regress/expected/alter_table.out‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3567,12 +3567,15 @@ SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment F
35673567
-- filenode function call can return NULL for a relation dropped concurrently
35683568
-- with the call's surrounding query, so ignore a NULL mapped_oid for
35693569
-- relations that no longer exist after all calls finish.
3570+
-- Temporary relations are ignored, as not supported by pg_filenode_relation().
35703571
CREATE TEMP TABLE filenode_mapping AS
35713572
SELECT
35723573
oid, mapped_oid, reltablespace, relfilenode, relname
35733574
FROM pg_class,
35743575
pg_filenode_relation(reltablespace, pg_relation_filenode(oid)) AS mapped_oid
3575-
WHERE relkind IN ('r', 'i', 'S', 't', 'm') AND mapped_oid IS DISTINCT FROM oid;
3576+
WHERE relkind IN ('r', 'i', 'S', 't', 'm')
3577+
AND relpersistence != 't'
3578+
AND mapped_oid IS DISTINCT FROM oid;
35763579
SELECT m.* FROM filenode_mapping m LEFT JOIN pg_class c ON c.oid = m.oid
35773580
WHERE c.oid IS NOT NULL OR m.mapped_oid IS NOT NULL;
35783581
oid | mapped_oid | reltablespace | relfilenode | relname

‎src/test/regress/expected/create_table.out‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ ERROR: tables declared WITH OIDS are not supported
102102
-- but explicitly not adding oids is still supported
103103
CREATE TEMP TABLE withoutoid() WITHOUT OIDS; DROP TABLE withoutoid;
104104
CREATE TEMP TABLE withoutoid() WITH (oids = false); DROP TABLE withoutoid;
105+
-- temporary tables are ignored by pg_filenode_relation().
106+
CREATE TEMP TABLE relation_filenode_check(c1 int);
107+
SELECT relpersistence,
108+
pg_filenode_relation (reltablespace, pg_relation_filenode(oid))
109+
FROM pg_class
110+
WHERE relname = 'relation_filenode_check';
111+
relpersistence | pg_filenode_relation
112+
----------------+----------------------
113+
t |
114+
(1 row)
115+
116+
DROP TABLE relation_filenode_check;
105117
-- check restriction with default expressions
106118
-- invalid use of column reference in default expressions
107119
CREATE TABLE default_expr_column (id int DEFAULT (id));

‎src/test/regress/sql/alter_table.sql‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,13 +2202,15 @@ SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment F
22022202
-- filenode function call can return NULL for a relation dropped concurrently
22032203
-- with the call's surrounding query, so ignore a NULL mapped_oid for
22042204
-- relations that no longer exist after all calls finish.
2205+
-- Temporary relations are ignored, as not supported by pg_filenode_relation().
22052206
CREATE TEMP TABLE filenode_mappingAS
22062207
SELECT
22072208
oid, mapped_oid, reltablespace, relfilenode, relname
22082209
FROM pg_class,
22092210
pg_filenode_relation(reltablespace, pg_relation_filenode(oid))AS mapped_oid
2210-
WHERE relkindIN ('r','i','S','t','m')AND mapped_oid IS DISTINCTFROMoid;
2211-
2211+
WHERE relkindIN ('r','i','S','t','m')
2212+
AND relpersistence!='t'
2213+
AND mapped_oid IS DISTINCTFROMoid;
22122214
SELECT m.*FROM filenode_mapping mLEFT JOIN pg_class cONc.oid=m.oid
22132215
WHEREc.oidIS NOT NULLORm.mapped_oidIS NOT NULL;
22142216

‎src/test/regress/sql/create_table.sql‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ CREATE TABLE withoid() WITH (oids = true);
6868
CREATE TEMP TABLE withoutoid() WITHOUT OIDS;DROPTABLEwithoutoid;
6969
CREATE TEMP TABLE withoutoid() WITH (oids= false);DROPTABLEwithoutoid;
7070

71+
-- temporary tables are ignored by pg_filenode_relation().
72+
CREATE TEMP TABLE relation_filenode_check(c1int);
73+
SELECT relpersistence,
74+
pg_filenode_relation (reltablespace, pg_relation_filenode(oid))
75+
FROM pg_class
76+
WHERE relname='relation_filenode_check';
77+
DROPTABLE relation_filenode_check;
78+
7179
-- check restriction with default expressions
7280
-- invalid use of column reference in default expressions
7381
CREATETABLEdefault_expr_column (idint DEFAULT (id));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp