mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-28 11:55:03 +03:00 
			
		
		
		
	Inline initial comparisons in TestForOldSnapshot()
Even with old_snapshot_threshold = -1 (which disables the "snapshot too old" feature), performance regressions were seen at moderate to high concurrency. For example, a one-socket, four-core system running 200 connections at saturation could see up to a 2.3% regression, with larger regressions possible on NUMA machines. By inlining the early (smaller, faster) tests in the TestForOldSnapshot() function, the i7 case dropped to a 0.2% regression, which could easily just be noise, and is clearly an improvement. Further testing will show whether more is needed.
This commit is contained in:
		| @@ -4282,33 +4282,15 @@ IssuePendingWritebacks(WritebackContext *context) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Check whether the given snapshot is too old to have safely read the given | ||||
|  * page from the given table.  If so, throw a "snapshot too old" error. | ||||
|  * Implement slower/larger portions of TestForOldSnapshot | ||||
|  * | ||||
|  * This test generally needs to be performed after every BufferGetPage() call | ||||
|  * that is executed as part of a scan.  It is not needed for calls made for | ||||
|  * modifying the page (for example, to position to the right place to insert a | ||||
|  * new index tuple or for vacuuming).  It may also be omitted where calls to | ||||
|  * lower-level functions will have already performed the test. | ||||
|  * | ||||
|  * Note that a NULL snapshot argument is allowed and causes a fast return | ||||
|  * without error; this is to support call sites which can be called from | ||||
|  * either scans or index modification areas. | ||||
|  * | ||||
|  * For best performance, keep the tests that are fastest and/or most likely to | ||||
|  * exclude a page from old snapshot testing near the front. | ||||
|  * Smaller/faster portions are put inline, but the entire set of logic is too | ||||
|  * big for that. | ||||
|  */ | ||||
| void | ||||
| TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page) | ||||
| TestForOldSnapshot_impl(Snapshot snapshot, Relation relation) | ||||
| { | ||||
| 	Assert(relation != NULL); | ||||
|  | ||||
| 	if (old_snapshot_threshold >= 0 | ||||
| 	 && (snapshot) != NULL | ||||
| 	 && (snapshot)->satisfies == HeapTupleSatisfiesMVCC | ||||
| 	 && !XLogRecPtrIsInvalid((snapshot)->lsn) | ||||
| 	 && PageGetLSN(page) > (snapshot)->lsn | ||||
| 	 && !IsCatalogRelation(relation) | ||||
| 	if (!IsCatalogRelation(relation) | ||||
| 	 && !RelationIsAccessibleInLogicalDecoding(relation) | ||||
| 	 && (snapshot)->whenTaken < GetOldSnapshotThresholdTimestamp()) | ||||
| 		ereport(ERROR, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user