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; }
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; }
/* * 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); }