Alvaro Herrera escribió:
> Yeah, we need two "at-commit" routines, one of which needs to be called
> early. I'm prepping a patch.
Here it is ... the large object patch is also included. I've created
new functions to specify the resource owner to register a snapshot in;
now that there are two callers, it seems likely that there will be more
in the future.
--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/access/transam/xact.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/transam/xact.c,v
retrieving revision 1.269
diff -c -p -r1.269 xact.c
*** src/backend/access/transam/xact.c 19 Nov 2008 10:34:50 -0000 1.269
--- src/backend/access/transam/xact.c 3 Dec 2008 19:30:35 -0000
*************** CommitTransaction(void)
*** 1667,1672 ****
--- 1667,1675 ----
/* Clean up the relation cache */
AtEOXact_RelationCache(true);
+ /* Clean up the snapshot manager */
+ AtEarlyCommit_Snapshot();
+
/*
* Make catalog changes visible to all backends. This has to happen after
* relcache references are dropped (see comments for
*************** PrepareTransaction(void)
*** 1906,1911 ****
--- 1909,1917 ----
/* Clean up the relation cache */
AtEOXact_RelationCache(true);
+ /* Clean up the snapshot manager */
+ AtEarlyCommit_Snapshot();
+
/* notify and flatfiles don't need a postprepare call */
PostPrepare_PgStat();
Index: src/backend/storage/large_object/inv_api.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/storage/large_object/inv_api.c,v
retrieving revision 1.135
diff -c -p -r1.135 inv_api.c
*** src/backend/storage/large_object/inv_api.c 2 Nov 2008 01:45:28 -0000 1.135
--- src/backend/storage/large_object/inv_api.c 3 Dec 2008 18:59:43 -0000
*************** inv_open(Oid lobjId, int flags, MemoryCo
*** 247,253 ****
}
else if (flags & INV_READ)
{
! retval->snapshot = RegisterSnapshot(GetActiveSnapshot());
retval->flags = IFS_RDLOCK;
}
else
--- 247,254 ----
}
else if (flags & INV_READ)
{
! retval->snapshot = RegisterSnapshotOnOwner(GetActiveSnapshot(),
! TopTransactionResourceOwner);
retval->flags = IFS_RDLOCK;
}
else
*************** void
*** 270,277 ****
inv_close(LargeObjectDesc *obj_desc)
{
Assert(PointerIsValid(obj_desc));
if (obj_desc->snapshot != SnapshotNow)
! UnregisterSnapshot(obj_desc->snapshot);
pfree(obj_desc);
}
--- 271,281 ----
inv_close(LargeObjectDesc *obj_desc)
{
Assert(PointerIsValid(obj_desc));
+
if (obj_desc->snapshot != SnapshotNow)
! UnregisterSnapshotFromOwner(obj_desc->snapshot,
! TopTransactionResourceOwner);
!
pfree(obj_desc);
}
Index: src/backend/utils/time/snapmgr.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/utils/time/snapmgr.c,v
retrieving revision 1.7
diff -c -p -r1.7 snapmgr.c
*** src/backend/utils/time/snapmgr.c 25 Nov 2008 20:28:29 -0000 1.7
--- src/backend/utils/time/snapmgr.c 3 Dec 2008 19:28:50 -0000
*************** GetTransactionSnapshot(void)
*** 136,142 ****
*/
if (IsXactIsoLevelSerializable)
{
! CurrentSnapshot = RegisterSnapshot(CurrentSnapshot);
registered_serializable = true;
}
--- 136,143 ----
*/
if (IsXactIsoLevelSerializable)
{
! CurrentSnapshot = RegisterSnapshotOnOwner(CurrentSnapshot,
! TopTransactionResourceOwner);
registered_serializable = true;
}
*************** ActiveSnapshotSet(void)
*** 345,351 ****
/*
* RegisterSnapshot
! * Register a snapshot as being in use
*
* If InvalidSnapshot is passed, it is not registered.
*/
--- 346,352 ----
/*
* RegisterSnapshot
! * Register a snapshot as being in use by the current resource owner
*
* If InvalidSnapshot is passed, it is not registered.
*/
*************** RegisterSnapshot(Snapshot snapshot)
*** 371,376 ****
--- 372,396 ----
}
/*
+ * As above, but register it on a specific resource owner
+ */
+ Snapshot
+ RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner)
+ {
+ Snapshot retval;
+ ResourceOwner save_CurrentResourceOwner;
+
+ save_CurrentResourceOwner = CurrentResourceOwner;
+ CurrentResourceOwner = TopTransactionResourceOwner;
+
+ retval = RegisterSnapshot(snapshot);
+
+ CurrentResourceOwner = save_CurrentResourceOwner;
+
+ return retval;
+ }
+
+ /*
* UnregisterSnapshot
*
* Decrement the reference count of a snapshot, remove the corresponding
*************** UnregisterSnapshot(Snapshot snapshot)
*** 395,400 ****
--- 415,433 ----
}
}
+ void
+ UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner)
+ {
+ ResourceOwner save_CurrentResourceOwner;
+
+ save_CurrentResourceOwner = CurrentResourceOwner;
+ CurrentResourceOwner = TopTransactionResourceOwner;
+
+ UnregisterSnapshot(snapshot);
+
+ CurrentResourceOwner = save_CurrentResourceOwner;
+ }
+
/*
* SnapshotResetXmin
*
*************** AtSubAbort_Snapshot(int level)
*** 463,468 ****
--- 496,514 ----
SnapshotResetXmin();
}
+ void
+ AtEarlyCommit_Snapshot(void)
+ {
+ /*
+ * On a serializable transaction we must first unregister our private
+ * refcount to the serializable snapshot.
+ */
+ if (registered_serializable)
+ UnregisterSnapshotFromOwner(CurrentSnapshot,
+ TopTransactionResourceOwner);
+
+ }
+
/*
* AtEOXact_Snapshot
* Snapshot manager's cleanup function for end of transaction
*************** AtEOXact_Snapshot(bool isCommit)
*** 475,487 ****
{
ActiveSnapshotElt *active;
- /*
- * On a serializable snapshot we must first unregister our private
- * refcount to the serializable snapshot.
- */
- if (registered_serializable)
- UnregisterSnapshot(CurrentSnapshot);
-
if (RegisteredSnapshots != 0)
elog(WARNING, "%d registered snapshots seem to remain after cleanup",
RegisteredSnapshots);
--- 521,526 ----
Index: src/include/utils/snapmgr.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/utils/snapmgr.h,v
retrieving revision 1.2
diff -c -p -r1.2 snapmgr.h
*** src/include/utils/snapmgr.h 12 May 2008 20:02:02 -0000 1.2
--- src/include/utils/snapmgr.h 3 Dec 2008 19:31:06 -0000
***************
*** 13,18 ****
--- 13,19 ----
#ifndef SNAPMGR_H
#define SNAPMGR_H
+ #include "utils/resowner.h"
#include "utils/snapshot.h"
*************** extern bool ActiveSnapshotSet(void);
*** 34,42 ****
--- 35,46 ----
extern Snapshot RegisterSnapshot(Snapshot snapshot);
extern void UnregisterSnapshot(Snapshot snapshot);
+ extern Snapshot RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner);
+ extern void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner);
extern void AtSubCommit_Snapshot(int level);
extern void AtSubAbort_Snapshot(int level);
+ extern void AtEarlyCommit_Snapshot(void);
extern void AtEOXact_Snapshot(bool isCommit);
#endif /* SNAPMGR_H */
Index: src/test/regress/input/largeobject.source
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/test/regress/input/largeobject.source,v
retrieving revision 1.4
diff -c -p -r1.4 largeobject.source
*** src/test/regress/input/largeobject.source 3 Mar 2007 22:57:03 -0000 1.4
--- src/test/regress/input/largeobject.source 2 Dec 2008 14:27:26 -0000
*************** SELECT lo_close(fd) FROM lotest_stash_va
*** 83,88 ****
--- 83,93 ----
END;
+ -- Test resource management
+ BEGIN;
+ SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
+ ABORT;
+
-- Test truncation.
BEGIN;
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
Index: src/test/regress/output/largeobject.source
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/test/regress/output/largeobject.source,v
retrieving revision 1.4
diff -c -p -r1.4 largeobject.source
*** src/test/regress/output/largeobject.source 3 Mar 2007 22:57:04 -0000 1.4
--- src/test/regress/output/largeobject.source 2 Dec 2008 14:42:34 -0000
*************** SELECT lo_close(fd) FROM lotest_stash_va
*** 116,121 ****
--- 116,130 ----
(1 row)
END;
+ -- Test resource management
+ BEGIN;
+ SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
+ lo_open
+ ---------
+ 0
+ (1 row)
+
+ ABORT;
-- Test truncation.
BEGIN;
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
Index: src/test/regress/output/largeobject_1.source
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/test/regress/output/largeobject_1.source,v
retrieving revision 1.1
diff -c -p -r1.1 largeobject_1.source
*** src/test/regress/output/largeobject_1.source 10 Mar 2007 03:42:19 -0000 1.1
--- src/test/regress/output/largeobject_1.source 2 Dec 2008 14:42:51 -0000
*************** SELECT lo_close(fd) FROM lotest_stash_va
*** 116,121 ****
--- 116,130 ----
(1 row)
END;
+ -- Test resource management
+ BEGIN;
+ SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
+ lo_open
+ ---------
+ 0
+ (1 row)
+
+ ABORT;
-- Test truncation.
BEGIN;
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers