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

Commit7ea20a2

Browse files
committed
Avoid failure if autovacuum tries to access a just-dropped temp namespace.
Such an access became possible when commit246a6c8 added moreaggressive cleanup of orphaned temp relations by autovacuum.Since autovacuum's snapshot might be slightly stale, it couldattempt to access an already-dropped temp namespace, resulting inan assertion failure or null-pointer dereference. (In practice,since we don't drop temp namespaces automatically but merelyrecycle them, this situation could only arise if a superuser doesa manual drop of a temp namespace. Still, that should be allowed.)The core of the bug, IMO, is that isTempNamespaceInUse and its callersfailed to think hard about whether to treat "temp namespace isn't there"differently from "temp namespace isn't in use". In hopes of forestallingfuture mistakes of the same ilk, replace that function with a new onecheckTempNamespaceStatus, which makes the same tests but returns athree-way enum rather than just a bool. isTempNamespaceInUse is goneentirely in HEAD; but just in case some external code is relying on it,keep it in the back branches, as a bug-compatible wrapper around thenew function.Per report originally from Prabhat Kumar Sahu, investigated by MahendraSingh and Michael Paquier; the final form of the patch is my fault.This replaces the failed fix attempt ina052f6c.Backpatch as far as v11, as246a6c8 was.Discussion:https://postgr.es/m/CAKYtNAr9Zq=1-ww4etHo-VCC-k120YxZy5OS01VkaLPaDbv2tg@mail.gmail.com
1 parent880643b commit7ea20a2

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

‎src/backend/catalog/namespace.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3215,16 +3215,16 @@ isOtherTempNamespace(Oid namespaceId)
32153215
}
32163216

32173217
/*
3218-
*isTempNamespaceInUse - is the given namespace owned and actively used
3218+
*checkTempNamespaceStatus - is the given namespace owned and actively used
32193219
* by a backend?
32203220
*
32213221
* Note: this can be used while scanning relations in pg_class to detect
32223222
* orphaned temporary tables or namespaces with a backend connected to a
32233223
* given database. The result may be out of date quickly, so the caller
32243224
* must be careful how to handle this information.
32253225
*/
3226-
bool
3227-
isTempNamespaceInUse(OidnamespaceId)
3226+
TempNamespaceStatus
3227+
checkTempNamespaceStatus(OidnamespaceId)
32283228
{
32293229
PGPROC*proc;
32303230
intbackendId;
@@ -3233,25 +3233,35 @@ isTempNamespaceInUse(Oid namespaceId)
32333233

32343234
backendId=GetTempNamespaceBackendId(namespaceId);
32353235

3236-
/* No suchtemporarynamespace? */
3236+
/* No such namespace, or its name shows it's not temp? */
32373237
if (backendId==InvalidBackendId)
3238-
returnfalse;
3238+
returnTEMP_NAMESPACE_NOT_TEMP;
32393239

32403240
/* Is the backend alive? */
32413241
proc=BackendIdGetProc(backendId);
32423242
if (proc==NULL)
3243-
returnfalse;
3243+
returnTEMP_NAMESPACE_IDLE;
32443244

32453245
/* Is the backend connected to the same database we are looking at? */
32463246
if (proc->databaseId!=MyDatabaseId)
3247-
returnfalse;
3247+
returnTEMP_NAMESPACE_IDLE;
32483248

32493249
/* Does the backend own the temporary namespace? */
32503250
if (proc->tempNamespaceId!=namespaceId)
3251-
returnfalse;
3251+
returnTEMP_NAMESPACE_IDLE;
32523252

3253-
/* all good to go */
3254-
return true;
3253+
/* Yup, so namespace is busy */
3254+
returnTEMP_NAMESPACE_IN_USE;
3255+
}
3256+
3257+
/*
3258+
* isTempNamespaceInUse - oversimplified, deprecated version of
3259+
* checkTempNamespaceStatus
3260+
*/
3261+
bool
3262+
isTempNamespaceInUse(OidnamespaceId)
3263+
{
3264+
returncheckTempNamespaceStatus(namespaceId)==TEMP_NAMESPACE_IN_USE;
32553265
}
32563266

32573267
/*

‎src/backend/postmaster/autovacuum.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,9 +2089,10 @@ do_autovacuum(void)
20892089
{
20902090
/*
20912091
* We just ignore it if the owning backend is still active and
2092-
* using the temporary schema.
2092+
* using the temporary schema. Also, for safety, ignore it if the
2093+
* namespace doesn't exist or isn't a temp namespace after all.
20932094
*/
2094-
if (!isTempNamespaceInUse(classForm->relnamespace))
2095+
if (checkTempNamespaceStatus(classForm->relnamespace)==TEMP_NAMESPACE_IDLE)
20952096
{
20962097
/*
20972098
* The table seems to be orphaned -- although it might be that
@@ -2261,7 +2262,7 @@ do_autovacuum(void)
22612262
continue;
22622263
}
22632264

2264-
if (isTempNamespaceInUse(classForm->relnamespace))
2265+
if (checkTempNamespaceStatus(classForm->relnamespace)!=TEMP_NAMESPACE_IDLE)
22652266
{
22662267
UnlockRelationOid(relid,AccessExclusiveLock);
22672268
continue;

‎src/include/catalog/namespace.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ typedef struct _FuncCandidateList
3737
Oidargs[FLEXIBLE_ARRAY_MEMBER];/* arg types */
3838
}*FuncCandidateList;
3939

40+
/*
41+
* Result of checkTempNamespaceStatus
42+
*/
43+
typedefenumTempNamespaceStatus
44+
{
45+
TEMP_NAMESPACE_NOT_TEMP,/* nonexistent, or non-temp namespace */
46+
TEMP_NAMESPACE_IDLE,/* exists, belongs to no active session */
47+
TEMP_NAMESPACE_IN_USE/* belongs to some active session */
48+
}TempNamespaceStatus;
49+
4050
/*
4151
*Structure for xxxOverrideSearchPath functions
4252
*/
@@ -138,6 +148,7 @@ extern bool isTempToastNamespace(Oid namespaceId);
138148
externboolisTempOrTempToastNamespace(OidnamespaceId);
139149
externboolisAnyTempNamespace(OidnamespaceId);
140150
externboolisOtherTempNamespace(OidnamespaceId);
151+
externTempNamespaceStatuscheckTempNamespaceStatus(OidnamespaceId);
141152
externboolisTempNamespaceInUse(OidnamespaceId);
142153
externintGetTempNamespaceBackendId(OidnamespaceId);
143154
externOidGetTempToastNamespace(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp