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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to