7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
9
* IDENTIFICATION
10
- * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.150 2009/08/05 18:01:54 heikki Exp $
10
+ * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.151 2009/12/03 11:03:28 heikki Exp $
11
11
*
12
12
* NOTES:
13
13
*
55
55
#include "storage/fd.h"
56
56
#include "storage/ipc.h"
57
57
#include "utils/guc.h"
58
+ #include "utils/resowner.h"
58
59
59
60
60
61
/*
@@ -134,7 +135,7 @@ typedef struct vfd
134
135
{
135
136
int fd ; /* current FD, or VFD_CLOSED if none */
136
137
unsigned short fdstate ; /* bitflags for VFD's state */
137
- SubTransactionId create_subid ; /* for TEMPORARY fds, creating subxact */
138
+ ResourceOwner resowner ; /* owner, for automatic cleanup */
138
139
File nextFree ; /* link to next free VFD, if in freelist */
139
140
File lruMoreRecently ; /* doubly linked recency-of-use list */
140
141
File lruLessRecently ;
@@ -865,6 +866,7 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
865
866
vfdP -> fileMode = fileMode ;
866
867
vfdP -> seekPos = 0 ;
867
868
vfdP -> fdstate = 0x0 ;
869
+ vfdP -> resowner = NULL ;
868
870
869
871
return file ;
870
872
}
@@ -876,11 +878,12 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
876
878
* There's no need to pass in fileFlags or fileMode either, since only
877
879
* one setting makes any sense for a temp file.
878
880
*
879
- * interXact: if true, don't close the file at end-of-transaction. In
880
- * most cases, you don't want temporary files to outlive the transaction
881
- * that created them, so this should be false -- but if you need
882
- * "somewhat" temporary storage, this might be useful. In either case,
883
- * the file is removed when the File is explicitly closed.
881
+ * Unless interXact is true, the file is remembered by CurrentResourceOwner
882
+ * to ensure it's closed and deleted when it's no longer needed, typically at
883
+ * the end-of-transaction. In most cases, you don't want temporary files to
884
+ * outlive the transaction that created them, so this should be false -- but
885
+ * if you need "somewhat" temporary storage, this might be useful. In either
886
+ * case, the file is removed when the File is explicitly closed.
884
887
*/
885
888
File
886
889
OpenTemporaryFile (bool interXact )
@@ -918,11 +921,14 @@ OpenTemporaryFile(bool interXact)
918
921
/* Mark it for deletion at close */
919
922
VfdCache [file ].fdstate |= FD_TEMPORARY ;
920
923
921
- /* Mark it for deletion at EOXact */
924
+ /* Register it with the current resource owner */
922
925
if (!interXact )
923
926
{
924
927
VfdCache [file ].fdstate |= FD_XACT_TEMPORARY ;
925
- VfdCache [file ].create_subid = GetCurrentSubTransactionId ();
928
+
929
+ ResourceOwnerEnlargeFiles (CurrentResourceOwner );
930
+ ResourceOwnerRememberFile (CurrentResourceOwner , file );
931
+ VfdCache [file ].resowner = CurrentResourceOwner ;
926
932
927
933
/* ensure cleanup happens at eoxact */
928
934
have_xact_temporary_files = true;
@@ -1051,6 +1057,10 @@ FileClose(File file)
1051
1057
elog (LOG , "could not unlink file \"%s\": %m" , vfdP -> fileName );
1052
1058
}
1053
1059
1060
+ /* Unregister it from the resource owner */
1061
+ if (vfdP -> resowner )
1062
+ ResourceOwnerForgetFile (vfdP -> resowner , file );
1063
+
1054
1064
/*
1055
1065
* Return the Vfd slot to the free list
1056
1066
*/
@@ -1695,24 +1705,6 @@ AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
1695
1705
{
1696
1706
Index i ;
1697
1707
1698
- if (have_xact_temporary_files )
1699
- {
1700
- Assert (FileIsNotOpen (0 )); /* Make sure ring not corrupted */
1701
- for (i = 1 ; i < SizeVfdCache ; i ++ )
1702
- {
1703
- unsigned short fdstate = VfdCache [i ].fdstate ;
1704
-
1705
- if ((fdstate & FD_XACT_TEMPORARY ) &&
1706
- VfdCache [i ].create_subid == mySubid )
1707
- {
1708
- if (isCommit )
1709
- VfdCache [i ].create_subid = parentSubid ;
1710
- else if (VfdCache [i ].fileName != NULL )
1711
- FileClose (i );
1712
- }
1713
- }
1714
- }
1715
-
1716
1708
for (i = 0 ; i < numAllocatedDescs ; i ++ )
1717
1709
{
1718
1710
if (allocatedDescs [i ].create_subid == mySubid )
@@ -1733,9 +1725,10 @@ AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
1733
1725
*
1734
1726
* This routine is called during transaction commit or abort (it doesn't
1735
1727
* particularly care which). All still-open per-transaction temporary file
1736
- * VFDs are closed, which also causes the underlying files to be
1737
- * deleted. Furthermore, all "allocated" stdio files are closed.
1738
- * We also forget any transaction-local temp tablespace list.
1728
+ * VFDs are closed, which also causes the underlying files to be deleted
1729
+ * (although they should've been closed already by the ResourceOwner
1730
+ * cleanup). Furthermore, all "allocated" stdio files are closed. We also
1731
+ * forget any transaction-local temp tablespace list.
1739
1732
*/
1740
1733
void
1741
1734
AtEOXact_Files (void )
@@ -1787,16 +1780,26 @@ CleanupTempFiles(bool isProcExit)
1787
1780
/*
1788
1781
* If we're in the process of exiting a backend process, close
1789
1782
* all temporary files. Otherwise, only close temporary files
1790
- * local to the current transaction.
1783
+ * local to the current transaction. They should be closed
1784
+ * by the ResourceOwner mechanism already, so this is just
1785
+ * a debugging cross-check.
1791
1786
*/
1792
- if (isProcExit || (fdstate & FD_XACT_TEMPORARY ))
1787
+ if (isProcExit )
1788
+ FileClose (i );
1789
+ else if (fdstate & FD_XACT_TEMPORARY )
1790
+ {
1791
+ elog (WARNING ,
1792
+ "temporary file %s not closed at end-of-transaction" ,
1793
+ VfdCache [i ].fileName );
1793
1794
FileClose (i );
1795
+ }
1794
1796
}
1795
1797
}
1796
1798
1797
1799
have_xact_temporary_files = false;
1798
1800
}
1799
1801
1802
+ /* Clean up "allocated" stdio files and dirs. */
1800
1803
while (numAllocatedDescs > 0 )
1801
1804
FreeDesc (& allocatedDescs [0 ]);
1802
1805
}
0 commit comments