Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7b640b0

Browse files
committed
Fix a couple of snapshot management bugs in the new ResourceOwner world:
non-writable large objects need to have their snapshots registered on thetransaction resowner, not the current portal's, because it must persist untilthe large object is closed (which the portal does not). Also, ensure that theserializable snapshot is recorded by the transaction resource owner too, evenwhen a subtransaction has changed the current resource owner beforeserializable is taken.Per bug reports from Pavan Deolasee.
1 parent30c5253 commit7b640b0

File tree

7 files changed

+101
-19
lines changed

7 files changed

+101
-19
lines changed

‎src/backend/access/transam/xact.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.269 2008/11/19 10:34:50 heikki Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.270 2008/12/04 14:51:02 alvherre Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1667,6 +1667,9 @@ CommitTransaction(void)
16671667
/* Clean up the relation cache */
16681668
AtEOXact_RelationCache(true);
16691669

1670+
/* Clean up the snapshot manager */
1671+
AtEarlyCommit_Snapshot();
1672+
16701673
/*
16711674
* Make catalog changes visible to all backends. This has to happen after
16721675
* relcache references are dropped (see comments for
@@ -1906,6 +1909,9 @@ PrepareTransaction(void)
19061909
/* Clean up the relation cache */
19071910
AtEOXact_RelationCache(true);
19081911

1912+
/* Clean up the snapshot manager */
1913+
AtEarlyCommit_Snapshot();
1914+
19091915
/* notify and flatfiles don't need a postprepare call */
19101916

19111917
PostPrepare_PgStat();

‎src/backend/storage/large_object/inv_api.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*
2525
*
2626
* IDENTIFICATION
27-
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.135 2008/11/02 01:45:28 tgl Exp $
27+
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.136 2008/12/04 14:51:02 alvherre Exp $
2828
*
2929
*-------------------------------------------------------------------------
3030
*/
@@ -247,7 +247,13 @@ inv_open(Oid lobjId, int flags, MemoryContext mcxt)
247247
}
248248
elseif (flags&INV_READ)
249249
{
250-
retval->snapshot=RegisterSnapshot(GetActiveSnapshot());
250+
/*
251+
* We must register the snapshot in TopTransaction's resowner,
252+
* because it must stay alive until the LO is closed rather than until
253+
* the current portal shuts down.
254+
*/
255+
retval->snapshot=RegisterSnapshotOnOwner(GetActiveSnapshot(),
256+
TopTransactionResourceOwner);
251257
retval->flags=IFS_RDLOCK;
252258
}
253259
else
@@ -270,8 +276,11 @@ void
270276
inv_close(LargeObjectDesc*obj_desc)
271277
{
272278
Assert(PointerIsValid(obj_desc));
279+
273280
if (obj_desc->snapshot!=SnapshotNow)
274-
UnregisterSnapshot(obj_desc->snapshot);
281+
UnregisterSnapshotFromOwner(obj_desc->snapshot,
282+
TopTransactionResourceOwner);
283+
275284
pfree(obj_desc);
276285
}
277286

‎src/backend/utils/time/snapmgr.c

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* Portions Copyright (c) 1994, Regents of the University of California
2020
*
2121
* IDENTIFICATION
22-
* $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.7 2008/11/25 20:28:29 alvherre Exp $
22+
* $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.8 2008/12/04 14:51:02 alvherre Exp $
2323
*
2424
*-------------------------------------------------------------------------
2525
*/
@@ -136,7 +136,8 @@ GetTransactionSnapshot(void)
136136
*/
137137
if (IsXactIsoLevelSerializable)
138138
{
139-
CurrentSnapshot=RegisterSnapshot(CurrentSnapshot);
139+
CurrentSnapshot=RegisterSnapshotOnOwner(CurrentSnapshot,
140+
TopTransactionResourceOwner);
140141
registered_serializable= true;
141142
}
142143

@@ -345,14 +346,27 @@ ActiveSnapshotSet(void)
345346

346347
/*
347348
* RegisterSnapshot
348-
* Register a snapshot as being in use
349+
* Register a snapshot as being in use by the current resource owner
349350
*
350351
* If InvalidSnapshot is passed, it is not registered.
351352
*/
352353
Snapshot
353354
RegisterSnapshot(Snapshotsnapshot)
354355
{
355-
Snapshotsnap;
356+
if (snapshot==InvalidSnapshot)
357+
returnInvalidSnapshot;
358+
359+
returnRegisterSnapshotOnOwner(snapshot,CurrentResourceOwner);
360+
}
361+
362+
/*
363+
* RegisterSnapshotOnOwner
364+
* As above, but use the specified resource owner
365+
*/
366+
Snapshot
367+
RegisterSnapshotOnOwner(Snapshotsnapshot,ResourceOwnerowner)
368+
{
369+
Snapshotsnap;
356370

357371
if (snapshot==InvalidSnapshot)
358372
returnInvalidSnapshot;
@@ -361,9 +375,9 @@ RegisterSnapshot(Snapshot snapshot)
361375
snap=snapshot->copied ?snapshot :CopySnapshot(snapshot);
362376

363377
/* and tell resowner.c about it */
364-
ResourceOwnerEnlargeSnapshots(CurrentResourceOwner);
378+
ResourceOwnerEnlargeSnapshots(owner);
365379
snap->regd_count++;
366-
ResourceOwnerRememberSnapshot(CurrentResourceOwner,snap);
380+
ResourceOwnerRememberSnapshot(owner,snap);
367381

368382
RegisteredSnapshots++;
369383

@@ -379,14 +393,27 @@ RegisterSnapshot(Snapshot snapshot)
379393
*/
380394
void
381395
UnregisterSnapshot(Snapshotsnapshot)
396+
{
397+
if (snapshot==NULL)
398+
return;
399+
400+
UnregisterSnapshotFromOwner(snapshot,CurrentResourceOwner);
401+
}
402+
403+
/*
404+
* UnregisterSnapshotFromOwner
405+
* As above, but use the specified resource owner
406+
*/
407+
void
408+
UnregisterSnapshotFromOwner(Snapshotsnapshot,ResourceOwnerowner)
382409
{
383410
if (snapshot==NULL)
384411
return;
385412

386413
Assert(snapshot->regd_count>0);
387414
Assert(RegisteredSnapshots>0);
388415

389-
ResourceOwnerForgetSnapshot(CurrentResourceOwner,snapshot);
416+
ResourceOwnerForgetSnapshot(owner,snapshot);
390417
RegisteredSnapshots--;
391418
if (--snapshot->regd_count==0&&snapshot->active_count==0)
392419
{
@@ -463,6 +490,26 @@ AtSubAbort_Snapshot(int level)
463490
SnapshotResetXmin();
464491
}
465492

493+
/*
494+
* AtEarlyCommit_Snapshot
495+
*
496+
* Snapshot manager's cleanup function, to be called on commit, before
497+
* doing resowner.c resource release.
498+
*/
499+
void
500+
AtEarlyCommit_Snapshot(void)
501+
{
502+
/*
503+
* On a serializable transaction we must unregister our private refcount to
504+
* the serializable snapshot.
505+
*/
506+
if (registered_serializable)
507+
UnregisterSnapshotFromOwner(CurrentSnapshot,
508+
TopTransactionResourceOwner);
509+
registered_serializable= false;
510+
511+
}
512+
466513
/*
467514
* AtEOXact_Snapshot
468515
* Snapshot manager's cleanup function for end of transaction
@@ -475,13 +522,6 @@ AtEOXact_Snapshot(bool isCommit)
475522
{
476523
ActiveSnapshotElt*active;
477524

478-
/*
479-
* On a serializable snapshot we must first unregister our private
480-
* refcount to the serializable snapshot.
481-
*/
482-
if (registered_serializable)
483-
UnregisterSnapshot(CurrentSnapshot);
484-
485525
if (RegisteredSnapshots!=0)
486526
elog(WARNING,"%d registered snapshots seem to remain after cleanup",
487527
RegisteredSnapshots);

‎src/include/utils/snapmgr.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/utils/snapmgr.h,v 1.2 2008/05/12 20:02:02 alvherre Exp $
9+
* $PostgreSQL: pgsql/src/include/utils/snapmgr.h,v 1.3 2008/12/04 14:51:02 alvherre Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
1313
#ifndefSNAPMGR_H
1414
#defineSNAPMGR_H
1515

16+
#include"utils/resowner.h"
1617
#include"utils/snapshot.h"
1718

1819

@@ -34,9 +35,12 @@ extern bool ActiveSnapshotSet(void);
3435

3536
externSnapshotRegisterSnapshot(Snapshotsnapshot);
3637
externvoidUnregisterSnapshot(Snapshotsnapshot);
38+
externSnapshotRegisterSnapshotOnOwner(Snapshotsnapshot,ResourceOwnerowner);
39+
externvoidUnregisterSnapshotFromOwner(Snapshotsnapshot,ResourceOwnerowner);
3740

3841
externvoidAtSubCommit_Snapshot(intlevel);
3942
externvoidAtSubAbort_Snapshot(intlevel);
43+
externvoidAtEarlyCommit_Snapshot(void);
4044
externvoidAtEOXact_Snapshot(boolisCommit);
4145

4246
#endif/* SNAPMGR_H */

‎src/test/regress/input/largeobject.source

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ SELECT lo_close(fd) FROM lotest_stash_values;
8383

8484
END;
8585

86+
-- Test resource management
87+
BEGIN;
88+
SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
89+
ABORT;
90+
8691
-- Test truncation.
8792
BEGIN;
8893
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));

‎src/test/regress/output/largeobject.source

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ SELECT lo_close(fd) FROM lotest_stash_values;
116116
(1 row)
117117

118118
END;
119+
-- Test resource management
120+
BEGIN;
121+
SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
122+
lo_open
123+
---------
124+
0
125+
(1 row)
126+
127+
ABORT;
119128
-- Test truncation.
120129
BEGIN;
121130
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));

‎src/test/regress/output/largeobject_1.source

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ SELECT lo_close(fd) FROM lotest_stash_values;
116116
(1 row)
117117

118118
END;
119+
-- Test resource management
120+
BEGIN;
121+
SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
122+
lo_open
123+
---------
124+
0
125+
(1 row)
126+
127+
ABORT;
119128
-- Test truncation.
120129
BEGIN;
121130
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp