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

Commit163ab48

Browse files
committed
Added tempbuffers patch. by A Lubennicova. Resolved conflict with PTRACK. See PGPRO-82
1 parent9b79234 commit163ab48

File tree

12 files changed

+318
-8
lines changed

12 files changed

+318
-8
lines changed

‎src/backend/catalog/namespace.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include"utils/lsyscache.h"
5757
#include"utils/memutils.h"
5858
#include"utils/syscache.h"
59+
#include"storage/bufmgr.h"
5960

6061

6162
/*
@@ -3879,6 +3880,7 @@ RemoveTempRelations(Oid tempNamespaceId)
38793880
object.objectId=tempNamespaceId;
38803881
object.objectSubId=0;
38813882

3883+
drop_temptableinfo_hashtable();
38823884
deleteWhatDependsOn(&object, false);
38833885
}
38843886

‎src/backend/catalog/storage.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ RelationDropStorage(Relation rel)
156156
pending->next=pendingDeletes;
157157
pendingDeletes=pending;
158158

159+
/* Delete cache entry from tempTableHashTab for this rel */
160+
if (rel->rd_rel->relkind==RELKIND_RELATION
161+
&&rel->rd_rel->relpersistence==RELPERSISTENCE_TEMP)
162+
delete_temptableinfo_from_hashtable(rel->rd_node);
159163
/*
160164
* NOTE: if the relation was created in this transaction, it will now be
161165
* present in the pending-delete list twice, once with atCommit true and
@@ -239,6 +243,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
239243
rel->rd_smgr->smgr_fsm_nblocks=InvalidBlockNumber;
240244
rel->rd_smgr->smgr_vm_nblocks=InvalidBlockNumber;
241245
rel->rd_smgr->smgr_ptrack_nblocks=InvalidBlockNumber;
246+
rel->rd_smgr->smgr_main_nblocks=InvalidBlockNumber;
242247

243248
/* Truncate the FSM first if it exists */
244249
fsm=smgrexists(rel->rd_smgr,FSM_FORKNUM);
@@ -250,6 +255,16 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
250255
if (vm)
251256
visibilitymap_truncate(rel,nblocks);
252257

258+
/*
259+
* Update cached number of blocks of temp relation,
260+
* but don't delete the entry from tempTableHashTab
261+
*/
262+
if (rel->rd_rel->relpersistence==RELPERSISTENCE_TEMP
263+
&&rel->rd_rel->relkind==RELKIND_RELATION)
264+
{
265+
insert_temptableinfo_hashtable(rel->rd_node,0);
266+
}
267+
253268
/*
254269
* We WAL-log the truncation before actually truncating, which means
255270
* trouble if the truncation fails. If we then crash, the WAL replay

‎src/backend/commands/cluster.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,18 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
10801080
/* Write out any remaining tuples, and fsync if needed */
10811081
end_heap_rewrite(rwstate);
10821082

1083+
/*
1084+
* Create new entry for temptable to track number of blocks
1085+
* in the new relation
1086+
*/
1087+
if (NewHeap->rd_rel->relpersistence==RELPERSISTENCE_TEMP
1088+
&&NewHeap->rd_rel->relkind==RELKIND_RELATION)
1089+
{
1090+
RelationOpenSmgr(NewHeap);
1091+
insert_temptableinfo_hashtable(NewHeap->rd_node,
1092+
smgrnblocks(NewHeap->rd_smgr,MAIN_FORKNUM));
1093+
}
1094+
10831095
/* Reset rd_toastoid just to be tidy --- it shouldn't be looked at again */
10841096
NewHeap->rd_toastoid=InvalidOid;
10851097

@@ -1578,7 +1590,6 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
15781590
* depends on it, so DROP_RESTRICT should be OK.
15791591
*/
15801592
performDeletion(&object,DROP_RESTRICT,PERFORM_DELETION_INTERNAL);
1581-
15821593
/* performDeletion does CommandCounterIncrement at end */
15831594

15841595
/*

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 198 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ ForgetPrivateRefCountEntry(PrivateRefCountEntry *ref)
428428
)
429429

430430

431-
staticBufferReadBuffer_common(SMgrRelationreln,charrelpersistence,
431+
staticBufferReadBuffer_common(SMgrRelationreln,charrelpersistence,charrelkind,
432432
ForkNumberforkNum,BlockNumberblockNum,
433433
ReadBufferModemode,BufferAccessStrategystrategy,
434434
bool*hit);
@@ -458,6 +458,95 @@ static intbuffertag_comparator(const void *p1, const void *p2);
458458
staticintckpt_buforder_comparator(constvoid*pa,constvoid*pb);
459459
staticintts_ckpt_progress_comparator(Datuma,Datumb,void*arg);
460460

461+
/* ----------------------------
462+
* TODO Replace it somewhere. BEGIN.
463+
* ----------------------------
464+
*/
465+
466+
typedefstructTempTableInfoData
467+
{
468+
RelFileNodernode;/* relfilenode of this temp table (hash key) */
469+
BlockNumbermain_nblocks;/* number of blocks in the rel */
470+
}TempTableInfoData;
471+
472+
typedefTempTableInfoData*TempTableInfo;
473+
474+
staticHTAB*tempTableHashTab=NULL;/* hash table for tracking temp table's length */
475+
476+
/*
477+
* Creates the hash table for storing the actual length of temp tables
478+
*/
479+
staticvoid
480+
create_temptableinfo_hashtable(void)
481+
{
482+
HASHCTLctl;
483+
484+
memset(&ctl,0,sizeof(ctl));
485+
ctl.keysize=sizeof(RelFileNode);
486+
ctl.entrysize=sizeof(TempTableInfoData);
487+
488+
tempTableHashTab=hash_create("Temp table's lengts",16,&ctl,
489+
HASH_ELEM |HASH_BLOBS);
490+
}
491+
492+
void
493+
drop_temptableinfo_hashtable(void)
494+
{
495+
if (tempTableHashTab)
496+
{
497+
hash_destroy(tempTableHashTab);
498+
tempTableHashTab=NULL;
499+
}
500+
}
501+
502+
void
503+
delete_temptableinfo_from_hashtable(RelFileNodernode)
504+
{
505+
elog(DEBUG1,"delete entry from tempTableHashTab");
506+
507+
if (tempTableHashTab==NULL)
508+
return;
509+
510+
if (hash_search(tempTableHashTab,
511+
(void*)&rnode,
512+
HASH_REMOVE,NULL)==NULL)
513+
elog(DEBUG1,"tempTableHashTab has no entry to delete");
514+
}
515+
516+
void
517+
insert_temptableinfo_hashtable(RelFileNodernode,BlockNumbernblocks)
518+
{
519+
TempTableInfotti;
520+
boolttiIsFound;
521+
elog(DEBUG1,"insert entry to tempTableHashTab, nblocks %u",nblocks);
522+
elog(DEBUG1,"insert entry. spcNode %u, dbNode %u, relNode %u",rnode.spcNode,rnode.dbNode,rnode.relNode);
523+
524+
/* hash table must already exist, when we are rewriting temp rel */
525+
if (tempTableHashTab==NULL)
526+
{
527+
//TODO add some check here.
528+
return;
529+
}
530+
/* Create a hash table entry for this temp table */
531+
tti= (TempTableInfo)hash_search(tempTableHashTab,&rnode,
532+
HASH_ENTER,&ttiIsFound);
533+
534+
if (!ttiIsFound)
535+
{
536+
elog(DEBUG1,"tempTableHashTab entry is not found");
537+
}
538+
else
539+
{
540+
elog(DEBUG1,"tempTableHashTab entry is found. main_nblocks %u, nblocks %u",tti->main_nblocks,nblocks);
541+
}
542+
tti->main_nblocks=nblocks;
543+
}
544+
545+
/* ----------------------------
546+
* TODO Replace it somewhere. END.
547+
* ----------------------------
548+
*/
549+
461550

462551
/*
463552
* ComputeIoConcurrency -- get the number of pages to prefetch for a given
@@ -662,6 +751,7 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum,
662751
*/
663752
pgstat_count_buffer_read(reln);
664753
buf=ReadBuffer_common(reln->rd_smgr,reln->rd_rel->relpersistence,
754+
reln->rd_rel->relkind,
665755
forkNum,blockNum,mode,strategy,&hit);
666756
if (hit)
667757
pgstat_count_buffer_hit(reln);
@@ -689,7 +779,7 @@ ReadBufferWithoutRelcache(RelFileNode rnode, ForkNumber forkNum,
689779

690780
Assert(InRecovery);
691781

692-
returnReadBuffer_common(smgr,RELPERSISTENCE_PERMANENT,forkNum,blockNum,
782+
returnReadBuffer_common(smgr,RELPERSISTENCE_PERMANENT,RELKIND_UNKNOWN,forkNum,blockNum,
693783
mode,strategy,&hit);
694784
}
695785

@@ -711,15 +801,17 @@ ReadBufferWithoutRelcache2(SMgrRelation smgr, ForkNumber forkNum,
711801
* *hit is set to true if the request was satisfied from shared buffer cache.
712802
*/
713803
staticBuffer
714-
ReadBuffer_common(SMgrRelationsmgr,charrelpersistence,ForkNumberforkNum,
715-
BlockNumberblockNum,ReadBufferModemode,
716-
BufferAccessStrategystrategy,bool*hit)
804+
ReadBuffer_common(SMgrRelationsmgr,charrelpersistence,charrelkind,
805+
ForkNumberforkNum,BlockNumberblockNum,ReadBufferModemode,
806+
BufferAccessStrategystrategy,bool*hit)
717807
{
718808
BufferDesc*bufHdr;
719809
BlockbufBlock;
720810
boolfound;
721811
boolisExtend;
722812
boolisLocalBuf=SmgrIsTemp(smgr);
813+
boolisTempTableMainFork= false;
814+
TempTableInfotti;
723815

724816
*hit= false;
725817

@@ -736,12 +828,70 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
736828
isExtend);
737829

738830
/* Substitute proper block number if caller asked for P_NEW */
831+
832+
/*
833+
* It's unnecessary to create a physical file for a local temp
834+
* relation when all buffers can be kept in memory.
835+
* Track actual number of blocks in tempTableHashTab and don't
836+
* use smgrnblocks to compute it.
837+
* Here we do all the work needed for cache initialization.
838+
*/
839+
if (isLocalBuf
840+
&&relkind==RELKIND_RELATION
841+
&&forkNum==MAIN_FORKNUM)
842+
{
843+
boolttiIsFound;
844+
RelFileNodernode=smgr->smgr_rnode.node;
845+
846+
elog(DEBUG1,"ReadBuffer_common. spcNode %u, dbNode %u, relNode %u",rnode.spcNode,rnode.dbNode,rnode.relNode);
847+
/* use the flag instead of "if" constructions like above */
848+
isTempTableMainFork= true;
849+
850+
/* Create hash table if it's the first call */
851+
if (tempTableHashTab==NULL)
852+
{
853+
create_temptableinfo_hashtable();
854+
elog(DEBUG1,"tempTableHashTab is created");
855+
}
856+
/* Find or create a hash table entry for this temp table */
857+
tti= (TempTableInfo)hash_search(tempTableHashTab,&rnode,
858+
HASH_ENTER,&ttiIsFound);
859+
860+
/*
861+
* If it's the first time we're going to extend rel,
862+
* fill the cache entry with number of blocks = 0
863+
*/
864+
if (!ttiIsFound)
865+
{
866+
elog(DEBUG1,"tempTableHashTab entry is not found");
867+
/* tti->rnode already filled in */
868+
tti->main_nblocks=0;
869+
}
870+
else
871+
{
872+
elog(DEBUG1,"tempTableHashTab is found. nblocks %u",tti->main_nblocks);
873+
}
874+
875+
/* And finally fill up the smgr cache value */
876+
smgr->smgr_main_nblocks=tti->main_nblocks;
877+
elog(DEBUG1,"We're done with a cache entry. smgr->smgr_main_nblocks %u tti->main_nblocks %u",
878+
smgr->smgr_main_nblocks,tti->main_nblocks);
879+
}
880+
739881
if (isExtend)
740-
blockNum=smgrnblocks(smgr,forkNum);
882+
{
883+
if (isTempTableMainFork)
884+
blockNum=smgr->smgr_main_nblocks;
885+
else
886+
blockNum=smgrnblocks(smgr,forkNum);
887+
888+
elog(DEBUG1,"isExtend. blockNum %u smgr->smgr_main_nblocks %u",blockNum,smgr->smgr_main_nblocks);
889+
}
741890

742891
if (isLocalBuf)
743892
{
744893
bufHdr=LocalBufferAlloc(smgr,forkNum,blockNum,&found);
894+
745895
if (found)
746896
pgBufferUsage.local_blks_hit++;
747897
else
@@ -873,7 +1023,23 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
8731023
/* new buffers are zero-filled */
8741024
MemSet((char*)bufBlock,0,BLCKSZ);
8751025
/* don't set checksum for all-zero page */
876-
smgrextend(smgr,forkNum,blockNum, (char*)bufBlock, false);
1026+
1027+
1028+
/* Do not extend physical file for temp tables while table fits
1029+
* into temp_buffers cache. We'll do it on demand, when buffer
1030+
* will be flushed out to disk.
1031+
* NOTE Currently works only for plain tables.
1032+
*/
1033+
if (isTempTableMainFork)
1034+
{
1035+
smgr->smgr_main_nblocks++;
1036+
tti->main_nblocks++;
1037+
}
1038+
else
1039+
smgrextend(smgr,forkNum,blockNum, (char*)bufBlock, false);
1040+
1041+
elog(DEBUG1,"isExtend 2. relnode %u smgr->smgr_main_nblocks %u",
1042+
smgr->smgr_rnode.node.relNode,smgr->smgr_main_nblocks);
8771043

8781044
/*
8791045
* NB: we're *not* doing a ScheduleBufferTagForWriteback here;
@@ -2784,6 +2950,31 @@ RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
27842950
/* Open it at the smgr level if not already done */
27852951
RelationOpenSmgr(relation);
27862952

2953+
/* Handle temp tables separately */
2954+
if (SmgrIsTemp(relation->rd_smgr)
2955+
&&forkNum==MAIN_FORKNUM
2956+
&&relation->rd_rel->relkind==RELKIND_RELATION)
2957+
{
2958+
TempTableInfotti;
2959+
boolttiIsFound;
2960+
RelFileNodernode=relation->rd_smgr->smgr_rnode.node;
2961+
2962+
/* If we have no hash table, the relation is definitely new and empty. */
2963+
if (tempTableHashTab==NULL)
2964+
return0;
2965+
2966+
tti= (TempTableInfo)hash_search(tempTableHashTab,&rnode,
2967+
HASH_FIND,&ttiIsFound);
2968+
if (!ttiIsFound)
2969+
{
2970+
elog(DEBUG1,"No cache entry for this temp relation");
2971+
// /* It's essential to fill the entry here */
2972+
// tti->main_nblocks = 0;
2973+
return0;
2974+
}
2975+
else
2976+
returntti->main_nblocks;
2977+
}
27872978
returnsmgrnblocks(relation->rd_smgr,forkNum);
27882979
}
27892980

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp