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

Commit6bbef4e

Browse files
committed
Use ResourceOwners in the snapshot manager, instead of attempting to track them
by hand. As an added bonus, the new code is smaller and more understandable,and the ugly loops are gone.This had been discussed all along but never implemented. It became clear thatit really needed to be fixed after a bug report by Pavan Deolasee.
1 parent1304f29 commit6bbef4e

File tree

4 files changed

+156
-184
lines changed

4 files changed

+156
-184
lines changed

‎src/backend/utils/resowner/README

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$PostgreSQL: pgsql/src/backend/utils/resowner/README,v 1.7 2008/03/21 13:23:28 momjian Exp $
1+
$PostgreSQL: pgsql/src/backend/utils/resowner/README,v 1.8 2008/11/25 20:28:29 alvherre Exp $
22

33
Notes About Resource Owners
44
===========================
@@ -61,11 +61,11 @@ ResourceOwner transfers lock ownership to the parent instead of actually
6161
releasing the lock, if isCommit is true.
6262

6363
Currently, ResourceOwners contain direct support for recording ownership of
64-
buffer pins, lmgr locks, and catcache, relcache, plancache,andtupdesc
65-
references. Other objects can be associated with a ResourceOwner by recording
66-
the address of the owning ResourceOwner in such an object. There is an API
67-
for other modules to get control during ResourceOwner release, so that they
68-
can scan their own data structures to find the objects that need to be
64+
buffer pins, lmgr locks, and catcache, relcache, plancache, tupdesc, and
65+
snapshotreferences. Other objects can be associated with a ResourceOwner by
66+
recordingthe address of the owning ResourceOwner in such an object. There is
67+
an APIfor other modules to get control during ResourceOwner release, so that
68+
theycan scan their own data structures to find the objects that need to be
6969
deleted.
7070

7171
Whenever we are inside a transaction, the global variable

‎src/backend/utils/resowner/resowner.c

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.29 2008/06/19 00:46:05 alvherre Exp $
17+
* $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.30 2008/11/25 20:28:29 alvherre Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -26,6 +26,7 @@
2626
#include"utils/memutils.h"
2727
#include"utils/rel.h"
2828
#include"utils/resowner.h"
29+
#include"utils/snapmgr.h"
2930

3031

3132
/*
@@ -66,6 +67,11 @@ typedef struct ResourceOwnerData
6667
intntupdescs;/* number of owned tupdesc references */
6768
TupleDesc*tupdescs;/* dynamically allocated array */
6869
intmaxtupdescs;/* currently allocated array size */
70+
71+
/* We have built-in support for remembering snapshot references */
72+
intnsnapshots;/* number of owned snapshot references */
73+
Snapshot*snapshots;/* dynamically allocated array */
74+
intmaxsnapshots;/* currently allocated array size */
6975
}ResourceOwnerData;
7076

7177

@@ -98,6 +104,7 @@ static void ResourceOwnerReleaseInternal(ResourceOwner owner,
98104
staticvoidPrintRelCacheLeakWarning(Relationrel);
99105
staticvoidPrintPlanCacheLeakWarning(CachedPlan*plan);
100106
staticvoidPrintTupleDescLeakWarning(TupleDesctupdesc);
107+
staticvoidPrintSnapshotLeakWarning(Snapshotsnapshot);
101108

102109

103110
/*****************************************************************************
@@ -301,6 +308,13 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
301308
PrintTupleDescLeakWarning(owner->tupdescs[owner->ntupdescs-1]);
302309
DecrTupleDescRefCount(owner->tupdescs[owner->ntupdescs-1]);
303310
}
311+
/* Ditto for snapshot references */
312+
while (owner->nsnapshots>0)
313+
{
314+
if (isCommit)
315+
PrintSnapshotLeakWarning(owner->snapshots[owner->nsnapshots-1]);
316+
UnregisterSnapshot(owner->snapshots[owner->nsnapshots-1]);
317+
}
304318

305319
/* Clean up index scans too */
306320
ReleaseResources_hash();
@@ -332,6 +346,7 @@ ResourceOwnerDelete(ResourceOwner owner)
332346
Assert(owner->nrelrefs==0);
333347
Assert(owner->nplanrefs==0);
334348
Assert(owner->ntupdescs==0);
349+
Assert(owner->nsnapshots==0);
335350

336351
/*
337352
* Delete children. The recursive call will delink the child from me, so
@@ -360,6 +375,8 @@ ResourceOwnerDelete(ResourceOwner owner)
360375
pfree(owner->planrefs);
361376
if (owner->tupdescs)
362377
pfree(owner->tupdescs);
378+
if (owner->snapshots)
379+
pfree(owner->snapshots);
363380

364381
pfree(owner);
365382
}
@@ -936,3 +953,85 @@ PrintTupleDescLeakWarning(TupleDesc tupdesc)
936953
"TupleDesc reference leak: TupleDesc %p (%u,%d) still referenced",
937954
tupdesc,tupdesc->tdtypeid,tupdesc->tdtypmod);
938955
}
956+
957+
/*
958+
* Make sure there is room for at least one more entry in a ResourceOwner's
959+
* snapshot reference array.
960+
*
961+
* This is separate from actually inserting an entry because if we run out
962+
* of memory, it's critical to do so *before* acquiring the resource.
963+
*/
964+
void
965+
ResourceOwnerEnlargeSnapshots(ResourceOwnerowner)
966+
{
967+
intnewmax;
968+
969+
if (owner->nsnapshots<owner->maxsnapshots)
970+
return;/* nothing to do */
971+
972+
if (owner->snapshots==NULL)
973+
{
974+
newmax=16;
975+
owner->snapshots= (Snapshot*)
976+
MemoryContextAlloc(TopMemoryContext,newmax*sizeof(Snapshot));
977+
owner->maxsnapshots=newmax;
978+
}
979+
else
980+
{
981+
newmax=owner->maxsnapshots*2;
982+
owner->snapshots= (Snapshot*)
983+
repalloc(owner->snapshots,newmax*sizeof(Snapshot));
984+
owner->maxsnapshots=newmax;
985+
}
986+
}
987+
988+
/*
989+
* Remember that a snapshot reference is owned by a ResourceOwner
990+
*
991+
* Caller must have previously done ResourceOwnerEnlargeSnapshots()
992+
*/
993+
void
994+
ResourceOwnerRememberSnapshot(ResourceOwnerowner,Snapshotsnapshot)
995+
{
996+
Assert(owner->nsnapshots<owner->maxsnapshots);
997+
owner->snapshots[owner->nsnapshots]=snapshot;
998+
owner->nsnapshots++;
999+
}
1000+
1001+
/*
1002+
* Forget that a snapshot reference is owned by a ResourceOwner
1003+
*/
1004+
void
1005+
ResourceOwnerForgetSnapshot(ResourceOwnerowner,Snapshotsnapshot)
1006+
{
1007+
Snapshot*snapshots=owner->snapshots;
1008+
intns1=owner->nsnapshots-1;
1009+
inti;
1010+
1011+
for (i=ns1;i >=0;i--)
1012+
{
1013+
if (snapshots[i]==snapshot)
1014+
{
1015+
while (i<ns1)
1016+
{
1017+
snapshots[i]=snapshots[i+1];
1018+
i++;
1019+
}
1020+
owner->nsnapshots=ns1;
1021+
return;
1022+
}
1023+
}
1024+
elog(ERROR,"snapshot reference %p is not owned by resource owner %s",
1025+
snapshot,owner->name);
1026+
}
1027+
1028+
/*
1029+
* Debugging subroutine
1030+
*/
1031+
staticvoid
1032+
PrintSnapshotLeakWarning(Snapshotsnapshot)
1033+
{
1034+
elog(WARNING,
1035+
"Snapshot reference leak: Snapshot %p still referenced",
1036+
snapshot);
1037+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp