Пример #1
0
Файл: fd.c Проект: hellower/gpdb
int
FileSync(File file)
{
	int			returnCode;
	FileRepGpmonRecord_s gpmonRecord;
	FileRepGpmonStatType_e whichStat;

	if (fileRepRole == FileRepPrimaryRole)
	{
			whichStat = FileRepGpmonStatType_PrimaryFsyncSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
	} else 
	{
			whichStat = FileRepGpmonStatType_MirrorFsyncSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
	}
	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileSync: %d (%s)",
			   file, VfdCache[file].fileName));

	returnCode = FileAccess(file);
	if (returnCode < 0)
		return returnCode;

#ifdef FAULT_INJECTOR
	FaultInjector_InjectFaultIfSet(
								   FileRepFlush,
								   DDLNotSpecified,
								   "",	//databaseName
								   ""); // tableName
#endif								
	
	returnCode =  pg_fsync(VfdCache[file].fd);
	
	if (returnCode >= 0)
	{
			//only include stats if successful
			if ((fileRepRole == FileRepPrimaryRole) || 
				(fileRepRole == FileRepMirrorRole))
			{
					FileRepGpmonStat_CloseRecord(whichStat, &gpmonRecord);
			}
	}
	return returnCode;
}
Пример #2
0
Файл: fd.c Проект: hellower/gpdb
int
FileWrite(File file, char *buffer, int amount)
{
	int			returnCode;
	FileRepGpmonRecord_s gpmonRecord;
	FileRepGpmonStatType_e whichStat =0;

	if (fileRepRole == FileRepPrimaryRole)
	{
			whichStat = FileRepGpmonStatType_PrimaryWriteSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
			gpmonRecord.size = amount;

	} else if (fileRepRole == FileRepMirrorRole)
	{
			whichStat = FileRepGpmonStatType_MirrorWriteSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
			gpmonRecord.size = amount;

	}

	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
			   file, VfdCache[file].fileName,
			   VfdCache[file].seekPos, amount, buffer));

	/* Added temporary for troubleshooting */
	if (Debug_filerep_print)
		elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
		 file, VfdCache[file].fileName,
		 VfdCache[file].seekPos, amount, buffer);
	else
		FileRep_InsertLogEntry(
							   "FileWrite",
							   FileRep_GetFlatFileIdentifier(VfdCache[file].fileName, ""),
							   FileRepRelationTypeFlatFile,
							   FileRepOperationWrite,
							   FILEREP_UNDEFINED,
							   FILEREP_UNDEFINED,
							   FileRepAckStateNotInitialized,
							   VfdCache[file].seekPos,
							   amount);

	returnCode = FileAccess(file);
	if (returnCode < 0)
		return returnCode;

#ifdef FAULT_INJECTOR	
	if (! strcmp(VfdCache[file].fileName, "global/pg_control"))
	{
		if (FaultInjector_InjectFaultIfSet(
										   PgControl, 
										   DDLNotSpecified,
										   "" /* databaseName */,
										   "" /* tableName */) == FaultInjectorTypeDataCorruption)
		{
			MemSet(buffer, 0, amount);
		}
	}
	
	if (strstr(VfdCache[file].fileName, "pg_xlog/"))
	{
		if (FaultInjector_InjectFaultIfSet(
										   PgXlog, 
										   DDLNotSpecified,
										   "" /* databaseName */,
										   "" /* tableName */) == FaultInjectorTypeDataCorruption)
		{
			MemSet(buffer, 0, amount);
		}
	}
#endif

retry:
	errno = 0;
	returnCode = write(VfdCache[file].fd, buffer, amount);

	/* if write didn't set errno, assume problem is no disk space */
	if (returnCode != amount && errno == 0)
		errno = ENOSPC;

	if (returnCode >= 0)
		VfdCache[file].seekPos += returnCode;
	else
	{
		/*
		 * See comments in FileRead()
		 */
#ifdef WIN32
		DWORD		error = GetLastError();

		switch (error)
		{
			case ERROR_NO_SYSTEM_RESOURCES:
				pg_usleep(1000L);
				errno = EINTR;
				break;
			default:
				_dosmaperr(error);
				break;
		}
#endif
		/* OK to retry if interrupted */
		if (errno == EINTR)
			goto retry;

		/* Trouble, so assume we don't know the file position anymore */
		VfdCache[file].seekPos = FileUnknownPos;
	}

	if (returnCode >= 0)
	{
		//only include stat if successful
		if ((fileRepRole == FileRepPrimaryRole) ||
			(fileRepRole == FileRepMirrorRole))
		{
			FileRepGpmonStat_CloseRecord(whichStat, &gpmonRecord);
		}
	}
	return returnCode;
}
Пример #3
0
/*
 * Flush a flat file.
 *
 */
bool MirroredBufferPool_Flush(
	MirroredBufferPoolOpen *open)
				/* The open struct. */	

{
	int primaryError;
	FileRepGpmonRecord_s gpmonRecord;

	Assert(open != NULL);
	Assert(open->isActive);

	primaryError = 0;
	
	/*
	 * For Buffer Pool managed, we are normally not session oriented like Append-Only.
	 *
	 * Figure out mirroring each time...
	 */		
	MirroredBufferPool_RecheckMirrorAccess(open);

	if (StorageManagerMirrorMode_SendToMirror(open->mirrorMode) &&
		!open->mirrorDataLossOccurred)
	{
	    if (fileRepRole == FileRepPrimaryRole) 
		{
				FileRepGpmonStat_OpenRecord(
						FileRepGpmonStatType_PrimaryRoundtripFsyncMsg, 
						&gpmonRecord);
		}
		if (FileRepPrimary_MirrorFlush(
										FileRep_GetRelationIdentifier(
																	  open->mirrorFilespaceLocation,
																	  open->relFileNode, 
																	  open->segmentFileNum),
										FileRepRelationTypeBufferPool) != 0) 
		{
			if (Debug_filerep_print)
				ereport(LOG,
					(errmsg("could not sent file fsync request to mirror "), 
							FileRep_ReportRelationPath(
													   open->mirrorFilespaceLocation,
													   open->relFileNode,
													   open->segmentFileNum)));
		}
		
		open->mirrorDataLossOccurred =  FileRepPrimary_IsMirrorDataLossOccurred();
	}
	
	if (StorageManagerMirrorMode_DoPrimaryWork(open->mirrorMode) &&
		! FileRepResyncWorker_IsResyncRequest())	
	{
		errno = 0;

		if (FileSync(open->primaryFile) < 0) 
			primaryError = errno;
	}

	if (StorageManagerMirrorMode_SendToMirror(open->mirrorMode) &&
		!open->mirrorDataLossOccurred)
	{
		if (FileRepPrimary_IsOperationCompleted(
						FileRep_GetRelationIdentifier(
													  open->mirrorFilespaceLocation,
													  open->relFileNode, 
													  open->segmentFileNum),									
						FileRepRelationTypeBufferPool) == FALSE)	
		{
			ereport(LOG,
				(errmsg("could not fsync file on mirror "), 
					FileRep_ReportRelationPath(
								open->mirrorFilespaceLocation,
								open->relFileNode,
								open->segmentFileNum)));
		} else 
		{
				//only include this stat if the fsync was successful
				if (fileRepRole == FileRepPrimaryRole) 
				{
						FileRepGpmonStat_CloseRecord(
								FileRepGpmonStatType_PrimaryRoundtripFsyncMsg, 
								&gpmonRecord);
				}
		}
		open->mirrorDataLossOccurred = FileRepPrimary_IsMirrorDataLossOccurred();

	}
	
	errno = primaryError;
	return (errno == 0);

}