/* * SenderLoop * */ static int FileRepAckMirror_RunSender(void) { FileRepShmemMessageDescr_s *fileRepShmemMessageDescr=NULL; char *fileRepMessage; int status = STATUS_OK; bool movePositionConsume = FALSE; FileRepConsumerProcIndex_e messageType; FileRepMessageHeader_s *fileRepMessageHeader; FileRepShmem_s *fileRepAckShmem = NULL; FileRep_InsertConfigLogEntry("run sender ack"); fileRepAckShmem = fileRepAckShmemArray[FILEREP_OUTGOING_MESSAGE_QUEUE]; while (1) { LWLockAcquire(FileRepAckShmemLock, LW_EXCLUSIVE); if (movePositionConsume) { fileRepAckShmem->positionConsume = fileRepAckShmem->positionConsume + fileRepShmemMessageDescr->messageLength + sizeof(FileRepShmemMessageDescr_s); if (fileRepAckShmem->positionConsume == fileRepAckShmem->positionWraparound && fileRepAckShmem->positionInsert != fileRepAckShmem->positionWraparound) { fileRepAckShmem->positionConsume = fileRepAckShmem->positionBegin; fileRepAckShmem->positionWraparound = fileRepAckShmem->positionEnd; } FileRep_IpcSignal(fileRepIpcArray[fileRepAckShmem->ipcArrayIndex]->semP, &fileRepIpcArray[fileRepAckShmem->ipcArrayIndex]->refCountSemP); } fileRepShmemMessageDescr = (FileRepShmemMessageDescr_s*) fileRepAckShmem->positionConsume; while ((fileRepAckShmem->positionConsume == fileRepAckShmem->positionInsert) || ((fileRepAckShmem->positionConsume != fileRepAckShmem->positionInsert) && (fileRepShmemMessageDescr->messageState != FileRepShmemMessageStateReady))) { fileRepIpcArray[fileRepAckShmem->ipcArrayIndex]->refCountSemC++; LWLockRelease(FileRepAckShmemLock); FileRepSubProcess_ProcessSignals(); if (FileRepSubProcess_GetState() != FileRepStateReady) { LWLockAcquire(FileRepAckShmemLock, LW_EXCLUSIVE); break; } FileRep_IpcWait(fileRepIpcArray[fileRepAckShmem->ipcArrayIndex]->semC, &fileRepIpcArray[fileRepAckShmem->ipcArrayIndex]->refCountSemC, FileRepAckShmemLock); LWLockAcquire(FileRepAckShmemLock, LW_EXCLUSIVE); if (fileRepAckShmem->positionConsume == fileRepAckShmem->positionWraparound && fileRepAckShmem->positionInsert != fileRepAckShmem->positionWraparound) { fileRepAckShmem->positionConsume = fileRepAckShmem->positionBegin; fileRepAckShmem->positionWraparound = fileRepAckShmem->positionEnd; } /* Re-assign to find if messageState is changed */ fileRepShmemMessageDescr = (FileRepShmemMessageDescr_s*) fileRepAckShmem->positionConsume; } // while internal fileRepAckShmem->consumeCount++; LWLockRelease(FileRepAckShmemLock); FileRepSubProcess_ProcessSignals(); if (FileRepSubProcess_GetState() != FileRepStateReady) { break; } FileRep_InsertLogEntry( "M_RunSenderAck", FileRep_GetFlatFileIdentifier("", ""), FileRepRelationTypeNotSpecified, FileRepOperationNotSpecified, FILEREP_UNDEFINED, FILEREP_UNDEFINED, FileRepAckStateNotInitialized, FILEREP_UNDEFINED, FILEREP_UNDEFINED); #ifdef FAULT_INJECTOR FaultInjector_InjectFaultIfSet( FileRepSender, DDLNotSpecified, "", //databaseName ""); // tableName #endif fileRepMessage = (char*) (fileRepAckShmem->positionConsume + sizeof(FileRepShmemMessageDescr_s)); fileRepMessageHeader = (FileRepMessageHeader_s*) (fileRepAckShmem->positionConsume + sizeof(FileRepShmemMessageDescr_s)); messageType = FileRepMessageTypeXLog; if (! FileRepConnClient_SendMessage( messageType, fileRepShmemMessageDescr->messageSync, fileRepMessage, fileRepShmemMessageDescr->messageLength)) { ereport(WARNING, (errcode_for_socket_access(), errmsg("mirror failure, " "could not sent ack message to primary : %m, " "failover requested"), errhint("run gprecoverseg to re-establish mirror connectivity"), FileRep_errdetail_ShmemAck(), FileRep_errcontext())); status = STATUS_ERROR; break; } movePositionConsume = TRUE; } // while(1) FileRepConnClient_CloseConnection(); return status; }
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; }
static int FileRepAckPrimary_RunReceiver(void) { uint32_t msgLength = 0; FileRepConsumerProcIndex_e msgType; int status = STATUS_OK; char *msgPositionInsert; FileRepShmemMessageDescr_s *fileRepShmemMessageDescr; uint32 spareField; FileRep_InsertConfigLogEntry("run receiver"); while (1) { FileRepSubProcess_ProcessSignals(); if (FileRepSubProcess_GetState() != FileRepStateReady && FileRepSubProcess_GetState() != FileRepStateInitialization) { break; } if ( ! FileRepConnServer_AwaitMessageBegin()) { /* call was interrupted ... go back to beginning to process signals */ continue; } status = FileRepConnServer_ReceiveMessageType(&msgType); if (status != STATUS_OK) { break; } /* DATA MESSAGE TYPE */ status = FileRepConnServer_ReceiveMessageLength(&msgLength); if (status != STATUS_OK) { break; } msgPositionInsert = FileRep_ReserveShmem(fileRepAckShmemArray[msgType], msgLength, /* not used */ &spareField, FileRepOperationNotSpecified, FileRepAckShmemLock); if (msgPositionInsert == NULL) { status = STATUS_ERROR; ereport(WARNING, (errmsg("mirror failure, " "could not queue received ack message to be processed, " "failover requested"), errhint("run gprecoverseg to re-establish mirror connectivity"), FileRep_errdetail_Shmem(), FileRep_errdetail_ShmemAck(), FileRep_errcontext())); break; } status = FileRepConnServer_ReceiveMessageData( msgPositionInsert + sizeof(FileRepShmemMessageDescr_s), msgLength); if (status != STATUS_OK) { break; } SIMPLE_FAULT_INJECTOR(FileRepReceiver); fileRepShmemMessageDescr = (FileRepShmemMessageDescr_s*) msgPositionInsert; /* it is not in use */ fileRepShmemMessageDescr->messageSync = FALSE; fileRepShmemMessageDescr->messageState = FileRepShmemMessageStateReady; LWLockAcquire(FileRepAckShmemLock, LW_EXCLUSIVE); FileRep_IpcSignal(fileRepIpcArray[fileRepAckShmemArray[msgType]->ipcArrayIndex]->semC, &fileRepIpcArray[fileRepAckShmemArray[msgType]->ipcArrayIndex]->refCountSemC); LWLockRelease(FileRepAckShmemLock); FileRep_InsertLogEntry( "P_RunReceiver", FileRep_GetFlatFileIdentifier("", ""), FileRepRelationTypeNotSpecified, FileRepOperationNotSpecified, FILEREP_UNDEFINED, FILEREP_UNDEFINED, FileRepAckStateNotInitialized, spareField, FILEREP_UNDEFINED); } // while(1) FileRepConnServer_CloseConnection(); return status; }