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

Commitfe455ee

Browse files
committed
Revise ResourceOwner code to avoid accumulating ResourceOwner objects
for every command executed within a transaction. For long transactionsthis was a significant memory leak. Instead, we can delete a portal'sor subtransaction's ResourceOwner immediately, if we physically transferthe information about its locks up to the parent owner. This does notfully solve the leak problem; we need to do something about countingmultiple acquisitions of the same lock in order to fix it. But it's anecessary step along the way.
1 parentb662311 commitfe455ee

File tree

4 files changed

+72
-30
lines changed

4 files changed

+72
-30
lines changed

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

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.178 2004/08/11 04:07:15 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.179 2004/08/25 18:43:42 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1716,11 +1716,16 @@ CommitTransactionCommand(void)
17161716
/*
17171717
* We were issued a RELEASE command, so we end the current
17181718
* subtransaction and return to the parent transaction.
1719+
*
1720+
* Since RELEASE can exit multiple levels of subtransaction,
1721+
* we must loop here until we get out of all SUBEND'ed levels.
17191722
*/
17201723
caseTBLOCK_SUBEND:
1721-
CommitSubTransaction();
1722-
PopTransaction();
1723-
s=CurrentTransactionState;/* changed by pop */
1724+
do {
1725+
CommitSubTransaction();
1726+
PopTransaction();
1727+
s=CurrentTransactionState;/* changed by pop */
1728+
}while (s->blockState==TBLOCK_SUBEND);
17241729
break;
17251730

17261731
/*
@@ -2411,9 +2416,10 @@ void
24112416
ReleaseSavepoint(List*options)
24122417
{
24132418
TransactionStates=CurrentTransactionState;
2414-
TransactionStatetarget=s;
2415-
char*name=NULL;
2419+
TransactionStatetarget,
2420+
xact;
24162421
ListCell*cell;
2422+
char*name=NULL;
24172423

24182424
/*
24192425
* Check valid block state transaction status.
@@ -2462,19 +2468,38 @@ ReleaseSavepoint(List *options)
24622468

24632469
Assert(PointerIsValid(name));
24642470

2465-
while (target!=NULL)
2471+
for (target=s;PointerIsValid(target);target=target->parent)
24662472
{
24672473
if (PointerIsValid(target->name)&&strcmp(target->name,name)==0)
24682474
break;
2469-
target=target->parent;
24702475
}
24712476

24722477
if (!PointerIsValid(target))
24732478
ereport(ERROR,
24742479
(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
24752480
errmsg("no such savepoint")));
24762481

2477-
CommitTransactionToLevel(target->nestingLevel);
2482+
/* disallow crossing savepoint level boundaries */
2483+
if (target->savepointLevel!=s->savepointLevel)
2484+
ereport(ERROR,
2485+
(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
2486+
errmsg("no such savepoint")));
2487+
2488+
/*
2489+
* Mark "commit pending" all subtransactions up to the target
2490+
* subtransaction. The actual commits will happen when control
2491+
* gets to CommitTransactionCommand.
2492+
*/
2493+
xact=CurrentTransactionState;
2494+
for (;;)
2495+
{
2496+
Assert(xact->blockState==TBLOCK_SUBINPROGRESS);
2497+
xact->blockState=TBLOCK_SUBEND;
2498+
if (xact==target)
2499+
break;
2500+
xact=xact->parent;
2501+
Assert(PointerIsValid(xact));
2502+
}
24782503
}
24792504

24802505
/*
@@ -2969,18 +2994,13 @@ CommitSubTransaction(void)
29692994

29702995
CallXactCallbacks(XACT_EVENT_COMMIT_SUB,s->parent->transactionIdData);
29712996

2972-
/*
2973-
* Note that we just release the resource owner's resources and don't
2974-
* delete it. This is because locks are not actually released here.
2975-
* The owner object continues to exist as a child of its parent owner
2976-
* (namely my parent transaction's resource owner), and the locks
2977-
* effectively become that owner object's responsibility.
2978-
*/
29792997
ResourceOwnerRelease(s->curTransactionOwner,
29802998
RESOURCE_RELEASE_BEFORE_LOCKS,
29812999
true, false);
29823000
AtEOSubXact_Inval(true);
2983-
/* we can skip the LOCKS phase */
3001+
ResourceOwnerRelease(s->curTransactionOwner,
3002+
RESOURCE_RELEASE_LOCKS,
3003+
true, false);
29843004
ResourceOwnerRelease(s->curTransactionOwner,
29853005
RESOURCE_RELEASE_AFTER_LOCKS,
29863006
true, false);
@@ -3003,6 +3023,7 @@ CommitSubTransaction(void)
30033023

30043024
CurrentResourceOwner=s->parent->curTransactionOwner;
30053025
CurTransactionResourceOwner=s->parent->curTransactionOwner;
3026+
ResourceOwnerDelete(s->curTransactionOwner);
30063027
s->curTransactionOwner=NULL;
30073028

30083029
AtSubCommit_Memory();

‎src/backend/utils/mmgr/portalmem.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.68 2004/08/02 21:42:18 tgl Exp $
15+
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.69 2004/08/25 18:43:43 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -354,8 +354,7 @@ PortalDrop(Portal portal, bool isTopCommit)
354354
ResourceOwnerRelease(portal->resowner,
355355
RESOURCE_RELEASE_AFTER_LOCKS,
356356
isCommit, false);
357-
if (!isCommit)
358-
ResourceOwnerDelete(portal->resowner);
357+
ResourceOwnerDelete(portal->resowner);
359358
}
360359
portal->resowner=NULL;
361360

‎src/backend/utils/resowner/README

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$PostgreSQL: pgsql/src/backend/utils/resowner/README,v 1.2 2004/07/31 00:45:40 tgl Exp $
1+
$PostgreSQL: pgsql/src/backend/utils/resowner/README,v 1.3 2004/08/25 18:43:43 tgl Exp $
22

33
Notes about resource owners
44
---------------------------
@@ -30,8 +30,9 @@ ownership of the acquired resources in that ResourceOwner object.
3030
When a Portal is closed, any remaining resources (typically only locks)
3131
become the responsibility of the current transaction. This is represented
3232
by making the Portal's ResourceOwner a child of the current transaction's
33-
ResourceOwner. Similarly, subtransaction ResourceOwners are children of
34-
their immediate parent.
33+
ResourceOwner. resowner.c automatically transfers the resources to the
34+
parent object when releasing the child. Similarly, subtransaction
35+
ResourceOwners are children of their immediate parent.
3536

3637
We need transaction-related ResourceOwners as well as Portal-related ones
3738
because transactions may initiate operations that require resources (such
@@ -53,6 +54,12 @@ The basic operations on a ResourceOwner are:
5354
* delete a ResourceOwner (including child owner objects); all resources
5455
must have been released beforehand
5556

57+
Locks are handled specially because in non-error situations a lock should
58+
be held until end of transaction, even if it was originally taken by a
59+
subtransaction or portal. Therefore, the "release" operation on a child
60+
ResourceOwner transfers lock ownership to the parent instead of actually
61+
releasing the lock, if isCommit is true.
62+
5663
Currently, ResourceOwners contain direct support for recording ownership
5764
of buffer pins, lmgr locks, and catcache and relcache references. Other
5865
objects can be associated with a ResourceOwner by recording the address of

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

Lines changed: 22 additions & 7 deletions
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.2 2004/07/31 00:45:40 tgl Exp $
17+
* $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.3 2004/08/25 18:43:43 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -277,25 +277,40 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
277277
/* Mark object as holding no locks, just for sanity */
278278
owner->nlocks=0;
279279
}
280-
elseif (!isCommit)
280+
else
281281
{
282282
/*
283283
* Release locks retail. Note that LockRelease will remove
284284
* the lock entry from my list, so I just have to iterate till
285285
* there are none. Also note that if we are committing a
286-
* subtransaction, we do NOT release its locks yet.
286+
* subtransaction, we do NOT release its locks yet, but transfer
287+
* them to the parent.
287288
*
288289
* XXX as above, this is a bit inefficient but probably not worth
289290
* the trouble to optimize more.
290291
*/
292+
Assert(owner->parent!=NULL);
291293
while (owner->nlocks>0)
292294
{
293295
LockIdData*lockid=&owner->locks[owner->nlocks-1];
294296

295-
LockRelease(lockid->locktag.lockmethodid,
296-
&lockid->locktag,
297-
lockid->xid,
298-
lockid->lockmode);
297+
if (isCommit)
298+
{
299+
ResourceOwnerEnlargeLocks(owner->parent);
300+
ResourceOwnerRememberLock(owner->parent,
301+
&lockid->locktag,
302+
lockid->xid,
303+
lockid->lockmode);
304+
owner->nlocks--;
305+
}
306+
else
307+
{
308+
LockRelease(lockid->locktag.lockmethodid,
309+
&lockid->locktag,
310+
lockid->xid,
311+
lockid->lockmode);
312+
/* LockRelease will have removed the entry from list */
313+
}
299314
}
300315
}
301316
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp