find-overlap-snapshotnow.patch

text/plain

Filename: find-overlap-snapshotnow.patch
Type: text/plain
Part: 0
Message: Re: ALTER TABLE lock strength reduction patch is unsafe

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
src/backend/access/heap/heapam.c 8 0
src/backend/access/index/indexam.c 4 0
src/backend/utils/time/snapmgr.c 25 0
src/backend/utils/time/tqual.c 3 1
src/include/utils/snapmgr.h 2 0
src/include/utils/tqual.h 2 0
*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
***************
*** 1201,1206 **** heap_beginscan_internal(Relation relation, Snapshot snapshot,
--- 1201,1208 ----
  	 */
  	scan->rs_pageatatime = IsMVCCSnapshot(snapshot);
  
+ 	InitSnapshotNowIfNeeded(snapshot);
+ 
  	/*
  	 * For a seqscan in a serializable transaction, acquire a predicate lock
  	 * on the entire relation. This is required not only to lock all the
***************
*** 1270,1275 **** heap_endscan(HeapScanDesc scan)
--- 1272,1279 ----
  	if (BufferIsValid(scan->rs_cbuf))
  		ReleaseBuffer(scan->rs_cbuf);
  
+ 	FinishSnapshotNow(scan->rs_snapshot);
+ 
  	/*
  	 * decrement relation reference count and free scan descriptor storage
  	 */
***************
*** 1680,1685 **** heap_get_latest_tid(Relation relation,
--- 1684,1691 ----
  	if (!ItemPointerIsValid(tid))
  		return;
  
+ 	InitSnapshotNowIfNeeded(snapshot);
+ 
  	/*
  	 * Since this can be called with user-supplied TID, don't trust the input
  	 * too much.  (RelationGetNumberOfBlocks is an expensive check, so we
***************
*** 1775,1780 **** heap_get_latest_tid(Relation relation,
--- 1781,1788 ----
  		priorXmax = HeapTupleHeaderGetXmax(tp.t_data);
  		UnlockReleaseBuffer(buffer);
  	}							/* end of loop */
+ 
+ 	FinishSnapshotNow(snapshot);
  }
  
  
*** a/src/backend/access/index/indexam.c
--- b/src/backend/access/index/indexam.c
***************
*** 292,297 **** index_beginscan_internal(Relation indexRelation,
--- 292,299 ----
  	 */
  	RelationIncrementReferenceCount(indexRelation);
  
+ 	InitSnapshotNowIfNeeded(snapshot);
+ 
  	/*
  	 * Tell the AM to open a scan.
  	 */
***************
*** 370,375 **** index_endscan(IndexScanDesc scan)
--- 372,379 ----
  	/* End the AM's scan */
  	FunctionCall1(procedure, PointerGetDatum(scan));
  
+ 	FinishSnapshotNow(scan->xs_snapshot);
+ 
  	/* Release index refcount acquired by index_beginscan */
  	RelationDecrementReferenceCount(scan->indexRelation);
  
*** a/src/backend/utils/time/snapmgr.c
--- b/src/backend/utils/time/snapmgr.c
***************
*** 205,210 **** GetLatestSnapshot(void)
--- 205,235 ----
  	return SecondarySnapshot;
  }
  
+ static bool SnapshotNowActive;
+ 
+ /*
+  * InitSnapshotNowIfNeeded
+  *		If passed snapshot is SnapshotNow then refresh it with latest info.
+  */
+ void
+ InitSnapshotNowIfNeeded(Snapshot snap)
+ {
+ 	if (!IsSnapshotNow(snap))
+ 		return;
+ 
+ 	if (SnapshotNowActive)
+ 		elog(WARNING, "SnapshotNow used concurrently");
+ 
+ 	snap = GetSnapshotData(&SnapshotNowData);
+ 	SnapshotNowActive = true;
+ }
+ 
+ void FinishSnapshotNow(Snapshot snap)
+ {
+ 	if (IsSnapshotNow(snap))
+ 		SnapshotNowActive = false;
+ }
+ 
  /*
   * SnapshotSetCommandId
   *		Propagate CommandCounterIncrement into the static snapshots, if set
*** a/src/backend/utils/time/tqual.c
--- b/src/backend/utils/time/tqual.c
***************
*** 67,73 ****
  
  
  /* Static variables representing various special snapshot semantics */
! SnapshotData SnapshotNowData = {HeapTupleSatisfiesNow};
  SnapshotData SnapshotSelfData = {HeapTupleSatisfiesSelf};
  SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny};
  SnapshotData SnapshotToastData = {HeapTupleSatisfiesToast};
--- 67,73 ----
  
  
  /* Static variables representing various special snapshot semantics */
! SnapshotData SnapshotNowData = {HeapTupleSatisfiesMVCC};
  SnapshotData SnapshotSelfData = {HeapTupleSatisfiesSelf};
  SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny};
  SnapshotData SnapshotToastData = {HeapTupleSatisfiesToast};
***************
*** 293,298 **** HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
--- 293,299 ----
  	return false;
  }
  
+ #ifdef RECENTLY_DEAD_CODE
  /*
   * HeapTupleSatisfiesNow
   *		True iff heap tuple is valid "now".
***************
*** 474,479 **** HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
--- 475,481 ----
  				HeapTupleHeaderGetXmax(tuple));
  	return false;
  }
+ #endif
  
  /*
   * HeapTupleSatisfiesAny
*** a/src/include/utils/snapmgr.h
--- b/src/include/utils/snapmgr.h
***************
*** 24,29 **** extern TransactionId RecentGlobalXmin;
--- 24,31 ----
  
  extern Snapshot GetTransactionSnapshot(void);
  extern Snapshot GetLatestSnapshot(void);
+ extern void InitSnapshotNowIfNeeded(Snapshot snap);
+ extern void FinishSnapshotNow(Snapshot snap);
  extern void SnapshotSetCommandId(CommandId curcid);
  
  extern void PushActiveSnapshot(Snapshot snapshot);
*** a/src/include/utils/tqual.h
--- b/src/include/utils/tqual.h
***************
*** 40,45 **** extern PGDLLIMPORT SnapshotData SnapshotToastData;
--- 40,47 ----
  /* This macro encodes the knowledge of which snapshots are MVCC-safe */
  #define IsMVCCSnapshot(snapshot)  \
  	((snapshot)->satisfies == HeapTupleSatisfiesMVCC)
+ #define IsSnapshotNow(snapshot)  \
+ 	((snapshot) == (&SnapshotNowData))
  
  /*
   * HeapTupleSatisfiesVisibility