mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Fix theoretical torn page hazard.
The original report was concerned with a possible inconsistency between the heap and the visibility map, which I was unable to confirm. The concern has been retracted. However, there did seem to be a torn page hazard when using checksums. By not setting the heap page LSN during redo, the protections of minRecoveryPoint were bypassed. Fixed, along with a misleading comment. It may have been impossible to hit this problem in practice, because it would require a page tear between the checksum and the flags, so I am marking this as a theoretical risk. But, as discussed, it did violate expectations about the page LSN, so it may have other consequences. Backpatch to all supported versions. Reported-by: Konstantin Knizhnik Reviewed-by: Konstantin Knizhnik Discussion: https://postgr.es/m/fed17dac-8cb8-4f5b-d462-1bb4908c029e@garret.ru Backpatch-through: 11
This commit is contained in:
		@@ -7956,8 +7956,7 @@ heap_xlog_visible(XLogReaderState *record)
 | 
				
			|||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * We don't bump the LSN of the heap page when setting the visibility
 | 
							 * We don't bump the LSN of the heap page when setting the visibility
 | 
				
			||||||
		 * map bit (unless checksums or wal_hint_bits is enabled, in which
 | 
							 * map bit (unless checksums or wal_hint_bits is enabled, in which
 | 
				
			||||||
		 * case we must), because that would generate an unworkable volume of
 | 
							 * case we must). This exposes us to torn page hazards, but since
 | 
				
			||||||
		 * full-page writes.  This exposes us to torn page hazards, but since
 | 
					 | 
				
			||||||
		 * we're not inspecting the existing page contents in any way, we
 | 
							 * we're not inspecting the existing page contents in any way, we
 | 
				
			||||||
		 * don't care.
 | 
							 * don't care.
 | 
				
			||||||
		 *
 | 
							 *
 | 
				
			||||||
@@ -7971,6 +7970,9 @@ heap_xlog_visible(XLogReaderState *record)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		PageSetAllVisible(page);
 | 
							PageSetAllVisible(page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (XLogHintBitIsNeeded())
 | 
				
			||||||
 | 
								PageSetLSN(page, lsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		MarkBufferDirty(buffer);
 | 
							MarkBufferDirty(buffer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (action == BLK_RESTORED)
 | 
						else if (action == BLK_RESTORED)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user