mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Don't forget about failed fsync() requests.
If fsync() fails, md.c must keep the request in its bitmap, so that future attempts will try again. Back-patch to all supported releases. Author: Thomas Munro Reviewed-by: Amit Kapila Reported-by: Andrew Gierth Discussion: https://postgr.es/m/87y3i1ia4w.fsf%40news-spur.riddles.org.uk
This commit is contained in:
		@@ -1151,10 +1151,8 @@ mdsync(void)
 | 
				
			|||||||
		 * The bitmap manipulations are slightly tricky, because we can call
 | 
							 * The bitmap manipulations are slightly tricky, because we can call
 | 
				
			||||||
		 * AbsorbFsyncRequests() inside the loop and that could result in
 | 
							 * AbsorbFsyncRequests() inside the loop and that could result in
 | 
				
			||||||
		 * bms_add_member() modifying and even re-palloc'ing the bitmapsets.
 | 
							 * bms_add_member() modifying and even re-palloc'ing the bitmapsets.
 | 
				
			||||||
		 * This is okay because we unlink each bitmapset from the hashtable
 | 
							 * So we detach it, but if we fail we'll merge it with any new
 | 
				
			||||||
		 * entry before scanning it.  That means that any incoming fsync
 | 
							 * requests that have arrived in the meantime.
 | 
				
			||||||
		 * requests will be processed now if they reach the table before we
 | 
					 | 
				
			||||||
		 * begin to scan their fork.
 | 
					 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
 | 
							for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -1164,7 +1162,8 @@ mdsync(void)
 | 
				
			|||||||
			entry->requests[forknum] = NULL;
 | 
								entry->requests[forknum] = NULL;
 | 
				
			||||||
			entry->canceled[forknum] = false;
 | 
								entry->canceled[forknum] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			while ((segno = bms_first_member(requests)) >= 0)
 | 
								segno = -1;
 | 
				
			||||||
 | 
								while ((segno = bms_next_member(requests, segno)) >= 0)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				int			failures;
 | 
									int			failures;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1245,6 +1244,7 @@ mdsync(void)
 | 
				
			|||||||
							longest = elapsed;
 | 
												longest = elapsed;
 | 
				
			||||||
						total_elapsed += elapsed;
 | 
											total_elapsed += elapsed;
 | 
				
			||||||
						processed++;
 | 
											processed++;
 | 
				
			||||||
 | 
											requests = bms_del_member(requests, segno);
 | 
				
			||||||
						if (log_checkpoints)
 | 
											if (log_checkpoints)
 | 
				
			||||||
							elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec",
 | 
												elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec",
 | 
				
			||||||
								 processed,
 | 
													 processed,
 | 
				
			||||||
@@ -1273,10 +1273,23 @@ mdsync(void)
 | 
				
			|||||||
					 */
 | 
										 */
 | 
				
			||||||
					if (!FILE_POSSIBLY_DELETED(errno) ||
 | 
										if (!FILE_POSSIBLY_DELETED(errno) ||
 | 
				
			||||||
						failures > 0)
 | 
											failures > 0)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											Bitmapset  *new_requests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											/*
 | 
				
			||||||
 | 
											 * We need to merge these unsatisfied requests with
 | 
				
			||||||
 | 
											 * any others that have arrived since we started.
 | 
				
			||||||
 | 
											 */
 | 
				
			||||||
 | 
											new_requests = entry->requests[forknum];
 | 
				
			||||||
 | 
											entry->requests[forknum] =
 | 
				
			||||||
 | 
												bms_join(new_requests, requests);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											errno = save_errno;
 | 
				
			||||||
						ereport(ERROR,
 | 
											ereport(ERROR,
 | 
				
			||||||
								(errcode_for_file_access(),
 | 
													(errcode_for_file_access(),
 | 
				
			||||||
								 errmsg("could not fsync file \"%s\": %m",
 | 
													 errmsg("could not fsync file \"%s\": %m",
 | 
				
			||||||
										path)));
 | 
															path)));
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
						ereport(DEBUG1,
 | 
											ereport(DEBUG1,
 | 
				
			||||||
								(errcode_for_file_access(),
 | 
													(errcode_for_file_access(),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user