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

Commit5b965bf

Browse files
committed
Teach autovacuum how to determine whether a temp table belongs to a crashed
backend. If so, send a LOG message to the postmaster log, and if the tableis beyond the vacuum-for-wraparound horizon, forcibly drop it. Per recentdiscussions. Perhaps we ought to back-patch this, but it probably needsto age a bit in HEAD first.
1 parent92d1cc8 commit5b965bf

File tree

5 files changed

+136
-69
lines changed

5 files changed

+136
-69
lines changed

‎src/backend/catalog/namespace.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.106 2008/06/19 00:46:04 alvherre Exp $
16+
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.107 2008/07/01 02:09:34 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -2209,6 +2209,32 @@ isOtherTempNamespace(Oid namespaceId)
22092209
returnisAnyTempNamespace(namespaceId);
22102210
}
22112211

2212+
/*
2213+
* GetTempNamespaceBackendId - if the given namespace is a temporary-table
2214+
* namespace (either my own, or another backend's), return the BackendId
2215+
* that owns it. Temporary-toast-table namespaces are included, too.
2216+
* If it isn't a temp namespace, return -1.
2217+
*/
2218+
int
2219+
GetTempNamespaceBackendId(OidnamespaceId)
2220+
{
2221+
intresult;
2222+
char*nspname;
2223+
2224+
/* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
2225+
nspname=get_namespace_name(namespaceId);
2226+
if (!nspname)
2227+
return-1;/* no such namespace? */
2228+
if (strncmp(nspname,"pg_temp_",8)==0)
2229+
result=atoi(nspname+8);
2230+
elseif (strncmp(nspname,"pg_toast_temp_",14)==0)
2231+
result=atoi(nspname+14);
2232+
else
2233+
result=-1;
2234+
pfree(nspname);
2235+
returnresult;
2236+
}
2237+
22122238
/*
22132239
* GetTempToastNamespace - get the OID of my temporary-toast-table namespace,
22142240
* which must already be assigned.(This is only used when creating a toast

‎src/backend/postmaster/autovacuum.c

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
*
5656
*
5757
* IDENTIFICATION
58-
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.79 2008/06/05 15:47:32 alvherre Exp $
58+
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.80 2008/07/01 02:09:34 tgl Exp $
5959
*
6060
*-------------------------------------------------------------------------
6161
*/
@@ -71,6 +71,7 @@
7171
#include"access/heapam.h"
7272
#include"access/transam.h"
7373
#include"access/xact.h"
74+
#include"catalog/dependency.h"
7475
#include"catalog/indexing.h"
7576
#include"catalog/namespace.h"
7677
#include"catalog/pg_autovacuum.h"
@@ -90,7 +91,7 @@
9091
#include"storage/pmsignal.h"
9192
#include"storage/proc.h"
9293
#include"storage/procarray.h"
93-
#include"storage/sinval.h"
94+
#include"storage/sinvaladt.h"
9495
#include"tcop/tcopprot.h"
9596
#include"utils/flatfiles.h"
9697
#include"utils/fmgroids.h"
@@ -275,10 +276,6 @@ static void autovac_balance_cost(void);
275276
staticvoiddo_autovacuum(void);
276277
staticvoidFreeWorkerInfo(intcode,Datumarg);
277278

278-
staticvoidrelation_check_autovac(Oidrelid,Form_pg_classclassForm,
279-
Form_pg_autovacuumavForm,PgStat_StatTabEntry*tabentry,
280-
List**table_oids,List**table_toast_list,
281-
List**toast_oids);
282279
staticautovac_table*table_recheck_autovac(Oidrelid);
283280
staticvoidrelation_needs_vacanalyze(Oidrelid,Form_pg_autovacuumavForm,
284281
Form_pg_classclassForm,
@@ -1912,19 +1909,16 @@ do_autovacuum(void)
19121909
PgStat_StatTabEntry*tabentry;
19131910
HeapTupleavTup;
19141911
Oidrelid;
1912+
booldovacuum;
1913+
booldoanalyze;
1914+
boolwraparound;
1915+
intbackendID;
19151916

19161917
/* Consider only regular and toast tables. */
19171918
if (classForm->relkind!=RELKIND_RELATION&&
19181919
classForm->relkind!=RELKIND_TOASTVALUE)
19191920
continue;
19201921

1921-
/*
1922-
* Skip temp tables (i.e. those in temp namespaces). We cannot safely
1923-
* process other backends' temp tables.
1924-
*/
1925-
if (isAnyTempNamespace(classForm->relnamespace))
1926-
continue;
1927-
19281922
relid=HeapTupleGetOid(tuple);
19291923

19301924
/* Fetch the pg_autovacuum tuple for the relation, if any */
@@ -1936,8 +1930,76 @@ do_autovacuum(void)
19361930
tabentry=get_pgstat_tabentry_relid(relid,classForm->relisshared,
19371931
shared,dbentry);
19381932

1939-
relation_check_autovac(relid,classForm,avForm,tabentry,
1940-
&table_oids,&table_toast_list,&toast_oids);
1933+
/* Check if it needs vacuum or analyze */
1934+
relation_needs_vacanalyze(relid,avForm,classForm,tabentry,
1935+
&dovacuum,&doanalyze,&wraparound);
1936+
1937+
/*
1938+
* Check if it is a temp table (presumably, of some other backend's).
1939+
* We cannot safely process other backends' temp tables.
1940+
*/
1941+
backendID=GetTempNamespaceBackendId(classForm->relnamespace);
1942+
1943+
if (backendID>0)
1944+
{
1945+
/* We just ignore it if the owning backend is still active */
1946+
if (backendID==MyBackendId|| !BackendIdIsActive(backendID))
1947+
{
1948+
/*
1949+
* We found an orphan temp table (which was probably left
1950+
* behind by a crashed backend). If it's so old as to need
1951+
* vacuum for wraparound, forcibly drop it. Otherwise just
1952+
* log a complaint.
1953+
*/
1954+
if (wraparound&&classForm->relkind==RELKIND_RELATION)
1955+
{
1956+
ObjectAddressobject;
1957+
1958+
ereport(LOG,
1959+
(errmsg("autovacuum: dropping orphan temp table \"%s\".\"%s\" in database \"%s\"",
1960+
get_namespace_name(classForm->relnamespace),
1961+
NameStr(classForm->relname),
1962+
get_database_name(MyDatabaseId))));
1963+
object.classId=RelationRelationId;
1964+
object.objectId=relid;
1965+
object.objectSubId=0;
1966+
performDeletion(&object,DROP_CASCADE);
1967+
}
1968+
else
1969+
{
1970+
ereport(LOG,
1971+
(errmsg("autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"",
1972+
get_namespace_name(classForm->relnamespace),
1973+
NameStr(classForm->relname),
1974+
get_database_name(MyDatabaseId))));
1975+
}
1976+
}
1977+
}
1978+
elseif (classForm->relkind==RELKIND_RELATION)
1979+
{
1980+
/* Plain relations that need work are added to table_oids */
1981+
if (dovacuum||doanalyze)
1982+
table_oids=lappend_oid(table_oids,relid);
1983+
elseif (OidIsValid(classForm->reltoastrelid))
1984+
{
1985+
/*
1986+
* If it doesn't appear to need vacuuming, but it has a toast
1987+
* table, remember the association to revisit below.
1988+
*/
1989+
av_relation*rel=palloc(sizeof(av_relation));
1990+
1991+
rel->ar_relid=relid;
1992+
rel->ar_toastrelid=classForm->reltoastrelid;
1993+
1994+
table_toast_list=lappend(table_toast_list,rel);
1995+
}
1996+
}
1997+
else
1998+
{
1999+
/* TOAST relations that need vacuum are added to toast_oids */
2000+
if (dovacuum)
2001+
toast_oids=lappend_oid(toast_oids,relid);
2002+
}
19412003

19422004
if (HeapTupleIsValid(avTup))
19432005
heap_freetuple(avTup);
@@ -2231,56 +2293,6 @@ get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
22312293
returntabentry;
22322294
}
22332295

2234-
/*
2235-
* relation_check_autovac
2236-
*
2237-
* For a given relation (either a plain table or TOAST table), check whether it
2238-
* needs vacuum or analyze.
2239-
*
2240-
* Plain tables that need either are added to the table_list. TOAST tables
2241-
* that need vacuum are added to toast_list. Plain tables that don't need
2242-
* either but which have a TOAST table are added, as a struct, to
2243-
* table_toast_list. The latter is to allow appending the OIDs of the plain
2244-
* tables whose TOAST table needs vacuuming into the plain tables list, which
2245-
* allows us to substantially reduce the number of "rechecks" that we need to
2246-
* do later on.
2247-
*/
2248-
staticvoid
2249-
relation_check_autovac(Oidrelid,Form_pg_classclassForm,
2250-
Form_pg_autovacuumavForm,PgStat_StatTabEntry*tabentry,
2251-
List**table_oids,List**table_toast_list,
2252-
List**toast_oids)
2253-
{
2254-
booldovacuum;
2255-
booldoanalyze;
2256-
booldummy;
2257-
2258-
relation_needs_vacanalyze(relid,avForm,classForm,tabentry,
2259-
&dovacuum,&doanalyze,&dummy);
2260-
2261-
if (classForm->relkind==RELKIND_TOASTVALUE)
2262-
{
2263-
if (dovacuum)
2264-
*toast_oids=lappend_oid(*toast_oids,relid);
2265-
}
2266-
else
2267-
{
2268-
Assert(classForm->relkind==RELKIND_RELATION);
2269-
2270-
if (dovacuum||doanalyze)
2271-
*table_oids=lappend_oid(*table_oids,relid);
2272-
elseif (OidIsValid(classForm->reltoastrelid))
2273-
{
2274-
av_relation*rel=palloc(sizeof(av_relation));
2275-
2276-
rel->ar_relid=relid;
2277-
rel->ar_toastrelid=classForm->reltoastrelid;
2278-
2279-
*table_toast_list=lappend(*table_toast_list,rel);
2280-
}
2281-
}
2282-
}
2283-
22842296
/*
22852297
* table_recheck_autovac
22862298
*

‎src/backend/storage/ipc/sinvaladt.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.72 2008/06/20 00:24:53 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.73 2008/07/01 02:09:34 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -357,6 +357,33 @@ CleanupInvalidationState(int status, Datum arg)
357357
LWLockRelease(SInvalWriteLock);
358358
}
359359

360+
/*
361+
* BackendIdIsActive
362+
*Test if the given backend ID is currently assigned to a process.
363+
*/
364+
bool
365+
BackendIdIsActive(intbackendID)
366+
{
367+
boolresult;
368+
SISeg*segP=shmInvalBuffer;
369+
370+
/* Need to lock out additions/removals of backends */
371+
LWLockAcquire(SInvalWriteLock,LW_SHARED);
372+
373+
if (backendID>0&&backendID <=segP->lastBackend)
374+
{
375+
ProcState*stateP=&segP->procState[backendID-1];
376+
377+
result= (stateP->procPid!=0);
378+
}
379+
else
380+
result= false;
381+
382+
LWLockRelease(SInvalWriteLock);
383+
384+
returnresult;
385+
}
386+
360387
/*
361388
* SIInsertDataEntries
362389
*Add new invalidation message(s) to the buffer.

‎src/include/catalog/namespace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.53 2008/01/0119:45:56 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.54 2008/07/0102:09:34 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -95,6 +95,7 @@ extern bool isTempToastNamespace(Oid namespaceId);
9595
externboolisTempOrToastNamespace(OidnamespaceId);
9696
externboolisAnyTempNamespace(OidnamespaceId);
9797
externboolisOtherTempNamespace(OidnamespaceId);
98+
externintGetTempNamespaceBackendId(OidnamespaceId);
9899
externOidGetTempToastNamespace(void);
99100
externvoidResetTempTableNamespace(void);
100101

‎src/include/storage/sinvaladt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
1616
* Portions Copyright (c) 1994, Regents of the University of California
1717
*
18-
* $PostgreSQL: pgsql/src/include/storage/sinvaladt.h,v 1.48 2008/06/19 21:32:56 tgl Exp $
18+
* $PostgreSQL: pgsql/src/include/storage/sinvaladt.h,v 1.49 2008/07/01 02:09:34 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -30,6 +30,7 @@
3030
externSizeSInvalShmemSize(void);
3131
externvoidCreateSharedInvalidationState(void);
3232
externvoidSharedInvalBackendInit(void);
33+
externboolBackendIdIsActive(intbackendID);
3334

3435
externvoidSIInsertDataEntries(constSharedInvalidationMessage*data,intn);
3536
externintSIGetDataEntries(SharedInvalidationMessage*data,intdatasize);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp