summaryrefslogtreecommitdiff
path: root/src/backend/catalog/storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/storage.c')
-rw-r--r--src/backend/catalog/storage.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index 2165341e0e..5a1131945c 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/storage.c,v 1.10 2010/02/09 21:43:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/storage.c,v 1.11 2010/08/13 20:10:50 rhaas Exp $
*
* NOTES
* Some of this code used to be in storage/smgr/smgr.c, and the
@@ -52,7 +52,7 @@
typedef struct PendingRelDelete
{
RelFileNode relnode; /* relation that may need to be deleted */
- bool isTemp; /* is it a temporary relation? */
+ BackendId backend; /* InvalidBackendId if not a temp rel */
bool atCommit; /* T=delete at commit; F=delete at abort */
int nestLevel; /* xact nesting level of request */
struct PendingRelDelete *next; /* linked-list link */
@@ -102,8 +102,9 @@ RelationCreateStorage(RelFileNode rnode, bool istemp)
XLogRecData rdata;
xl_smgr_create xlrec;
SMgrRelation srel;
+ BackendId backend = istemp ? MyBackendId : InvalidBackendId;
- srel = smgropen(rnode);
+ srel = smgropen(rnode, backend);
smgrcreate(srel, MAIN_FORKNUM, false);
if (!istemp)
@@ -125,7 +126,7 @@ RelationCreateStorage(RelFileNode rnode, bool istemp)
pending = (PendingRelDelete *)
MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
pending->relnode = rnode;
- pending->isTemp = istemp;
+ pending->backend = backend;
pending->atCommit = false; /* delete if abort */
pending->nestLevel = GetCurrentTransactionNestLevel();
pending->next = pendingDeletes;
@@ -145,7 +146,7 @@ RelationDropStorage(Relation rel)
pending = (PendingRelDelete *)
MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
pending->relnode = rel->rd_node;
- pending->isTemp = rel->rd_istemp;
+ pending->backend = rel->rd_backend;
pending->atCommit = true; /* delete if commit */
pending->nestLevel = GetCurrentTransactionNestLevel();
pending->next = pendingDeletes;
@@ -283,7 +284,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
}
/* Do the real work */
- smgrtruncate(rel->rd_smgr, MAIN_FORKNUM, nblocks, rel->rd_istemp);
+ smgrtruncate(rel->rd_smgr, MAIN_FORKNUM, nblocks);
}
/*
@@ -291,6 +292,11 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
*
* This also runs when aborting a subxact; we want to clean up a failed
* subxact immediately.
+ *
+ * Note: It's possible that we're being asked to remove a relation that has
+ * no physical storage in any fork. In particular, it's possible that we're
+ * cleaning up an old temporary relation for which RemovePgTempFiles has
+ * already recovered the physical storage.
*/
void
smgrDoPendingDeletes(bool isCommit)
@@ -322,14 +328,11 @@ smgrDoPendingDeletes(bool isCommit)
SMgrRelation srel;
int i;
- srel = smgropen(pending->relnode);
+ srel = smgropen(pending->relnode, pending->backend);
for (i = 0; i <= MAX_FORKNUM; i++)
{
if (smgrexists(srel, i))
- smgrdounlink(srel,
- i,
- pending->isTemp,
- false);
+ smgrdounlink(srel, i, false);
}
smgrclose(srel);
}
@@ -341,20 +344,24 @@ smgrDoPendingDeletes(bool isCommit)
}
/*
- * smgrGetPendingDeletes() -- Get a list of relations to be deleted.
+ * smgrGetPendingDeletes() -- Get a list of non-temp relations to be deleted.
*
* The return value is the number of relations scheduled for termination.
* *ptr is set to point to a freshly-palloc'd array of RelFileNodes.
* If there are no relations to be deleted, *ptr is set to NULL.
*
- * If haveNonTemp isn't NULL, the bool it points to gets set to true if
- * there is any non-temp table pending to be deleted; false if not.
+ * Only non-temporary relations are included in the returned list. This is OK
+ * because the list is used only in contexts where temporary relations don't
+ * matter: we're either writing to the two-phase state file (and transactions
+ * that have touched temp tables can't be prepared) or we're writing to xlog
+ * (and all temporary files will be zapped if we restart anyway, so no need
+ * for redo to do it also).
*
* Note that the list does not include anything scheduled for termination
* by upper-level transactions.
*/
int
-smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr, bool *haveNonTemp)
+smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr)
{
int nestLevel = GetCurrentTransactionNestLevel();
int nrels;
@@ -362,11 +369,10 @@ smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr, bool *haveNonTemp)
PendingRelDelete *pending;
nrels = 0;
- if (haveNonTemp)
- *haveNonTemp = false;
for (pending = pendingDeletes; pending != NULL; pending = pending->next)
{
- if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit)
+ if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit
+ && pending->backend == InvalidBackendId)
nrels++;
}
if (nrels == 0)
@@ -378,13 +384,12 @@ smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr, bool *haveNonTemp)
*ptr = rptr;
for (pending = pendingDeletes; pending != NULL; pending = pending->next)
{
- if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit)
+ if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit
+ && pending->backend == InvalidBackendId)
{
*rptr = pending->relnode;
rptr++;
}
- if (haveNonTemp && !pending->isTemp)
- *haveNonTemp = true;
}
return nrels;
}
@@ -456,7 +461,7 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
xl_smgr_create *xlrec = (xl_smgr_create *) XLogRecGetData(record);
SMgrRelation reln;
- reln = smgropen(xlrec->rnode);
+ reln = smgropen(xlrec->rnode, InvalidBackendId);
smgrcreate(reln, MAIN_FORKNUM, true);
}
else if (info == XLOG_SMGR_TRUNCATE)
@@ -465,7 +470,7 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
SMgrRelation reln;
Relation rel;
- reln = smgropen(xlrec->rnode);
+ reln = smgropen(xlrec->rnode, InvalidBackendId);
/*
* Forcibly create relation if it doesn't exist (which suggests that
@@ -475,7 +480,7 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
*/
smgrcreate(reln, MAIN_FORKNUM, true);
- smgrtruncate(reln, MAIN_FORKNUM, xlrec->blkno, false);
+ smgrtruncate(reln, MAIN_FORKNUM, xlrec->blkno);
/* Also tell xlogutils.c about it */
XLogTruncateRelation(xlrec->rnode, MAIN_FORKNUM, xlrec->blkno);
@@ -502,7 +507,7 @@ smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
if (info == XLOG_SMGR_CREATE)
{
xl_smgr_create *xlrec = (xl_smgr_create *) rec;
- char *path = relpath(xlrec->rnode, MAIN_FORKNUM);
+ char *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);
appendStringInfo(buf, "file create: %s", path);
pfree(path);
@@ -510,7 +515,7 @@ smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
else if (info == XLOG_SMGR_TRUNCATE)
{
xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
- char *path = relpath(xlrec->rnode, MAIN_FORKNUM);
+ char *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);
appendStringInfo(buf, "file truncate: %s to %u blocks", path,
xlrec->blkno);