mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	When performing a base backup, check for read errors.
The old code didn't differentiate between a read error and a concurrent truncation. fread reports both of these by returning 0; you have to use feof() or ferror() to distinguish between them, which this code did not do. It might be a better idea to use read() rather than fread() here, so that we can display a less-generic error message, but I'm not sure that would qualify as a back-patchable bug fix, so just do this much for now. Jeevan Chalke, reviewed by Jeevan Ladhe and by me. Discussion: http://postgr.es/m/CA+TgmobG4ywMzL5oQq2a8YKp8x2p3p1LOMMcGqpS7aekT9+ETA@mail.gmail.com
This commit is contained in:
		@@ -85,6 +85,18 @@ static char *statrelpath = NULL;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
#define THROTTLING_FREQUENCY	8
 | 
					#define THROTTLING_FREQUENCY	8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Checks whether we encountered any error in fread().  fread() doesn't give
 | 
				
			||||||
 | 
					 * any clue what has happened, so we check with ferror().  Also, neither
 | 
				
			||||||
 | 
					 * fread() nor ferror() set errno, so we just throw a generic error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define CHECK_FREAD_ERROR(fp, filename) \
 | 
				
			||||||
 | 
					do { \
 | 
				
			||||||
 | 
						if (ferror(fp)) \
 | 
				
			||||||
 | 
							ereport(ERROR, \
 | 
				
			||||||
 | 
									(errmsg("could not read from file \"%s\"", filename))); \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The actual number of bytes, transfer of which may cause sleep. */
 | 
					/* The actual number of bytes, transfer of which may cause sleep. */
 | 
				
			||||||
static uint64 throttling_sample;
 | 
					static uint64 throttling_sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -509,6 +521,8 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
 | 
				
			|||||||
					break;
 | 
										break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								CHECK_FREAD_ERROR(fp, pathbuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (len != XLogSegSize)
 | 
								if (len != XLogSegSize)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				CheckXLogRemoved(segno, tli);
 | 
									CheckXLogRemoved(segno, tli);
 | 
				
			||||||
@@ -1245,6 +1259,8 @@ sendFile(char *readfilename, char *tarfilename, struct stat *statbuf,
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CHECK_FREAD_ERROR(fp, readfilename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If the file was truncated while we were sending it, pad it with zeros */
 | 
						/* If the file was truncated while we were sending it, pad it with zeros */
 | 
				
			||||||
	if (len < statbuf->st_size)
 | 
						if (len < statbuf->st_size)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user