diff options
Diffstat (limited to 'src/backend/catalog/storage.c')
| -rw-r--r-- | src/backend/catalog/storage.c | 57 |
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); |
