コード例 #1
0
ファイル: cdbfilerepresyncworker.c プロジェクト: 50wu/gpdb
/*
 * FileRepPrimary_StartResyncWorker()
 */
void 
FileRepPrimary_StartResyncWorker(void)
{	
	int	status = STATUS_OK;
	
	FileRep_InsertConfigLogEntry("start resync worker");
	
	Insist(fileRepRole == FileRepPrimaryRole);
	
	while (1) {
		
		if (status != STATUS_OK) 
		{
			FileRep_SetSegmentState(SegmentStateFault, FaultTypeMirror);
			FileRepSubProcess_SetState(FileRepStateFault);
		}
		
		/*
		 * We are waiting for following conditions to move forward:
		 *
		 * 	Database is running
		 * 	And
		 * 		if dataState is InResync, we wait for FileRepSubProcess to Ready state
		 * 		else don't wait
		 */
		while (!isDatabaseRunning() ||
			   !(dataState == DataStateInResync ? FileRepSubProcess_GetState() == FileRepStateReady : true))
		{
			FileRepSubProcess_ProcessSignals();

			if (FileRepSubProcess_GetState() == FileRepStateShutdown ||
				FileRepSubProcess_GetState() == FileRepStateShutdownBackends)
			{
				break;
			}

			pg_usleep(50000L); /* 50 ms */	
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateShutdown ||
			FileRepSubProcess_GetState() == FileRepStateShutdownBackends) {
			break;
		}
		
		FileRepSubProcess_InitHeapAccess();

		status = FileRepPrimary_RunResyncWorker();
		
		if (status != STATUS_OK) {
			continue;
		}
		
		break;
		
	} // while(1)	
		
}
コード例 #2
0
ファイル: cdbfilerepprimaryack.c プロジェクト: hsyuan/gpdb
/*
 * 
 * FileRepAckPrimary_StartConsumer
*/
void 
FileRepAckPrimary_StartConsumer(void)
{
	int status = STATUS_OK;
	
	FileRep_InsertConfigLogEntry("run consumer");
		
	while (1) {
		
		if (status != STATUS_OK) 
		{
			FileRep_SetSegmentState(SegmentStateFault, FaultTypeMirror);
			FileRepSubProcess_SetState(FileRepStateFault);
		}
		
		while (FileRepSubProcess_GetState() == FileRepStateFault ||
			   
			   (fileRepShmemArray[0]->state == FileRepStateNotInitialized &&
			    FileRepSubProcess_GetState() != FileRepStateShutdown)) {
			
			FileRepSubProcess_ProcessSignals();
			pg_usleep(50000L); /* 50 ms */	
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateShutdown) {
			
			break;
		}		
		
		status = FileRepAckPrimary_RunConsumer();
		
	} // while(1)
		

	if (FileRepSubProcess_GetState() == FileRepStateShutdown) {
		/* perform graceful shutdown */
	}

	LWLockAcquire(FileRepAckHashShmemLock, LW_EXCLUSIVE);

	FileRep_IpcSignal(fileRepIpcArray[fileRepAckHashShmem->ipcArrayIndex]->semP, 
					  &fileRepIpcArray[fileRepAckHashShmem->ipcArrayIndex]->refCountSemP);
	
	LWLockRelease(FileRepAckHashShmemLock);

	/* NOTE free memory (if any) */
	return;
}
コード例 #3
0
/*
 * 
 * FileRepPrimary_StartRecoveryInSync()
 *
 *
 */
static void 
FileRepPrimary_StartRecoveryInSync(void)
{	
	int	status = STATUS_OK;
	
	FileRep_InsertConfigLogEntry("run recovery");
	
	while (1) {
		
		if (status != STATUS_OK) 
		{
			FileRep_SetSegmentState(SegmentStateFault, FaultTypeMirror);
			FileRepSubProcess_SetState(FileRepStateFault);
		}
		
		while (FileRepSubProcess_GetState() == FileRepStateFault ||
			   
			   (fileRepShmemArray[0]->state == FileRepStateNotInitialized &&
				FileRepSubProcess_GetState() != FileRepStateShutdownBackends &&
			    FileRepSubProcess_GetState() != FileRepStateShutdown)) {
			
			FileRepSubProcess_ProcessSignals();
			pg_usleep(50000L); /* 50 ms */	
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateShutdown ||
			FileRepSubProcess_GetState() == FileRepStateShutdownBackends) {
			
			break;
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateReady) {
			break;
		}
		
		Insist(fileRepRole == FileRepPrimaryRole);

		Insist(dataState == DataStateInSync);
		
		status = FileRepPrimary_RunRecoveryInSync();

		
	} // while(1)	

}
コード例 #4
0
ファイル: cdbfilerepresyncworker.c プロジェクト: AnLingm/gpdb
/*
 * FileRepPrimary_StartResyncWorker()
 */
void 
FileRepPrimary_StartResyncWorker(void)
{	
	int	status = STATUS_OK;
	
	FileRep_InsertConfigLogEntry("start resync worker");
	
	Insist(fileRepRole == FileRepPrimaryRole);
	
	while (1) {
		
		if (status != STATUS_OK) 
		{
			FileRep_SetSegmentState(SegmentStateFault, FaultTypeMirror);
			FileRepSubProcess_SetState(FileRepStateFault);
		}
		
		while (FileRepSubProcess_GetState() != FileRepStateShutdown &&
			   FileRepSubProcess_GetState() != FileRepStateShutdownBackends &&
			   ! (FileRepSubProcess_GetState() == FileRepStateReady && 
			    dataState == DataStateInResync)) {
			
			FileRepSubProcess_ProcessSignals();
			pg_usleep(50000L); /* 50 ms */	
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateShutdown ||
			FileRepSubProcess_GetState() == FileRepStateShutdownBackends) {
			
			break;
		}
		
		status = FileRepPrimary_RunResyncWorker();
		
		if (status != STATUS_OK) {
			continue;
		}
		
		break;
		
	} // while(1)	
		
}
コード例 #5
0
/*
 *  FileRepSubProcess_ProcessSignals()
 *
 */
bool
FileRepSubProcess_ProcessSignals()
{
	bool		processExit = false;

	if (reloadConfigFile)
	{
		reloadConfigFile = false;
		ProcessConfigFile(PGC_SIGHUP);

		FileRep_SetFileRepRetry();
	}

	if (shutdownRequested)
	{
		SegmentState_e segmentState;

		getPrimaryMirrorStatusCodes(NULL, &segmentState, NULL, NULL);

		shutdownRequested = false;

		if (segmentState == SegmentStateShutdownFilerepBackends)
		{
			processExit = FileRepIsBackendSubProcess(fileRepProcessType);
			FileRepSubProcess_SetState(FileRepStateShutdownBackends);
		}
		else
		{
			processExit = true;
			FileRepSubProcess_SetState(FileRepStateShutdown);
		}
	}

	/*
	 * Immediate shutdown if postmaster or main filerep process (parent) is
	 * not alive to avoid manual cleanup.
	 */
	if (!PostmasterIsAlive(false /* amDirectChild */ ) || !ParentProcIsAlive())
	{
		quickdie_impl();
	}

	for (;;)
	{
		/* check to see if change required */
		sig_atomic_t curStateChangeRequestCounter = stateChangeRequestCounter;

		if (curStateChangeRequestCounter == lastChangeRequestProcessCounterValue)
			break;
		lastChangeRequestProcessCounterValue = curStateChangeRequestCounter;

		/* do the change in local memory */
		getFileRepRoleAndState(&fileRepRole, &segmentState, &dataState, NULL, NULL);
		switch (segmentState)
		{

			case SegmentStateNotInitialized:
				FileRepSubProcess_SetState(FileRepStateNotInitialized);
				break;

			case SegmentStateInitialization:
				FileRepSubProcess_SetState(FileRepStateInitialization);
				break;

			case SegmentStateInResyncTransition:
				FileRepSubProcess_SetState(FileRepStateInitialization);
				break;

			case SegmentStateInChangeTrackingTransition:
			case SegmentStateInSyncTransition:
				/* fileRepState remains Ready */
				break;

			case SegmentStateChangeTrackingDisabled:
			case SegmentStateReady:
				FileRepSubProcess_SetState(FileRepStateReady);
				break;

			case SegmentStateFault:
				FileRepSubProcess_SetState(FileRepStateFault);
				break;

			case SegmentStateShutdownFilerepBackends:
				if (fileRepRole == FileRepPrimaryRole)
				{
					FileRepSubProcess_SetState(FileRepStateShutdownBackends);
				}
				else
				{
					processExit = true;
					FileRepSubProcess_SetState(FileRepStateShutdown);
				}
				break;

			case SegmentStateImmediateShutdown:
			case SegmentStateShutdown:
				processExit = true;
				FileRepSubProcess_SetState(FileRepStateShutdown);
				break;

			default:
				Assert(0);
				break;
		} //switch ()

				if (processExit == true)
				{
					FileRep_IpcSignalAll();
				}
	}

	return (processExit);
}
コード例 #6
0
/*
 * 
 * FileRepPrimary_StartRecoveryInChangeTracking()
 *
 */
static void 
FileRepPrimary_StartRecoveryInChangeTracking(void)
{		
	FileRep_InsertConfigLogEntry("run recovery");
	
	while (1) {
					
		while (FileRepSubProcess_GetState() == FileRepStateFault) {			
			FileRepSubProcess_ProcessSignals();
			pg_usleep(50000L); /* 50 ms */	
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateShutdown ||
			FileRepSubProcess_GetState() == FileRepStateShutdownBackends) {
			
			break;
		}
				
		Insist(fileRepRole == FileRepPrimaryRole);
		Insist(dataState == DataStateInChangeTracking);		
		Insist(FileRepSubProcess_GetState() != FileRepStateReady);
		
		if (ChangeTracking_RetrieveIsTransitionToInsync())
		{
			ChangeTracking_DropAll();
		}
		else
		{
			if (ChangeTracking_RetrieveIsTransitionToResync() == FALSE &&
				isFullResync())
			{
				ChangeTracking_MarkFullResync();
				/* segmentState == SegmentStateChangeTrackingDisabled */
				getFileRepRoleAndState(&fileRepRole, &segmentState, &dataState, NULL, NULL);
				Assert(segmentState == SegmentStateChangeTrackingDisabled);
				
				/* database is resumed */
				primaryMirrorSetIOSuspended(FALSE);
				
				FileRep_InsertConfigLogEntry("change tracking recovery completed");
				
				break;				
			}
			else
			{
				ChangeTracking_MarkIncrResync();
			}
			
		}
		
		XLogInChangeTrackingTransition();
				
		/* NOTE: Any error during change tracking will result in disabling Change Tracking */
		FileRepSubProcess_SetState(FileRepStateReady);
		
		/* database is resumed */
		primaryMirrorSetIOSuspended(FALSE);
				
		FileRep_InsertConfigLogEntry("change tracking recovery completed");
		
		break;
		
	} // while(1)	
}
コード例 #7
0
/*
 * 
 * FileRepPrimary_RunRecoveryInSync()
 *		
 *		1) Recover Flat Files
 *			a) pg_control file
 *			b) pg_database file
 *			c) pg_auth file
 *			d) pg_twophase directory
 *			e) Slru directories 
 *					*) pg_clog 
 *					*) pg_multixact 
 *					*) pg_distributedlog
 *					*) pg_distributedxidmap
 *					*) pg_subtrans
 *
 *		2) Reconcile xlog EOF
 *
 */
static int 
FileRepPrimary_RunRecoveryInSync(void)
{	
	int status = STATUS_OK;
	
	FileRep_InsertConfigLogEntry("run recovery of flat files");
	
	while (1) {
		
		status = XLogRecoverMirrorControlFile();
		
		if (status != STATUS_OK) {
			break;
		}
		
		FileRepSubProcess_ProcessSignals();
		if (FileRepSubProcess_GetState() != FileRepStateInitialization) {
			break;
		}		
		
		status = XLogReconcileEofPrimary();
		
		if (status != STATUS_OK) {
			break;
		}
		
		FileRepSubProcess_ProcessSignals();
		if (FileRepSubProcess_GetState() != FileRepStateInitialization) {
			break;
		}
		
		MirroredFlatFile_DropTemporaryFiles();
				
		FileRepSubProcess_ProcessSignals();
		if (FileRepSubProcess_GetState() != FileRepStateInitialization) {
			break;
		}				

		MirroredFlatFile_MirrorDropTemporaryFiles();

		FileRepSubProcess_ProcessSignals();
		if (FileRepSubProcess_GetState() != FileRepStateInitialization) {
			break;
		}						
		
		status = FlatFilesRecoverMirror();
		
		if (status != STATUS_OK) {
			break;
		}
		
		FileRepSubProcess_ProcessSignals();
		if (FileRepSubProcess_GetState() != FileRepStateInitialization) {
			break;
		}		

		status = TwoPhaseRecoverMirror();

		if (status != STATUS_OK) {
			break;
		}
		
		FileRepSubProcess_ProcessSignals();
		if (FileRepSubProcess_GetState() != FileRepStateInitialization) {
			break;
		}	
		
		status = SlruRecoverMirror();
		
		if (status != STATUS_OK) {
			break;
		}
		
		FileRepSubProcess_ProcessSignals();
		if (FileRepSubProcess_GetState() != FileRepStateInitialization) {
			break;
		}			
				
		FileRepSubProcess_SetState(FileRepStateReady);
		break;
	}
	
	
	return status;
}
コード例 #8
0
/*
 * 
 * FileRepPrimary_StartSender
 */
void 
FileRepAckMirror_StartSender(void)
{
	int				status = STATUS_OK;
	int				retry = 0; 
	struct timeval	currentTime;
	pg_time_t		beginTime = 0;
	pg_time_t		endTime = 0;
	
	FileRep_InsertConfigLogEntry("start sender ack");

	while (1) {
		
		if (status != STATUS_OK) {
			FileRep_SetSegmentState(SegmentStateFault, FaultTypeMirror);
			FileRepSubProcess_SetState(FileRepStateFault);
		}
		
		while (FileRepSubProcess_GetState() == FileRepStateInitialization ||
			   FileRepSubProcess_GetState() == FileRepStateFault ||

			   (fileRepShmemArray[0]->state == FileRepStateNotInitialized &&
			    FileRepSubProcess_GetState() != FileRepStateShutdown )) {
			
			FileRepSubProcess_ProcessSignals();
			pg_usleep(50000L); /* 50 ms */	
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateShutdown) {
			
			break;
		}

		{
			char	tmpBuf[FILEREP_MAX_LOG_DESCRIPTION_LEN];
			
			snprintf(tmpBuf, sizeof(tmpBuf), "primary address(port) '%s(%d)' mirror address(port) '%s(%d)' ",
					 fileRepPrimaryHostAddress, 
					 fileRepPrimaryPort,
					 fileRepMirrorHostAddress, 
					 fileRepMirrorPort);
			
			FileRep_InsertConfigLogEntry(tmpBuf);
		}
		
		Insist(fileRepRole == FileRepMirrorRole);

		status = FileRepConnClient_EstablishConnection(
									   fileRepPrimaryHostAddress,
									   fileRepPrimaryPort,
									   FALSE /* reportError */);		

		if (status != STATUS_OK)
		{
			gettimeofday(&currentTime, NULL);
			beginTime = (pg_time_t) currentTime.tv_sec;
		}
		
		while (status != STATUS_OK && 
			   FileRep_IsRetry(retry) &&
			   (endTime - beginTime) < gp_segment_connect_timeout)  
		{
			FileRep_Sleep10ms(retry);
			
			FileRep_IncrementRetry(retry);
			
			gettimeofday(&currentTime, NULL);
			endTime = (pg_time_t) currentTime.tv_sec;			
			
			status = FileRepConnClient_EstablishConnection(
														   fileRepPrimaryHostAddress,
														   fileRepPrimaryPort,
														   (retry == file_rep_retry && file_rep_retry != 0) ||
														   ((endTime - beginTime) > gp_segment_connect_timeout) ? TRUE : FALSE);

			if (FileRepSubProcess_IsStateTransitionRequested())
			{
				break;
			}			
		}
 
		if (status != STATUS_OK) {
			continue;
		}
		
		FileRep_SetFileRepRetry();
		
		status = FileRepAckMirror_RunSender();
		
	} // while(1)
		
	FileRepConnClient_CloseConnection();
	
	return;
}
コード例 #9
0
ファイル: cdbfilerepprimaryack.c プロジェクト: hsyuan/gpdb
/*
 * 
 * FileRepAckPrimary_StartReceiver
 */
void 
FileRepAckPrimary_StartReceiver(void)
{	
	int				status = STATUS_OK;
	struct timeval	currentTime;
	pg_time_t		beginTime = 0;
	pg_time_t		endTime = 0;	
	int				retval = 0;
	
	FileRep_InsertConfigLogEntry("start receiver ack");

	{
		char	tmpBuf[FILEREP_MAX_LOG_DESCRIPTION_LEN];
		
		snprintf(tmpBuf, sizeof(tmpBuf), "primary address(port) '%s(%d)' mirror address(port) '%s(%d)' ",
				 fileRepPrimaryHostAddress, 
				 fileRepPrimaryPort,
				 fileRepMirrorHostAddress, 
				 fileRepMirrorPort);
		
		FileRep_InsertConfigLogEntry(tmpBuf);
	}
		
	FileRepAckPrimary_ShmemReInit();
	
	Insist(fileRepRole == FileRepPrimaryRole);
	
	if (filerep_inject_listener_fault)
	{
		status = STATUS_ERROR;
		ereport(WARNING,
				(errmsg("mirror failure, "
						"injected fault by guc filerep_inject_listener_fault, "
						"failover requested"), 
				 FileRep_errcontext()));												
		
		FileRep_SetSegmentState(SegmentStateFault, FaultTypeMirror);
		FileRepSubProcess_SetState(FileRepStateFault);
		FileRepSubProcess_ProcessSignals();
		return;
	}
	
	status = FileRepConnServer_StartListener(
								 fileRepPrimaryHostAddress,
								 fileRepPrimaryPort);
	
	gettimeofday(&currentTime, NULL);
	beginTime = (pg_time_t) currentTime.tv_sec;
	
	while (1) {
		
		if (status != STATUS_OK) 
		{
			FileRep_SetSegmentState(SegmentStateFault, FaultTypeMirror);
			FileRepSubProcess_SetState(FileRepStateFault);
		}
		
		while (FileRepSubProcess_GetState() == FileRepStateFault) {
			
			FileRepSubProcess_ProcessSignals();
			pg_usleep(50000L); /* 50 ms */	
		}
		
		if (FileRepSubProcess_GetState() == FileRepStateShutdown) {
			
			break;
		}

		PG_SETMASK(&BlockSig);
		retval = FileRepConnServer_Select();	
		PG_SETMASK(&UnBlockSig);
		
		gettimeofday(&currentTime, NULL);
		endTime = (pg_time_t) currentTime.tv_sec;

		if ((endTime - beginTime) > gp_segment_connect_timeout) 
		{
			ereport(WARNING, 
					(errmsg("mirror failure, "
							"no connection was established from client from mirror, "
							"primary address(port) '%s(%d)' mirror address(port) '%s(%d)' timeout reached '%d' "
							"failover requested",
							fileRepPrimaryHostAddress, 
							fileRepPrimaryPort,
							fileRepMirrorHostAddress, 
							fileRepMirrorPort,
							gp_segment_connect_timeout),
					 errSendAlert(true),
					 FileRep_errcontext()));
			
			status = STATUS_ERROR;
			continue;
		}

		/* 
		 * check and process any signals received 
		 * The routine returns TRUE if the received signal requests
		 * process shutdown.
		 */
		if (FileRepSubProcess_ProcessSignals()) {
			continue;
		}
		
		if (retval < 0) {
			status = STATUS_ERROR;
			continue;
		}
		
		if (retval == 0) {
			continue;
		}
		
		Assert(retval > 0);
		
		status = FileRepConnServer_CreateConnection();
		
		if (status != STATUS_OK) {
			continue;
		}				
		
		status = FileRepConnServer_ReceiveStartupPacket();
		if (status != STATUS_OK) {
			continue;
		} 
		
		fileRepShmemArray[0]->state = FileRepStateInitialization;
		
		status = FileRepAckPrimary_RunReceiver();
		
	} // while(1)
			
	FileRepConnServer_CloseConnection();
	
	return;
}