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