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

Commitb41f4ab

Browse files
committed
Use a private memory context to store rule information in each relcache
entry that has rules. This allows us to release the rule parsetreeson relcache flush without needing a working freeObject() routine.Formerly, the rule trees were leaked permanently at relcache flush.Also, clean up handling of rule creation and deletion --- there wasnot sufficient locking of the relation being modified, and there wasno reliable notification of other backends that a relcache reloadwas needed. Also, clean up relcache.c code so that scans of systemtables needed to load a relcache entry are done in the caller'smemory context, not in CacheMemoryContext. This prevents anyun-pfreed memory from those scans from becoming a permanent memoryleak.
1 parentc9ec78a commitb41f4ab

File tree

10 files changed

+345
-516
lines changed

10 files changed

+345
-516
lines changed

‎src/backend/catalog/index.c

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.120 2000/06/28 03:31:23 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.121 2000/06/30 07:04:17 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -369,16 +369,21 @@ ConstructTupleDescriptor(Oid heapoid,
369369

370370
/* ----------------------------------------------------------------
371371
* AccessMethodObjectIdGetForm
372-
*Returns the formated access method tuple given its object identifier.
372+
*Returns an access method tuple given its object identifier,
373+
*or NULL if no such AM tuple can be found.
373374
*
374-
* XXX ADD INDEXING
375+
* Scanning is done using CurrentMemoryContext as working storage,
376+
* but the returned tuple will be allocated in resultCxt (which is
377+
* typically CacheMemoryContext).
375378
*
376-
* Note:
377-
*Assumes object identifier is valid.
379+
* There was a note here about adding indexing, but I don't see a need
380+
* for it. There are so few tuples in pg_am that an indexscan would
381+
* surely be slower.
378382
* ----------------------------------------------------------------
379383
*/
380384
Form_pg_am
381-
AccessMethodObjectIdGetForm(OidaccessMethodObjectId)
385+
AccessMethodObjectIdGetForm(OidaccessMethodObjectId,
386+
MemoryContextresultCxt)
382387
{
383388
Relationpg_am_desc;
384389
HeapScanDescpg_am_scan;
@@ -415,10 +420,10 @@ AccessMethodObjectIdGetForm(Oid accessMethodObjectId)
415420
}
416421

417422
/* ----------------
418-
*if foundam tuple, then copythe form and return the copy
423+
*if foundAM tuple, then copyit into resultCxt and return the copy
419424
* ----------------
420425
*/
421-
aform= (Form_pg_am)palloc(sizeof*aform);
426+
aform= (Form_pg_am)MemoryContextAlloc(resultCxt,sizeof*aform);
422427
memcpy(aform,GETSTRUCT(pg_am_tuple),sizeof*aform);
423428

424429
heap_endscan(pg_am_scan);
@@ -434,22 +439,8 @@ AccessMethodObjectIdGetForm(Oid accessMethodObjectId)
434439
staticvoid
435440
ConstructIndexReldesc(RelationindexRelation,Oidamoid)
436441
{
437-
MemoryContextoldcxt;
438-
439-
/* ----------------
440-
* here we make certain to allocate the access method
441-
* tuple within the cache context lest it vanish when the
442-
* context changes
443-
* ----------------
444-
*/
445-
if (!CacheMemoryContext)
446-
CreateCacheMemoryContext();
447-
448-
oldcxt=MemoryContextSwitchTo(CacheMemoryContext);
449-
450-
indexRelation->rd_am=AccessMethodObjectIdGetForm(amoid);
451-
452-
MemoryContextSwitchTo(oldcxt);
442+
indexRelation->rd_am=AccessMethodObjectIdGetForm(amoid,
443+
CacheMemoryContext);
453444

454445
/* ----------------
455446
* XXX missing the initialization of some other fields

‎src/backend/commands/trigger.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.70 2000/06/28 03:31:28 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.71 2000/06/30 07:04:17 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -431,10 +431,17 @@ RelationRemoveTriggers(Relation rel)
431431
heap_close(tgrel,RowExclusiveLock);
432432
}
433433

434+
/*
435+
* Build trigger data to attach to the given relcache entry.
436+
*
437+
* Note that trigger data must be allocated in CacheMemoryContext
438+
* to ensure it survives as long as the relcache entry. But we
439+
* are probably running in a less long-lived working context.
440+
*/
434441
void
435442
RelationBuildTriggers(Relationrelation)
436443
{
437-
TriggerDesc*trigdesc= (TriggerDesc*)palloc(sizeof(TriggerDesc));
444+
TriggerDesc*trigdesc;
438445
intntrigs=relation->rd_rel->reltriggers;
439446
Trigger*triggers=NULL;
440447
Trigger*build;
@@ -453,6 +460,8 @@ RelationBuildTriggers(Relation relation)
453460
intfound;
454461
boolhasindex;
455462

463+
trigdesc= (TriggerDesc*)MemoryContextAlloc(CacheMemoryContext,
464+
sizeof(TriggerDesc));
456465
MemSet(trigdesc,0,sizeof(TriggerDesc));
457466

458467
ScanKeyEntryInitialize(&skey,
@@ -499,13 +508,16 @@ RelationBuildTriggers(Relation relation)
499508
pg_trigger= (Form_pg_trigger)GETSTRUCT(htup);
500509

501510
if (triggers==NULL)
502-
triggers= (Trigger*)palloc(sizeof(Trigger));
511+
triggers= (Trigger*)MemoryContextAlloc(CacheMemoryContext,
512+
sizeof(Trigger));
503513
else
504-
triggers= (Trigger*)repalloc(triggers, (found+1)*sizeof(Trigger));
514+
triggers= (Trigger*)repalloc(triggers,
515+
(found+1)*sizeof(Trigger));
505516
build=&(triggers[found]);
506517

507518
build->tgoid=htup->t_data->t_oid;
508-
build->tgname=nameout(&pg_trigger->tgname);
519+
build->tgname=MemoryContextStrdup(CacheMemoryContext,
520+
nameout(&pg_trigger->tgname));
509521
build->tgfoid=pg_trigger->tgfoid;
510522
build->tgfunc.fn_oid=InvalidOid;/* mark FmgrInfo as uninitialized */
511523
build->tgtype=pg_trigger->tgtype;
@@ -514,7 +526,8 @@ RelationBuildTriggers(Relation relation)
514526
build->tgdeferrable=pg_trigger->tgdeferrable;
515527
build->tginitdeferred=pg_trigger->tginitdeferred;
516528
build->tgnargs=pg_trigger->tgnargs;
517-
memcpy(build->tgattr,&(pg_trigger->tgattr),FUNC_MAX_ARGS*sizeof(int16));
529+
memcpy(build->tgattr,&(pg_trigger->tgattr),
530+
FUNC_MAX_ARGS*sizeof(int16));
518531
val= (structvarlena*)fastgetattr(htup,
519532
Anum_pg_trigger_tgargs,
520533
tgrel->rd_att,&isnull);
@@ -533,10 +546,13 @@ RelationBuildTriggers(Relation relation)
533546
elog(ERROR,"RelationBuildTriggers: tgargs IS NULL for rel %s",
534547
RelationGetRelationName(relation));
535548
p= (char*)VARDATA(val);
536-
build->tgargs= (char**)palloc(build->tgnargs*sizeof(char*));
549+
build->tgargs= (char**)
550+
MemoryContextAlloc(CacheMemoryContext,
551+
build->tgnargs*sizeof(char*));
537552
for (i=0;i<build->tgnargs;i++)
538553
{
539-
build->tgargs[i]=pstrdup(p);
554+
build->tgargs[i]=MemoryContextStrdup(CacheMemoryContext,
555+
p);
540556
p+=strlen(p)+1;
541557
}
542558
}
@@ -611,7 +627,8 @@ DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger)
611627
{
612628
tp=&(t[TRIGGER_EVENT_INSERT]);
613629
if (*tp==NULL)
614-
*tp= (Trigger**)palloc(sizeof(Trigger*));
630+
*tp= (Trigger**)MemoryContextAlloc(CacheMemoryContext,
631+
sizeof(Trigger*));
615632
else
616633
*tp= (Trigger**)repalloc(*tp, (n[TRIGGER_EVENT_INSERT]+1)*
617634
sizeof(Trigger*));
@@ -623,7 +640,8 @@ DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger)
623640
{
624641
tp=&(t[TRIGGER_EVENT_DELETE]);
625642
if (*tp==NULL)
626-
*tp= (Trigger**)palloc(sizeof(Trigger*));
643+
*tp= (Trigger**)MemoryContextAlloc(CacheMemoryContext,
644+
sizeof(Trigger*));
627645
else
628646
*tp= (Trigger**)repalloc(*tp, (n[TRIGGER_EVENT_DELETE]+1)*
629647
sizeof(Trigger*));
@@ -635,7 +653,8 @@ DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger)
635653
{
636654
tp=&(t[TRIGGER_EVENT_UPDATE]);
637655
if (*tp==NULL)
638-
*tp= (Trigger**)palloc(sizeof(Trigger*));
656+
*tp= (Trigger**)MemoryContextAlloc(CacheMemoryContext,
657+
sizeof(Trigger*));
639658
else
640659
*tp= (Trigger**)repalloc(*tp, (n[TRIGGER_EVENT_UPDATE]+1)*
641660
sizeof(Trigger*));
@@ -1023,10 +1042,9 @@ ltrmark:;
10231042

10241043
/* ----------
10251044
* Internal data to the deferred trigger mechanism is held
1026-
* during entire session in a global memor created at startup and
1027-
* over statements/commands in a separate global memory which
1028-
* is created at transaction start and destroyed at transaction
1029-
* end.
1045+
* during entire session in a global context created at startup and
1046+
* over statements/commands in a separate context which
1047+
* is created at transaction start and destroyed at transaction end.
10301048
* ----------
10311049
*/
10321050
staticMemoryContextdeftrig_gcxt=NULL;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp