@ -7,7 +7,7 @@
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / storage / file / fd . c , v 1.150 2009 / 08 / 05 18 : 01 : 54 heikki Exp $
* $ PostgreSQL : pgsql / src / backend / storage / file / fd . c , v 1.151 2009 / 12 / 03 11 : 03 : 28 heikki Exp $
*
* NOTES :
*
@ -55,6 +55,7 @@
# include "storage/fd.h"
# include "storage/ipc.h"
# include "utils/guc.h"
# include "utils/resowner.h"
/*
@ -134,7 +135,7 @@ typedef struct vfd
{
int fd ; /* current FD, or VFD_CLOSED if none */
unsigned short fdstate ; /* bitflags for VFD's state */
SubTransactionId create_subid ; /* for TEMPORARY fds, creating subxact */
ResourceOwner resowner ; /* owner, for automatic cleanup */
File nextFree ; /* link to next free VFD, if in freelist */
File lruMoreRecently ; /* doubly linked recency-of-use list */
File lruLessRecently ;
@ -865,6 +866,7 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
vfdP - > fileMode = fileMode ;
vfdP - > seekPos = 0 ;
vfdP - > fdstate = 0x0 ;
vfdP - > resowner = NULL ;
return file ;
}
@ -876,11 +878,12 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
* There ' s no need to pass in fileFlags or fileMode either , since only
* one setting makes any sense for a temp file .
*
* interXact : if true , don ' t close the file at end - of - transaction . In
* most cases , you don ' t want temporary files to outlive the transaction
* that created them , so this should be false - - but if you need
* " somewhat " temporary storage , this might be useful . In either case ,
* the file is removed when the File is explicitly closed .
* Unless interXact is true , the file is remembered by CurrentResourceOwner
* to ensure it ' s closed and deleted when it ' s no longer needed , typically at
* the end - of - transaction . In most cases , you don ' t want temporary files to
* outlive the transaction that created them , so this should be false - - but
* if you need " somewhat " temporary storage , this might be useful . In either
* case , the file is removed when the File is explicitly closed .
*/
File
OpenTemporaryFile ( bool interXact )
@ -918,11 +921,14 @@ OpenTemporaryFile(bool interXact)
/* Mark it for deletion at close */
VfdCache [ file ] . fdstate | = FD_TEMPORARY ;
/* Mark it for deletion at EOXact */
/* Register it with the current resource owner */
if ( ! interXact )
{
VfdCache [ file ] . fdstate | = FD_XACT_TEMPORARY ;
VfdCache [ file ] . create_subid = GetCurrentSubTransactionId ( ) ;
ResourceOwnerEnlargeFiles ( CurrentResourceOwner ) ;
ResourceOwnerRememberFile ( CurrentResourceOwner , file ) ;
VfdCache [ file ] . resowner = CurrentResourceOwner ;
/* ensure cleanup happens at eoxact */
have_xact_temporary_files = true ;
@ -1051,6 +1057,10 @@ FileClose(File file)
elog ( LOG , " could not unlink file \" %s \" : %m " , vfdP - > fileName ) ;
}
/* Unregister it from the resource owner */
if ( vfdP - > resowner )
ResourceOwnerForgetFile ( vfdP - > resowner , file ) ;
/*
* Return the Vfd slot to the free list
*/
@ -1695,24 +1705,6 @@ AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
{
Index i ;
if ( have_xact_temporary_files )
{
Assert ( FileIsNotOpen ( 0 ) ) ; /* Make sure ring not corrupted */
for ( i = 1 ; i < SizeVfdCache ; i + + )
{
unsigned short fdstate = VfdCache [ i ] . fdstate ;
if ( ( fdstate & FD_XACT_TEMPORARY ) & &
VfdCache [ i ] . create_subid = = mySubid )
{
if ( isCommit )
VfdCache [ i ] . create_subid = parentSubid ;
else if ( VfdCache [ i ] . fileName ! = NULL )
FileClose ( i ) ;
}
}
}
for ( i = 0 ; i < numAllocatedDescs ; i + + )
{
if ( allocatedDescs [ i ] . create_subid = = mySubid )
@ -1733,9 +1725,10 @@ AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
*
* This routine is called during transaction commit or abort ( it doesn ' t
* particularly care which ) . All still - open per - transaction temporary file
* VFDs are closed , which also causes the underlying files to be
* deleted . Furthermore , all " allocated " stdio files are closed .
* We also forget any transaction - local temp tablespace list .
* VFDs are closed , which also causes the underlying files to be deleted
* ( although they should ' ve been closed already by the ResourceOwner
* cleanup ) . Furthermore , all " allocated " stdio files are closed . We also
* forget any transaction - local temp tablespace list .
*/
void
AtEOXact_Files ( void )
@ -1787,16 +1780,26 @@ CleanupTempFiles(bool isProcExit)
/*
* If we ' re in the process of exiting a backend process , close
* all temporary files . Otherwise , only close temporary files
* local to the current transaction .
* local to the current transaction . They should be closed
* by the ResourceOwner mechanism already , so this is just
* a debugging cross - check .
*/
if ( isProcExit | | ( fdstate & FD_XACT_TEMPORARY ) )
if ( isProcExit )
FileClose ( i ) ;
else if ( fdstate & FD_XACT_TEMPORARY )
{
elog ( WARNING ,
" temporary file %s not closed at end-of-transaction " ,
VfdCache [ i ] . fileName ) ;
FileClose ( i ) ;
}
}
}
have_xact_temporary_files = false ;
}
/* Clean up "allocated" stdio files and dirs. */
while ( numAllocatedDescs > 0 )
FreeDesc ( & allocatedDescs [ 0 ] ) ;
}