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

Commit246a6c8

Browse files
committed
Make autovacuum more aggressive to remove orphaned temp tables
Commitdafa084, added in 10, made the removal of temporary orphanedtables more aggressive. This commit makes an extra step into theaggressiveness by adding a flag in each backend's MyProc which tracksdown any temporary namespace currently in use. The flag is set when thenamespace gets created and can be reset if the temporary namespace hasbeen created in a transaction or sub-transaction which is aborted. Theflag value assignment is assumed to be atomic, so this can be done in alock-less fashion like other flags already present in PGPROC likedatabaseId or backendId, still the fact that the temporary namespace andtable created are still locked until the transaction creating thosecommits acts as a barrier for other backends.This new flag gets used by autovacuum to discard more aggressivelyorphaned tables by additionally checking for the database a backend isconnected to as well as its temporary namespace in-use, removingorphaned temporary relations even if a backend reuses the same slot asone which created temporary relations in a past session.The base idea of this patch comes from Robert Haas, has been written inits first version by Tsunakawa Takayuki, then heavily reviewed by me.Author: Tsunakawa TakayukiReviewed-by: Michael Paquier, Kyotaro Horiguchi, Andres FreundDiscussion:https://postgr.es/m/0A3221C70F24FB45833433255569204D1F8A4DC6@G01JPEXMBYT05Backpatch: 11-, as PGPROC gains a new flag and we don't want silent ABIbreakages on already released versions.
1 parent4f9a97e commit246a6c8

File tree

6 files changed

+83
-14
lines changed

6 files changed

+83
-14
lines changed

‎src/backend/access/transam/twophase.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
471471
proc->backendId=InvalidBackendId;
472472
proc->databaseId=databaseid;
473473
proc->roleId=owner;
474+
proc->tempNamespaceId=InvalidOid;
474475
proc->isBackgroundWorker= false;
475476
proc->lwWaiting= false;
476477
proc->lwWaitMode=0;

‎src/backend/catalog/namespace.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
#include"parser/parse_func.h"
4848
#include"storage/ipc.h"
4949
#include"storage/lmgr.h"
50-
#include"storage/sinval.h"
50+
#include"storage/sinvaladt.h"
5151
#include"utils/acl.h"
5252
#include"utils/builtins.h"
5353
#include"utils/catcache.h"
@@ -3204,6 +3204,46 @@ isOtherTempNamespace(Oid namespaceId)
32043204
returnisAnyTempNamespace(namespaceId);
32053205
}
32063206

3207+
/*
3208+
* isTempNamespaceInUse - is the given namespace owned and actively used
3209+
* by a backend?
3210+
*
3211+
* Note: this can be used while scanning relations in pg_class to detect
3212+
* orphaned temporary tables or namespaces with a backend connected to a
3213+
* given database. The result may be out of date quickly, so the caller
3214+
* must be careful how to handle this information.
3215+
*/
3216+
bool
3217+
isTempNamespaceInUse(OidnamespaceId)
3218+
{
3219+
PGPROC*proc;
3220+
intbackendId;
3221+
3222+
Assert(OidIsValid(MyDatabaseId));
3223+
3224+
backendId=GetTempNamespaceBackendId(namespaceId);
3225+
3226+
if (backendId==InvalidBackendId||
3227+
backendId==MyBackendId)
3228+
return false;
3229+
3230+
/* Is the backend alive? */
3231+
proc=BackendIdGetProc(backendId);
3232+
if (proc==NULL)
3233+
return false;
3234+
3235+
/* Is the backend connected to the same database we are looking at? */
3236+
if (proc->databaseId!=MyDatabaseId)
3237+
return false;
3238+
3239+
/* Does the backend own the temporary namespace? */
3240+
if (proc->tempNamespaceId!=namespaceId)
3241+
return false;
3242+
3243+
/* all good to go */
3244+
return true;
3245+
}
3246+
32073247
/*
32083248
* GetTempNamespaceBackendId - if the given namespace is a temporary-table
32093249
* namespace (either my own, or another backend's), return the BackendId
@@ -3893,6 +3933,16 @@ InitTempTableNamespace(void)
38933933
myTempNamespace=namespaceId;
38943934
myTempToastNamespace=toastspaceId;
38953935

3936+
/*
3937+
* Mark MyProc as owning this namespace which other processes can use to
3938+
* decide if a temporary namespace is in use or not. We assume that
3939+
* assignment of namespaceId is an atomic operation. Even if it is not,
3940+
* the temporary relation which resulted in the creation of this temporary
3941+
* namespace is still locked until the current transaction commits, so it
3942+
* would not be accessible yet, acting as a barrier.
3943+
*/
3944+
MyProc->tempNamespaceId=namespaceId;
3945+
38963946
/* It should not be done already. */
38973947
AssertState(myTempNamespaceSubID==InvalidSubTransactionId);
38983948
myTempNamespaceSubID=GetCurrentSubTransactionId();
@@ -3923,6 +3973,15 @@ AtEOXact_Namespace(bool isCommit, bool parallel)
39233973
myTempNamespace=InvalidOid;
39243974
myTempToastNamespace=InvalidOid;
39253975
baseSearchPathValid= false;/* need to rebuild list */
3976+
3977+
/*
3978+
* Reset the temporary namespace flag in MyProc. We assume that
3979+
* this operation is atomic. Even if it is not, the temporary
3980+
* table which created this namespace is still locked until this
3981+
* transaction aborts so it would not be visible yet, acting as a
3982+
* barrier.
3983+
*/
3984+
MyProc->tempNamespaceId=InvalidOid;
39263985
}
39273986
myTempNamespaceSubID=InvalidSubTransactionId;
39283987
}
@@ -3975,6 +4034,15 @@ AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
39754034
myTempNamespace=InvalidOid;
39764035
myTempToastNamespace=InvalidOid;
39774036
baseSearchPathValid= false;/* need to rebuild list */
4037+
4038+
/*
4039+
* Reset the temporary namespace flag in MyProc. We assume that
4040+
* this operation is atomic. Even if it is not, the temporary
4041+
* table which created this namespace is still locked until this
4042+
* transaction aborts so it would not be visible yet, acting as a
4043+
* barrier.
4044+
*/
4045+
MyProc->tempNamespaceId=InvalidOid;
39784046
}
39794047
}
39804048

‎src/backend/postmaster/autovacuum.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,14 +2080,11 @@ do_autovacuum(void)
20802080
*/
20812081
if (classForm->relpersistence==RELPERSISTENCE_TEMP)
20822082
{
2083-
intbackendID;
2084-
2085-
backendID=GetTempNamespaceBackendId(classForm->relnamespace);
2086-
2087-
/* We just ignore it if the owning backend is still active */
2088-
if (backendID!=InvalidBackendId&&
2089-
(backendID==MyBackendId||
2090-
BackendIdGetProc(backendID)==NULL))
2083+
/*
2084+
* We just ignore it if the owning backend is still active and
2085+
* using the temporary schema.
2086+
*/
2087+
if (!isTempNamespaceInUse(classForm->relnamespace))
20912088
{
20922089
/*
20932090
* The table seems to be orphaned -- although it might be that
@@ -2215,7 +2212,6 @@ do_autovacuum(void)
22152212
{
22162213
Oidrelid=lfirst_oid(cell);
22172214
Form_pg_classclassForm;
2218-
intbackendID;
22192215
ObjectAddressobject;
22202216

22212217
/*
@@ -2257,10 +2253,8 @@ do_autovacuum(void)
22572253
UnlockRelationOid(relid,AccessExclusiveLock);
22582254
continue;
22592255
}
2260-
backendID=GetTempNamespaceBackendId(classForm->relnamespace);
2261-
if (!(backendID!=InvalidBackendId&&
2262-
(backendID==MyBackendId||
2263-
BackendIdGetProc(backendID)==NULL)))
2256+
2257+
if (isTempNamespaceInUse(classForm->relnamespace))
22642258
{
22652259
UnlockRelationOid(relid,AccessExclusiveLock);
22662260
continue;

‎src/backend/storage/lmgr/proc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ InitProcess(void)
371371
MyProc->backendId=InvalidBackendId;
372372
MyProc->databaseId=InvalidOid;
373373
MyProc->roleId=InvalidOid;
374+
MyProc->tempNamespaceId=InvalidOid;
374375
MyProc->isBackgroundWorker=IsBackgroundWorker;
375376
MyPgXact->delayChkpt= false;
376377
MyPgXact->vacuumFlags=0;
@@ -552,6 +553,7 @@ InitAuxiliaryProcess(void)
552553
MyProc->backendId=InvalidBackendId;
553554
MyProc->databaseId=InvalidOid;
554555
MyProc->roleId=InvalidOid;
556+
MyProc->tempNamespaceId=InvalidOid;
555557
MyProc->isBackgroundWorker=IsBackgroundWorker;
556558
MyPgXact->delayChkpt= false;
557559
MyPgXact->vacuumFlags=0;

‎src/include/catalog/namespace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ extern bool isTempToastNamespace(Oid namespaceId);
137137
externboolisTempOrTempToastNamespace(OidnamespaceId);
138138
externboolisAnyTempNamespace(OidnamespaceId);
139139
externboolisOtherTempNamespace(OidnamespaceId);
140+
externboolisTempNamespaceInUse(OidnamespaceId);
140141
externintGetTempNamespaceBackendId(OidnamespaceId);
141142
externOidGetTempToastNamespace(void);
142143
externvoidGetTempNamespaceState(Oid*tempNamespaceId,

‎src/include/storage/proc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ struct PGPROC
114114
OiddatabaseId;/* OID of database this backend is using */
115115
OidroleId;/* OID of role using this backend */
116116

117+
OidtempNamespaceId;/* OID of temp schema this backend is
118+
* using */
119+
117120
boolisBackgroundWorker;/* true if background worker. */
118121

119122
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp