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