Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4d82750

Browse files
committed
Remove remants of "snapshot too old"
Remove the 'whenTaken' and 'lsn' fields from SnapshotData. After the removal of the "snapshot too old" feature, they were never set to a non-zero value. This largely reverts commit 3e2f3c2, which added the OldestActiveSnapshot tracking, and the init_toast_snapshot() function. That was only required for setting the 'whenTaken' and 'lsn' fields. SnapshotToast is now a constant again, like SnapshotSelf and SnapshotAny. I kept a thin get_toast_snapshot() wrapper around SnapshotToast though, to check that you have a registered or active snapshot. That's still a useful sanity check. Reviewed-by: Nathan Bossart, Andres Freund, Tom Lane Discussion: https://www.postgresql.org/message-id/cd4b4f8c-e63a-41c0-95f6-6e6cd9b83f6d@iki.fi
1 parent f64ec81 commit 4d82750

File tree

10 files changed

+28
-114
lines changed

10 files changed

+28
-114
lines changed

contrib/amcheck/verify_heapam.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,6 @@ check_tuple_attribute(HeapCheckContext *ctx)
17671767
static void
17681768
check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
17691769
{
1770-
SnapshotData SnapshotToast;
17711770
ScanKeyData toastkey;
17721771
SysScanDesc toastscan;
17731772
bool found_toasttup;
@@ -1791,10 +1790,9 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
17911790
* Check if any chunks for this toasted object exist in the toast table,
17921791
* accessible via the index.
17931792
*/
1794-
init_toast_snapshot(&SnapshotToast);
17951793
toastscan = systable_beginscan_ordered(ctx->toast_rel,
17961794
ctx->valid_toast_index,
1797-
&SnapshotToast, 1,
1795+
get_toast_snapshot(), 1,
17981796
&toastkey);
17991797
found_toasttup = false;
18001798
while ((toasttup =

src/backend/access/common/toast_internals.c

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,6 @@ toast_delete_datum(Relation rel, Datum value, bool is_speculative)
393393
HeapTuple toasttup;
394394
int num_indexes;
395395
int validIndex;
396-
SnapshotData SnapshotToast;
397396

398397
if (!VARATT_IS_EXTERNAL_ONDISK(attr))
399398
return;
@@ -425,9 +424,8 @@ toast_delete_datum(Relation rel, Datum value, bool is_speculative)
425424
* sequence or not, but since we've already locked the index we might as
426425
* well use systable_beginscan_ordered.)
427426
*/
428-
init_toast_snapshot(&SnapshotToast);
429427
toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex],
430-
&SnapshotToast, 1, &toastkey);
428+
get_toast_snapshot(), 1, &toastkey);
431429
while ((toasttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
432430
{
433431
/*
@@ -631,41 +629,28 @@ toast_close_indexes(Relation *toastidxs, int num_indexes, LOCKMODE lock)
631629
}
632630

633631
/* ----------
634-
* init_toast_snapshot
632+
* get_toast_snapshot
635633
*
636-
* Initialize an appropriate TOAST snapshot. We must use an MVCC snapshot
637-
* to initialize the TOAST snapshot; since we don't know which one to use,
638-
* just use the oldest one.
634+
* Return the TOAST snapshot. Detoasting *must* happen in the same
635+
* transaction that originally fetched the toast pointer.
639636
*/
640-
void
641-
init_toast_snapshot(Snapshot toast_snapshot)
637+
Snapshot
638+
get_toast_snapshot(void)
642639
{
643-
Snapshot snapshot = GetOldestSnapshot();
644-
645640
/*
646-
* GetOldestSnapshot returns NULL if the session has no active snapshots.
647-
* We can get that if, for example, a procedure fetches a toasted value
648-
* into a local variable, commits, and then tries to detoast the value.
649-
* Such coding is unsafe, because once we commit there is nothing to
650-
* prevent the toast data from being deleted. Detoasting *must* happen in
651-
* the same transaction that originally fetched the toast pointer. Hence,
652-
* rather than trying to band-aid over the problem, throw an error. (This
653-
* is not very much protection, because in many scenarios the procedure
654-
* would have already created a new transaction snapshot, preventing us
655-
* from detecting the problem. But it's better than nothing, and for sure
656-
* we shouldn't expend code on masking the problem more.)
641+
* We cannot directly check that detoasting happens in the same
642+
* transaction that originally fetched the toast pointer, but at least
643+
* check that the session has some active snapshots. It might not if, for
644+
* example, a procedure fetches a toasted value into a local variable,
645+
* commits, and then tries to detoast the value. Such coding is unsafe,
646+
* because once we commit there is nothing to prevent the toast data from
647+
* being deleted. (This is not very much protection, because in many
648+
* scenarios the procedure would have already created a new transaction
649+
* snapshot, preventing us from detecting the problem. But it's better
650+
* than nothing.)
657651
*/
658-
if (snapshot == NULL)
652+
if (!HaveRegisteredOrActiveSnapshot())
659653
elog(ERROR, "cannot fetch toast data without an active snapshot");
660654

661-
/*
662-
* Catalog snapshots can be returned by GetOldestSnapshot() even if not
663-
* registered or active. That easily hides bugs around not having a
664-
* snapshot set up - most of the time there is a valid catalog snapshot.
665-
* So additionally insist that the current snapshot is registered or
666-
* active.
667-
*/
668-
Assert(HaveRegisteredOrActiveSnapshot());
669-
670-
InitToastSnapshot(*toast_snapshot, snapshot->lsn, snapshot->whenTaken);
655+
return &SnapshotToastData;
671656
}

src/backend/access/heap/heaptoast.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,6 @@ heap_fetch_toast_slice(Relation toastrel, Oid valueid, int32 attrsize,
639639
int endchunk;
640640
int num_indexes;
641641
int validIndex;
642-
SnapshotData SnapshotToast;
643642

644643
/* Look for the valid index of toast relation */
645644
validIndex = toast_open_indexes(toastrel,
@@ -685,9 +684,8 @@ heap_fetch_toast_slice(Relation toastrel, Oid valueid, int32 attrsize,
685684
}
686685

687686
/* Prepare for scan */
688-
init_toast_snapshot(&SnapshotToast);
689687
toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex],
690-
&SnapshotToast, nscankeys, toastkey);
688+
get_toast_snapshot(), nscankeys, toastkey);
691689

692690
/*
693691
* Read the chunks by index

src/backend/storage/ipc/procarray.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,8 +2135,6 @@ GetSnapshotDataReuse(Snapshot snapshot)
21352135
snapshot->active_count = 0;
21362136
snapshot->regd_count = 0;
21372137
snapshot->copied = false;
2138-
snapshot->lsn = InvalidXLogRecPtr;
2139-
snapshot->whenTaken = 0;
21402138

21412139
return true;
21422140
}
@@ -2516,8 +2514,6 @@ GetSnapshotData(Snapshot snapshot)
25162514
snapshot->active_count = 0;
25172515
snapshot->regd_count = 0;
25182516
snapshot->copied = false;
2519-
snapshot->lsn = InvalidXLogRecPtr;
2520-
snapshot->whenTaken = 0;
25212517

25222518
return snapshot;
25232519
}

src/backend/utils/time/snapmgr.c

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static SnapshotData SecondarySnapshotData = {SNAPSHOT_MVCC};
8383
SnapshotData CatalogSnapshotData = {SNAPSHOT_MVCC};
8484
SnapshotData SnapshotSelfData = {SNAPSHOT_SELF};
8585
SnapshotData SnapshotAnyData = {SNAPSHOT_ANY};
86+
SnapshotData SnapshotToastData = {SNAPSHOT_TOAST};
8687

8788
/* Pointers to valid snapshots */
8889
static Snapshot CurrentSnapshot = NULL;
@@ -119,9 +120,6 @@ typedef struct ActiveSnapshotElt
119120
/* Top of the stack of active snapshots */
120121
static ActiveSnapshotElt *ActiveSnapshot = NULL;
121122

122-
/* Bottom of the stack of active snapshots */
123-
static ActiveSnapshotElt *OldestActiveSnapshot = NULL;
124-
125123
/*
126124
* Currently registered Snapshots. Ordered in a heap by xmin, so that we can
127125
* quickly find the one with lowest xmin, to advance our MyProc->xmin.
@@ -199,8 +197,6 @@ typedef struct SerializedSnapshotData
199197
bool suboverflowed;
200198
bool takenDuringRecovery;
201199
CommandId curcid;
202-
TimestampTz whenTaken;
203-
XLogRecPtr lsn;
204200
} SerializedSnapshotData;
205201

206202
/*
@@ -313,36 +309,6 @@ GetLatestSnapshot(void)
313309
return SecondarySnapshot;
314310
}
315311

316-
/*
317-
* GetOldestSnapshot
318-
*
319-
* Get the transaction's oldest known snapshot, as judged by the LSN.
320-
* Will return NULL if there are no active or registered snapshots.
321-
*/
322-
Snapshot
323-
GetOldestSnapshot(void)
324-
{
325-
Snapshot OldestRegisteredSnapshot = NULL;
326-
XLogRecPtr RegisteredLSN = InvalidXLogRecPtr;
327-
328-
if (!pairingheap_is_empty(&RegisteredSnapshots))
329-
{
330-
OldestRegisteredSnapshot = pairingheap_container(SnapshotData, ph_node,
331-
pairingheap_first(&RegisteredSnapshots));
332-
RegisteredLSN = OldestRegisteredSnapshot->lsn;
333-
}
334-
335-
if (OldestActiveSnapshot != NULL)
336-
{
337-
XLogRecPtr ActiveLSN = OldestActiveSnapshot->as_snap->lsn;
338-
339-
if (XLogRecPtrIsInvalid(RegisteredLSN) || RegisteredLSN > ActiveLSN)
340-
return OldestActiveSnapshot->as_snap;
341-
}
342-
343-
return OldestRegisteredSnapshot;
344-
}
345-
346312
/*
347313
* GetCatalogSnapshot
348314
* Get a snapshot that is sufficiently up-to-date for scan of the
@@ -684,8 +650,6 @@ PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level)
684650
newactive->as_snap->active_count++;
685651

686652
ActiveSnapshot = newactive;
687-
if (OldestActiveSnapshot == NULL)
688-
OldestActiveSnapshot = ActiveSnapshot;
689653
}
690654

691655
/*
@@ -756,8 +720,6 @@ PopActiveSnapshot(void)
756720

757721
pfree(ActiveSnapshot);
758722
ActiveSnapshot = newstack;
759-
if (ActiveSnapshot == NULL)
760-
OldestActiveSnapshot = NULL;
761723

762724
SnapshotResetXmin();
763725
}
@@ -902,13 +864,6 @@ xmin_cmp(const pairingheap_node *a, const pairingheap_node *b, void *arg)
902864
* dropped. For efficiency, we only consider recomputing PGPROC->xmin when
903865
* the active snapshot stack is empty; this allows us not to need to track
904866
* which active snapshot is oldest.
905-
*
906-
* Note: it's tempting to use GetOldestSnapshot() here so that we can include
907-
* active snapshots in the calculation. However, that compares by LSN not
908-
* xmin so it's not entirely clear that it's the same thing. Also, we'd be
909-
* critically dependent on the assumption that the bottommost active snapshot
910-
* stack entry has the oldest xmin. (Current uses of GetOldestSnapshot() are
911-
* not actually critical, but this would be.)
912867
*/
913868
static void
914869
SnapshotResetXmin(void)
@@ -980,8 +935,6 @@ AtSubAbort_Snapshot(int level)
980935
pfree(ActiveSnapshot);
981936

982937
ActiveSnapshot = next;
983-
if (ActiveSnapshot == NULL)
984-
OldestActiveSnapshot = NULL;
985938
}
986939

987940
SnapshotResetXmin();
@@ -1065,7 +1018,6 @@ AtEOXact_Snapshot(bool isCommit, bool resetXmin)
10651018
* it'll go away with TopTransactionContext.
10661019
*/
10671020
ActiveSnapshot = NULL;
1068-
OldestActiveSnapshot = NULL;
10691021
pairingheap_reset(&RegisteredSnapshots);
10701022

10711023
CurrentSnapshot = NULL;
@@ -1727,8 +1679,6 @@ SerializeSnapshot(Snapshot snapshot, char *start_address)
17271679
serialized_snapshot.suboverflowed = snapshot->suboverflowed;
17281680
serialized_snapshot.takenDuringRecovery = snapshot->takenDuringRecovery;
17291681
serialized_snapshot.curcid = snapshot->curcid;
1730-
serialized_snapshot.whenTaken = snapshot->whenTaken;
1731-
serialized_snapshot.lsn = snapshot->lsn;
17321682

17331683
/*
17341684
* Ignore the SubXID array if it has overflowed, unless the snapshot was
@@ -1801,8 +1751,6 @@ RestoreSnapshot(char *start_address)
18011751
snapshot->suboverflowed = serialized_snapshot.suboverflowed;
18021752
snapshot->takenDuringRecovery = serialized_snapshot.takenDuringRecovery;
18031753
snapshot->curcid = serialized_snapshot.curcid;
1804-
snapshot->whenTaken = serialized_snapshot.whenTaken;
1805-
snapshot->lsn = serialized_snapshot.lsn;
18061754
snapshot->snapXactCompletionCount = 0;
18071755

18081756
/* Copy XIDs, if present. */

src/include/access/genam.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
#ifndef GENAM_H
1515
#define GENAM_H
1616

17+
#include "access/htup.h"
1718
#include "access/sdir.h"
1819
#include "access/skey.h"
1920
#include "nodes/tidbitmap.h"
21+
#include "storage/buf.h"
2022
#include "storage/lockdefs.h"
2123
#include "utils/relcache.h"
2224
#include "utils/snapshot.h"

src/include/access/toast_internals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ extern int toast_open_indexes(Relation toastrel,
5858
int *num_indexes);
5959
extern void toast_close_indexes(Relation *toastidxs, int num_indexes,
6060
LOCKMODE lock);
61-
extern void init_toast_snapshot(Snapshot toast_snapshot);
61+
extern Snapshot get_toast_snapshot(void);
6262

6363
#endif /* TOAST_INTERNALS_H */

src/include/storage/predicate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef PREDICATE_H
1515
#define PREDICATE_H
1616

17+
#include "storage/itemptr.h"
1718
#include "storage/lock.h"
1819
#include "utils/relcache.h"
1920
#include "utils/snapshot.h"

src/include/utils/snapmgr.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ extern PGDLLIMPORT TransactionId RecentXmin;
2727
/* Variables representing various special snapshot semantics */
2828
extern PGDLLIMPORT SnapshotData SnapshotSelfData;
2929
extern PGDLLIMPORT SnapshotData SnapshotAnyData;
30+
extern PGDLLIMPORT SnapshotData SnapshotToastData;
3031
extern PGDLLIMPORT SnapshotData CatalogSnapshotData;
3132

3233
#define SnapshotSelf (&SnapshotSelfData)
3334
#define SnapshotAny (&SnapshotAnyData)
3435

36+
/* Use get_toast_snapshot() for the TOAST snapshot */
37+
3538
/*
3639
* We don't provide a static SnapshotDirty variable because it would be
3740
* non-reentrant. Instead, users of that snapshot type should declare a
@@ -49,15 +52,6 @@ extern PGDLLIMPORT SnapshotData CatalogSnapshotData;
4952
((snapshotdata).snapshot_type = SNAPSHOT_NON_VACUUMABLE, \
5053
(snapshotdata).vistest = (vistestp))
5154

52-
/*
53-
* Similarly, some initialization is required for SnapshotToast. We need
54-
* to set lsn and whenTaken correctly to support snapshot_too_old.
55-
*/
56-
#define InitToastSnapshot(snapshotdata, l, w) \
57-
((snapshotdata).snapshot_type = SNAPSHOT_TOAST, \
58-
(snapshotdata).lsn = (l), \
59-
(snapshotdata).whenTaken = (w))
60-
6155
/* This macro encodes the knowledge of which snapshots are MVCC-safe */
6256
#define IsMVCCSnapshot(snapshot) \
6357
((snapshot)->snapshot_type == SNAPSHOT_MVCC || \
@@ -66,7 +60,6 @@ extern PGDLLIMPORT SnapshotData CatalogSnapshotData;
6660
extern Snapshot GetTransactionSnapshot(void);
6761
extern Snapshot GetLatestSnapshot(void);
6862
extern void SnapshotSetCommandId(CommandId curcid);
69-
extern Snapshot GetOldestSnapshot(void);
7063

7164
extern Snapshot GetCatalogSnapshot(Oid relid);
7265
extern Snapshot GetNonHistoricCatalogSnapshot(Oid relid);

src/include/utils/snapshot.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@
1313
#ifndef SNAPSHOT_H
1414
#define SNAPSHOT_H
1515

16-
#include "access/htup.h"
17-
#include "access/xlogdefs.h"
18-
#include "datatype/timestamp.h"
1916
#include "lib/pairingheap.h"
20-
#include "storage/buf.h"
2117

2218

2319
/*
@@ -205,9 +201,6 @@ typedef struct SnapshotData
205201
uint32 regd_count; /* refcount on RegisteredSnapshots */
206202
pairingheap_node ph_node; /* link in the RegisteredSnapshots heap */
207203

208-
TimestampTz whenTaken; /* timestamp when snapshot was taken */
209-
XLogRecPtr lsn; /* position in the WAL stream when taken */
210-
211204
/*
212205
* The transaction completion count at the time GetSnapshotData() built
213206
* this snapshot. Allows to avoid re-computing static snapshots when no

0 commit comments

Comments
 (0)