mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Fix parallel vacuum buffer usage reporting.
A parallel worker's buffer usage is accumulated to its pgBufferUsage
and then is accumulated into the leader's one at the end of the
parallel vacuum. However, since the leader process used to use
dedicated VacuumPage{Hit, Miss, Dirty} globals for the buffer usage
reporting, the worker's buffer usage was not included, leading to an
incorrect buffer usage report.
To fix the problem, this commit makes vacuum use pgBufferUsage
instruments for buffer usage reporting instead of VacuumPage{Hit,
Miss, Dirty} globals. These global variables are still used by ANALYZE
command and autoanalyze.
This also fixes the buffer usage report of vacuuming on temporary
tables, since the buffers dirtied by MarkLocalBufferDirty() were not
tracked by the VacuumPageDirty variable.
Parallel vacuum was introduced in 13, but the buffer usage reporting
for VACUUM command with the VERBOSE option was implemented in
15. So backpatch to 15.
Reported-by: Anthonin Bonnefoy
Author: Anthonin Bonnefoy
Reviewed-by: Alena Rybakina, Masahiko Sawada
Discussion: https://postgr.es/m/CAO6_XqrQk+QZQcYs_C6nk0cMfHuUWk85vT9CrcA1NffFbAVE2A@mail.gmail.com
Backpatch-through: 15
			
			
This commit is contained in:
		@@ -317,9 +317,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 | 
				
			|||||||
	PgStat_Counter startreadtime = 0,
 | 
						PgStat_Counter startreadtime = 0,
 | 
				
			||||||
				startwritetime = 0;
 | 
									startwritetime = 0;
 | 
				
			||||||
	WalUsage	startwalusage = pgWalUsage;
 | 
						WalUsage	startwalusage = pgWalUsage;
 | 
				
			||||||
	int64		StartPageHit = VacuumPageHit,
 | 
						BufferUsage startbufferusage = pgBufferUsage;
 | 
				
			||||||
				StartPageMiss = VacuumPageMiss,
 | 
					 | 
				
			||||||
				StartPageDirty = VacuumPageDirty;
 | 
					 | 
				
			||||||
	ErrorContextCallback errcallback;
 | 
						ErrorContextCallback errcallback;
 | 
				
			||||||
	char	  **indnames = NULL;
 | 
						char	  **indnames = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -611,18 +609,18 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 | 
				
			|||||||
			long		secs_dur;
 | 
								long		secs_dur;
 | 
				
			||||||
			int			usecs_dur;
 | 
								int			usecs_dur;
 | 
				
			||||||
			WalUsage	walusage;
 | 
								WalUsage	walusage;
 | 
				
			||||||
 | 
								BufferUsage bufferusage;
 | 
				
			||||||
			StringInfoData buf;
 | 
								StringInfoData buf;
 | 
				
			||||||
			char	   *msgfmt;
 | 
								char	   *msgfmt;
 | 
				
			||||||
			int32		diff;
 | 
								int32		diff;
 | 
				
			||||||
			int64		PageHitOp = VacuumPageHit - StartPageHit,
 | 
					 | 
				
			||||||
						PageMissOp = VacuumPageMiss - StartPageMiss,
 | 
					 | 
				
			||||||
						PageDirtyOp = VacuumPageDirty - StartPageDirty;
 | 
					 | 
				
			||||||
			double		read_rate = 0,
 | 
								double		read_rate = 0,
 | 
				
			||||||
						write_rate = 0;
 | 
											write_rate = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			TimestampDifference(starttime, endtime, &secs_dur, &usecs_dur);
 | 
								TimestampDifference(starttime, endtime, &secs_dur, &usecs_dur);
 | 
				
			||||||
			memset(&walusage, 0, sizeof(WalUsage));
 | 
								memset(&walusage, 0, sizeof(WalUsage));
 | 
				
			||||||
			WalUsageAccumDiff(&walusage, &pgWalUsage, &startwalusage);
 | 
								WalUsageAccumDiff(&walusage, &pgWalUsage, &startwalusage);
 | 
				
			||||||
 | 
								memset(&bufferusage, 0, sizeof(BufferUsage));
 | 
				
			||||||
 | 
								BufferUsageAccumDiff(&bufferusage, &pgBufferUsage, &startbufferusage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			initStringInfo(&buf);
 | 
								initStringInfo(&buf);
 | 
				
			||||||
			if (verbose)
 | 
								if (verbose)
 | 
				
			||||||
@@ -749,18 +747,18 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			if (secs_dur > 0 || usecs_dur > 0)
 | 
								if (secs_dur > 0 || usecs_dur > 0)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				read_rate = (double) BLCKSZ * PageMissOp / (1024 * 1024) /
 | 
									read_rate = (double) BLCKSZ * (bufferusage.shared_blks_read + bufferusage.local_blks_read) /
 | 
				
			||||||
					(secs_dur + usecs_dur / 1000000.0);
 | 
										(1024 * 1024) / (secs_dur + usecs_dur / 1000000.0);
 | 
				
			||||||
				write_rate = (double) BLCKSZ * PageDirtyOp / (1024 * 1024) /
 | 
									write_rate = (double) BLCKSZ * (bufferusage.shared_blks_dirtied + bufferusage.local_blks_dirtied) /
 | 
				
			||||||
					(secs_dur + usecs_dur / 1000000.0);
 | 
										(1024 * 1024) / (secs_dur + usecs_dur / 1000000.0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			appendStringInfo(&buf, _("avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n"),
 | 
								appendStringInfo(&buf, _("avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n"),
 | 
				
			||||||
							 read_rate, write_rate);
 | 
												 read_rate, write_rate);
 | 
				
			||||||
			appendStringInfo(&buf,
 | 
								appendStringInfo(&buf,
 | 
				
			||||||
							 _("buffer usage: %lld hits, %lld misses, %lld dirtied\n"),
 | 
												 _("buffer usage: %lld hits, %lld misses, %lld dirtied\n"),
 | 
				
			||||||
							 (long long) PageHitOp,
 | 
												 (long long) (bufferusage.shared_blks_hit + bufferusage.local_blks_hit),
 | 
				
			||||||
							 (long long) PageMissOp,
 | 
												 (long long) (bufferusage.shared_blks_read + bufferusage.local_blks_read),
 | 
				
			||||||
							 (long long) PageDirtyOp);
 | 
												 (long long) (bufferusage.shared_blks_dirtied + bufferusage.local_blks_dirtied));
 | 
				
			||||||
			appendStringInfo(&buf,
 | 
								appendStringInfo(&buf,
 | 
				
			||||||
							 _("WAL usage: %lld records, %lld full page images, %llu bytes\n"),
 | 
												 _("WAL usage: %lld records, %lld full page images, %llu bytes\n"),
 | 
				
			||||||
							 (long long) walusage.wal_records,
 | 
												 (long long) walusage.wal_records,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user