Heikki Linnakangas escribió:

> I'm surprised you implemented RegisterSnapshotOnOwner by switching  
> CurrentResourceOwner and calling RegisterSnapshot, rather than  
> implementing RegisterSnapshot by calling RegisterSnapshotOnOwner(...,  
> CurrentResourceOwner).

Yeah, that was plenty silly.  Updated patch attached.

-- 
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 20:45:43 -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)
*** 357,369 ****
  	if (snapshot == InvalidSnapshot)
  		return InvalidSnapshot;
  
  	/* Static snapshot?  Create a persistent copy */
  	snap = snapshot->copied ? snapshot : CopySnapshot(snapshot);
  
  	/* and tell resowner.c about it */
! 	ResourceOwnerEnlargeSnapshots(CurrentResourceOwner);
  	snap->regd_count++;
! 	ResourceOwnerRememberSnapshot(CurrentResourceOwner, snap);
  
  	RegisteredSnapshots++;
  
--- 358,385 ----
  	if (snapshot == InvalidSnapshot)
  		return InvalidSnapshot;
  
+ 	return RegisterSnapshotOnOwner(snapshot, CurrentResourceOwner);
+ }
+ 
+ /*
+  * RegisterSnapshotOnOwner
+  * 		As above, but use the specified resource owner
+  */
+ Snapshot
+ RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner)
+ {
+ 	Snapshot		snap;
+ 
+ 	if (snapshot == InvalidSnapshot)
+ 		return InvalidSnapshot;
+ 
  	/* Static snapshot?  Create a persistent copy */
  	snap = snapshot->copied ? snapshot : CopySnapshot(snapshot);
  
  	/* and tell resowner.c about it */
! 	ResourceOwnerEnlargeSnapshots(owner);
  	snap->regd_count++;
! 	ResourceOwnerRememberSnapshot(owner, snap);
  
  	RegisteredSnapshots++;
  
*************** UnregisterSnapshot(Snapshot snapshot)
*** 383,392 ****
  	if (snapshot == NULL)
  		return;
  
  	Assert(snapshot->regd_count > 0);
  	Assert(RegisteredSnapshots > 0);
  
! 	ResourceOwnerForgetSnapshot(CurrentResourceOwner, snapshot);
  	RegisteredSnapshots--;
  	if (--snapshot->regd_count == 0 && snapshot->active_count == 0)
  	{
--- 399,421 ----
  	if (snapshot == NULL)
  		return;
  
+ 	UnregisterSnapshotFromOwner(snapshot, CurrentResourceOwner);
+ }
+ 
+ /*
+  * UnregisterSnapshotFromOwner
+  * 		As above, but use the specified resource owner
+  */
+ void
+ UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner)
+ {
+ 	if (snapshot == NULL)
+ 		return;
+ 
  	Assert(snapshot->regd_count > 0);
  	Assert(RegisteredSnapshots > 0);
  
! 	ResourceOwnerForgetSnapshot(owner, snapshot);
  	RegisteredSnapshots--;
  	if (--snapshot->regd_count == 0 && snapshot->active_count == 0)
  	{
*************** AtSubAbort_Snapshot(int level)
*** 464,469 ****
--- 493,518 ----
  }
  
  /*
+  * AtEarlyCommit_Snapshot
+  *
+  * Snapshot manager's cleanup function, to be called on commit, before
+  * doing resowner.c resource release.
+  */
+ void
+ AtEarlyCommit_Snapshot(void)
+ {
+ 	/*
+ 	 * On a serializable transaction we must unregister our private refcount to
+ 	 * the serializable snapshot.
+ 	 */
+ 	if (registered_serializable)
+ 		UnregisterSnapshotFromOwner(CurrentSnapshot,
+ 									TopTransactionResourceOwner);
+ 	registered_serializable = false;
+ 
+ }
+ 
+ /*
   * 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);
--- 524,529 ----
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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to