summaryrefslogtreecommitdiff
path: root/src/backend/libpq/be-fsstubs.c
diff options
context:
space:
mode:
authorTom Lane2004-07-28 14:23:31 +0000
committerTom Lane2004-07-28 14:23:31 +0000
commit1bf3d615047eb214b1ddde31bd268dabf96cc3fa (patch)
tree0fdb8cc0a4203c338b6f73130c9ef74b64d4a74e /src/backend/libpq/be-fsstubs.c
parentcc813fc2b8d9293bbd4d0e0d6a6f3b9cf02fe32f (diff)
Fix subtransaction behavior for large objects, temp namespace, files,
password/group files. Also allow read-only subtransactions of a read-write parent, but not vice versa. These are the reasonably noncontroversial parts of Alvaro's recent mop-up patch, plus further work on large objects to minimize use of the TopTransactionResourceOwner.
Diffstat (limited to 'src/backend/libpq/be-fsstubs.c')
-rw-r--r--src/backend/libpq/be-fsstubs.c73
1 files changed, 57 insertions, 16 deletions
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index ed19e76db2c..21d1f3ddcfe 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -1,24 +1,22 @@
/*-------------------------------------------------------------------------
*
* be-fsstubs.c
- * support for filesystem operations on large objects
+ * Builtin functions for open/close/read/write operations on large objects
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/libpq/be-fsstubs.c,v 1.70 2004/02/10 01:55:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/libpq/be-fsstubs.c,v 1.71 2004/07/28 14:23:28 tgl Exp $
*
* NOTES
* This should be moved to a more appropriate place. It is here
* for lack of a better place.
*
- * Builtin functions for open/close/read/write operations on large objects.
- *
* These functions operate in a private MemoryContext, which means
- * that large object descriptors hang around until we destroy the context.
- * That happens in lo_commit(). It'd be possible to prolong the lifetime
+ * that large object descriptors hang around until we destroy the context
+ * at transaction end. It'd be possible to prolong the lifetime
* of the context so that LO FDs are good across transactions (for example,
* we could release the context only if we see that no FDs remain open).
* But we'd need additional state in order to do the right thing at the
@@ -29,6 +27,11 @@
* existing documented semantics of LO FDs: they're only good within a
* transaction.
*
+ * As of PostgreSQL 7.5, much of the angst expressed above is no longer
+ * relevant, and in fact it'd be pretty easy to allow LO FDs to stay
+ * open across transactions. However backwards compatibility suggests
+ * that we should stick to the status quo.
+ *
*-------------------------------------------------------------------------
*/
@@ -46,8 +49,6 @@
#include "utils/memutils.h"
-/* [PA] is Pascal Andr� <[email protected]> */
-
/*#define FSDB 1*/
#define BUFSIZE 8192
@@ -68,6 +69,7 @@ static MemoryContext fscxt = NULL;
static int newLOfd(LargeObjectDesc *lobjCookie);
static void deleteLOfd(int fd);
+
/*****************************************************************************
* File Interfaces for Large Objects
*****************************************************************************/
@@ -399,7 +401,7 @@ lo_import(PG_FUNCTION_ARGS)
lobjOid = lobj->id;
/*
- * read in from the Unix file and write to the inversion file
+ * read in from the filesystem and write to the inversion file
*/
while ((nbytes = FileRead(fd, buf, BUFSIZE)) > 0)
{
@@ -471,7 +473,7 @@ lo_export(PG_FUNCTION_ARGS)
fnamebuf)));
/*
- * read in from the inversion file and write to the Unix file
+ * read in from the inversion file and write to the filesystem
*/
while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0)
{
@@ -490,11 +492,11 @@ lo_export(PG_FUNCTION_ARGS)
}
/*
- * lo_commit -
- * prepares large objects for transaction commit [PA, 7/17/98]
+ * AtEOXact_LargeObject -
+ * prepares large objects for transaction commit
*/
void
-lo_commit(bool isCommit)
+AtEOXact_LargeObject(bool isCommit)
{
int i;
MemoryContext currentContext;
@@ -505,8 +507,8 @@ lo_commit(bool isCommit)
currentContext = MemoryContextSwitchTo(fscxt);
/*
- * Clean out still-open index scans (not necessary if aborting) and
- * clear cookies array so that LO fds are no longer good.
+ * Close LO fds and clear cookies array so that LO fds are no longer good.
+ * On abort we skip the close step.
*/
for (i = 0; i < cookies_size; i++)
{
@@ -514,7 +516,7 @@ lo_commit(bool isCommit)
{
if (isCommit)
inv_close(cookies[i]);
- cookies[i] = NULL;
+ deleteLOfd(i);
}
}
@@ -527,8 +529,47 @@ lo_commit(bool isCommit)
/* Release the LO memory context to prevent permanent memory leaks. */
MemoryContextDelete(fscxt);
fscxt = NULL;
+
+ /* Give inv_api.c a chance to clean up, too */
+ close_lo_relation(isCommit);
}
+/*
+ * AtEOSubXact_LargeObject
+ * Take care of large objects at subtransaction commit/abort
+ *
+ * Reassign LOs created/opened during a committing subtransaction
+ * to the parent transaction. On abort, just close them.
+ */
+void
+AtEOSubXact_LargeObject(bool isCommit, TransactionId myXid,
+ TransactionId parentXid)
+{
+ int i;
+
+ if (fscxt == NULL) /* no LO operations in this xact */
+ return;
+
+ for (i = 0; i < cookies_size; i++)
+ {
+ LargeObjectDesc *lo = cookies[i];
+
+ if (lo != NULL && lo->xid == myXid)
+ {
+ if (isCommit)
+ lo->xid = parentXid;
+ else
+ {
+ /*
+ * Make sure we do not call inv_close twice if it errors out
+ * for some reason. Better a leak than a crash.
+ */
+ deleteLOfd(i);
+ inv_close(lo);
+ }
+ }
+ }
+}
/*****************************************************************************
* Support routines for this file