Exemplo n.º 1
0
void StreamBatchWaitAndRemove(StreamBatch *batch)
{
	int cycle = 0;

	while (!StreamBatchAllAcked(batch))
	{
		if (cycle % CHECK_CRASH_CYCLES == 0)
		{
			int num_crashes = num_cq_crashes(batch);

			cycle = 0;

			if (num_crashes == 0)
				continue;

			// All tuples have been read, and we've received acks from all workers that didn't crash.
			if (StreamBatchAllRead(batch) &&
					batch->num_wacks >= (batch->num_tups * (bms_num_members(batch->readers) - num_crashes)))
				break;
		}

		pg_usleep(SLEEP_MS * 1000);

		cycle++;
	}

	ShmemDynFree(batch);
}
Exemplo n.º 2
0
static jint initializeJavaVM(JVMOptList *optList)
{
	jint jstat;
	JavaVMInitArgs vm_args;

	if(pljava_debug)
	{
		elog(INFO, "Backend pid = %d. Attach the debugger and set pljava_debug to false to continue", getpid());
		while(pljava_debug)
			pg_usleep(1000000L);
	}

	vm_args.nOptions = optList->size;
	vm_args.options  = optList->options;
	vm_args.version  = JNI_VERSION_1_4;
	vm_args.ignoreUnrecognized = JNI_FALSE;

	elog(DEBUG2, "creating Java virtual machine");

	jstat = JNI_createVM(&s_javaVM, &vm_args);

	if(jstat == JNI_OK && JNI_exceptionCheck())
	{
		JNI_exceptionDescribe();
		JNI_exceptionClear();
		jstat = JNI_ERR;
	}
	JVMOptList_delete(optList);

	return jstat;
}
Exemplo n.º 3
0
static void
terminate_group(ContQueryProcGroup *grp)
{
	bool found;
	int i;

	grp->active = true;

	for (i = 0; i < TOTAL_SLOTS; i++)
	{
		ContQueryProc *proc = &grp->procs[i];

		/* Wake up processes, so they can see the terminate flag. */
		SetLatch(proc->latch);

		/* Let workers crash now as well in case we force terminate them. */
		ChangeBackgroundWorkerRestartState(&proc->handle, true, 0);
	}

	/* Wait for a bit and then force terminate any processes that are still alive. */
	pg_usleep(Max(ContQuerySchedulerShmem->params.max_wait, MIN_WAIT_TERMINATE_MS) * 1000);

	for (i = 0; i < TOTAL_SLOTS; i++)
	{
		ContQueryProc *proc = &grp->procs[i];
		TerminateBackgroundWorker(&proc->handle);
	}

	hash_search(ContQuerySchedulerShmem->proc_table, &grp->db_oid, HASH_REMOVE, &found);

	Assert(found);

	TupleBufferDrain(WorkerTupleBuffer, grp->db_oid);
	TupleBufferDrain(CombinerTupleBuffer, grp->db_oid);
}
Exemplo n.º 4
0
/*
 * Wait while spinning on a contended spinlock.
 */
void
perform_spin_delay(SpinDelayStatus *status)
{
	/* CPU-specific delay each time through the loop */
	SPIN_DELAY();

	/* Block the process every spins_per_delay tries */
	if (++(status->spins) >= spins_per_delay)
	{
		if (++(status->delays) > NUM_DELAYS)
			s_lock_stuck(status->file, status->line, status->func);

		if (status->cur_delay == 0)		/* first time to delay? */
			status->cur_delay = MIN_DELAY_USEC;

		pg_usleep(status->cur_delay);

#if defined(S_LOCK_TEST)
		fprintf(stdout, "*");
		fflush(stdout);
#endif

		/* increase delay by a random fraction between 1X and 2X */
		status->cur_delay += (int) (status->cur_delay *
					  ((double) random() / (double) MAX_RANDOM_VALUE) + 0.5);
		/* wrap back to minimum delay when max is exceeded */
		if (status->cur_delay > MAX_DELAY_USEC)
			status->cur_delay = MIN_DELAY_USEC;

		status->spins = 0;
	}
}
Exemplo n.º 5
0
/*
 *	pgrename
 */
int
pgrename(const char *from, const char *to)
{
    int			loops = 0;

    /*
     * We need to loop because even though PostgreSQL uses flags that
     * allow rename while the file is open, other applications might have
     * the file open without those flags.  However, we won't wait
     * indefinitely for someone else to close the file.
     */
#if defined(WIN32) && !defined(__CYGWIN__)
    while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
#else
    while (rename(from, to) < 0)
#endif
    {
#if defined(WIN32) && !defined(__CYGWIN__)
        if (GetLastError() != ERROR_ACCESS_DENIED)
#else
        if (errno != EACCES)
#endif
            /* set errno? */
            return -1;
        if (++loops > 300)		/* time out after 30 sec */
            return -1;
        pg_usleep(100000);		/* us */
    }
    return 0;
}
Exemplo n.º 6
0
/*
 * Synchronize threads to finish for this process to die.  Dispatching
 * threads need to acknowledge that we are dying, otherwise the main
 * thread will cleanup memory contexts which could cause process crash
 * while the threads are touching stale pointers.  Threads will check
 * proc_exit_inprogress and immediately stops once it's found to be true.
 */
void
cdbdisp_waitThreads(void)
{
	int	i,
		max_retry;
	long interval = 10 * 1000;	/* 10 msec */

	/*
	 * Just in case to avoid to be stuck in the final stage of process
	 * lifecycle, insure by setting time limit.  If it exceeds, it probably
	 * means some threads are stuck and not progressing, in which case
	 * we can go ahead and cleanup things anyway.  The duration should be
	 * longer than the select timeout in thread_DispatchWait.
	 */
	max_retry = (DISPATCH_WAIT_TIMEOUT_SEC + 10) * 1000000L / interval;

	/*
	 * This is supposed to be called after the flag is set.
	 */
	Assert(proc_exit_inprogress);

	for (i = 0; i < max_retry; i++)
	{
		if (RunningThreadCount == 0)
			break;
		pg_usleep(interval);
	}
}
Exemplo n.º 7
0
/*
 *	pgunlink
 */
int
pgunlink(const char *path)
{
	int			loops = 0;

	/* Is this loop even necessary now that we have win32_open()?  */
	while (unlink(path))
	{
		if (errno != EACCES)
			/* set errno? */
			return -1;
		pg_usleep(100000);		/* us */
		if (loops == 30)
#ifndef FRONTEND
			elog(LOG, "could not unlink \"%s\", continuing to try",
				 path);
#else
			fprintf(stderr, "could not unlink \"%s\", continuing to try\n",
					path);
#endif
		loops++;
	}

	if (loops > 30)
#ifndef FRONTEND
		elog(LOG, "completed unlink of \"%s\"", path);
#else
		fprintf(stderr, "completed unlink of \"%s\"\n", path);
#endif
	return 0;
}
Exemplo n.º 8
0
/*
 * Standby wait logic for ResolveRecoveryConflictWithVirtualXIDs.
 * We wait here for a while then return. If we decide we can't wait any
 * more then we return true, if we can wait some more return false.
 */
static bool
WaitExceedsMaxStandbyDelay(void)
{
	TimestampTz ltime;

	/* Are we past the limit time? */
	ltime = GetStandbyLimitTime();
	if (ltime && GetCurrentTimestamp() >= ltime)
		return true;

	/*
	 * Sleep a bit (this is essential to avoid busy-waiting).
	 */
	pg_usleep(standbyWait_us);

	/*
	 * Progressively increase the sleep times, but not to more than 1s, since
	 * pg_usleep isn't interruptable on some platforms.
	 */
	standbyWait_us *= 2;
	if (standbyWait_us > 1000000)
		standbyWait_us = 1000000;

	return false;
}
Exemplo n.º 9
0
/*
 * RestoreWALFileForRecovery()
 *
 *	  Perform the action required to restore the file from archive
 */
static bool
RestoreWALFileForRecovery(void)
{
	int			rc = 0;
	int			numretries = 0;

	if (debug)
	{
		fprintf(stderr, "running restore:      ");
		fflush(stderr);
	}

	while (numretries <= maxretries)
	{
		rc = system(restoreCommand);
		if (rc == 0)
		{
			if (debug)
			{
				fprintf(stderr, "OK\n");
				fflush(stderr);
			}
			return true;
		}
		pg_usleep(numretries++ * sleeptime * 1000000L);
	}

	/*
	 * Allow caller to add additional info
	 */
	if (debug)
		fprintf(stderr, "not restored\n");
	return false;
}
Exemplo n.º 10
0
void
ResolveRecoveryConflictWithDatabase(Oid dbid)
{
	/*
	 * We don't do ResolveRecoveryConflictWithVirtualXIDs() here since that
	 * only waits for transactions and completely idle sessions would block
	 * us. This is rare enough that we do this as simply as possible: no wait,
	 * just force them off immediately.
	 *
	 * No locking is required here because we already acquired
	 * AccessExclusiveLock. Anybody trying to connect while we do this will
	 * block during InitPostgres() and then disconnect when they see the
	 * database has been removed.
	 */
	while (CountDBBackends(dbid) > 0)
	{
		CancelDBBackends(dbid, PROCSIG_RECOVERY_CONFLICT_DATABASE, true);

		/*
		 * Wait awhile for them to die so that we avoid flooding an
		 * unresponsive backend when system is heavily loaded.
		 */
		pg_usleep(10000);
	}
}
Exemplo n.º 11
0
/*
 * ForgetRelationFsyncRequests -- ensure any fsyncs for a rel are forgotten
 */
void
ForgetRelationFsyncRequests(RelFileNode rnode)
{
	if (pendingOpsTable)
	{
		/* standalone backend or startup process: fsync state is local */
		RememberFsyncRequest(rnode, FORGET_RELATION_FSYNC);
	}
	else if (IsUnderPostmaster)
	{
		/*
		 * Notify the bgwriter about it.  If we fail to queue the revoke
		 * message, we have to sleep and try again ... ugly, but hopefully
		 * won't happen often.
		 *
		 * XXX should we CHECK_FOR_INTERRUPTS in this loop?  Escaping with
		 * an error would leave the no-longer-used file still present on
		 * disk, which would be bad, so I'm inclined to assume that the
		 * bgwriter will always empty the queue soon.
		 */
		while (!ForwardFsyncRequest(rnode, FORGET_RELATION_FSYNC))
			pg_usleep(10000L);	/* 10 msec seems a good number */
		/*
		 * Note we don't wait for the bgwriter to actually absorb the
		 * revoke message; see mdsync() for the implications.
		 */
	}
}
Exemplo n.º 12
0
/*
 * FileRepPrimary_RunResyncWorker()
 *
 */
static int
FileRepPrimary_RunResyncWorker(void)
{
	int							status = STATUS_OK;
	FileRepResyncHashEntry_s	*entry = NULL;
	ChangeTrackingRequest		*request = NULL;

	FileRep_InsertConfigLogEntry("run resync worker");
	
	while (1) {

		FileRepSubProcess_ProcessSignals();
		
		if (! (FileRepSubProcess_GetState() == FileRepStateReady && 
			   dataState == DataStateInResync))
		{
			break;
		}

		entry = FileRepPrimary_GetResyncEntry(&request);
				
		if (entry == NULL && request == NULL) {
			
			pg_usleep(100000L); /* 100 ms */
			continue;
		}
		
		Assert(! (entry != NULL && request != NULL));

		if (entry != NULL)
		{			
			status = FileRepPrimary_ResyncWrite(entry);
			
			if (status == STATUS_OK)
			{
				if (entry->mirrorBufpoolResyncChangedPageCount == 0)
				{
					entry->mirrorBufpoolResyncChangedPageCount = (entry->mirrorAppendOnlyNewEof - entry->mirrorAppendOnlyLossEof) / BLCKSZ;
				}					
				
				status = FileRepResync_UpdateEntry(entry);
			}
		}
		
		if (request != NULL)
		{
			status = FileRepPrimary_ResyncBufferPoolIncrementalWrite(request);
			request = NULL;
		}
		
		if (status != STATUS_OK)
		{
			break;
		}
		
	}
	
	return status;
}
Exemplo n.º 13
0
Arquivo: fd.c Projeto: hellower/gpdb
int
FileRead(File file, char *buffer, int amount)
{
	int			returnCode;

	Assert(FileIsValid(file));

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

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

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

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

	if (returnCode >= 0)
		VfdCache[file].seekPos += returnCode;
	else
	{
		/*
		 * Windows may run out of kernel buffers and return "Insufficient
		 * system resources" error.  Wait a bit and retry to solve it.
		 *
		 * It is rumored that EINTR is also possible on some Unix filesystems,
		 * in which case immediate retry is indicated.
		 */
#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;
	}

	return returnCode;
}
Exemplo n.º 14
0
Arquivo: lwlock.c Projeto: 50wu/gpdb
static void
LWLockTryLockWaiting(
		PGPROC	   *proc, 
		LWLockId lockid, 
		LWLockMode mode)
{
	volatile LWLock *lock = &(LWLockArray[lockid].lock);
	int 			milliseconds = 0;
	int				exclusivePid;
	
	while(true)
	{
		pg_usleep(5000L);
		if (PGSemaphoreTryLock(&proc->sem))
		{
			if (milliseconds >= 750)
				elog(LOG, "Done waiting on lockid %d", lockid);
			return;
		}

		milliseconds += 5;
		if (milliseconds == 750)
		{
			int l;
			int count = 0;
			char buffer[200];

			SpinLockAcquire(&lock->mutex);
			
			if (lock->exclusive > 0)
				exclusivePid = lock->exclusivePid;
			else
				exclusivePid = 0;
			
			SpinLockRelease(&lock->mutex);

			memcpy(buffer, "none", 5);
			
			for (l = 0; l < num_held_lwlocks; l++)
			{
				if (l == 0)
					count += sprintf(&buffer[count],"(");
				else
					count += sprintf(&buffer[count],", ");
				
				count += sprintf(&buffer[count],
							    "lockid %d",
							    held_lwlocks[l]);
			}
			if (num_held_lwlocks > 0)
				count += sprintf(&buffer[count],")");
				
			elog(LOG, "Waited .75 seconds on lockid %d with no success. Exclusive pid %d. Already held: %s", 
				 lockid, exclusivePid, buffer);

		}
	}
}
Exemplo n.º 15
0
/*
 * 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)	
		
}
Exemplo n.º 16
0
/*
 * Wrapper of simple pthread locking functionality, using pthread_mutex_trylock
 * and loop to make it interruptible when waiting the lock;
 *
 * return true if successfuly acquires the lock, false if unable to get the lock
 * and interrupted by SIGTERM, otherwise, infinitely loop to acquire the mutex.
 *
 * If we are going to return false, we close the socket to client; this is crucial
 * for exiting dispatch thread if it is stuck on sending NOTICE to client, and hence
 * avoid mutex deadlock;
 *
 * NOTE: should not call CHECK_FOR_INTERRUPTS and ereport in this routine, since
 * it is in multi-thread context;
 */
static bool
pq_send_mutex_lock()
{
	int count = PQ_BUSY_TEST_COUNT_IN_EXITING;
	int mutex_res;

	do
	{
		mutex_res = pthread_mutex_trylock(&send_mutex);

		if (mutex_res == 0)
		{
			return true;
		}

		if (mutex_res == EBUSY)
		{
			/* No need to acquire lock for TermSignalReceived, since we are in
 			 * a loop here */
			if (TermSignalReceived)
			{
				/*
 				 * try PQ_BUSY_TEST_COUNT_IN_EXITING times before going to
 				 * close the socket, in case real concurrent writing is in
 				 * progress(compared to stuck send call in secure_write);
 				 *
 				 * It cannot help completely eliminate the false negative
 				 * cases, but giving the process is exiting, it is acceptable
 				 * to discard some messages, contrasted with the chance of
 				 * infinite stuck;
 				 */
				if (count-- < 0)
				{
					/* On Redhat and Suse, simple closing the socket would not get
					 * send() out of hanging state, shutdown() can do this(though not
					 * explicitly mentioned in manual page); however, if send over a
					 * socket which has been shutdown, process would be terminated by
					 * SIGPIPE; to avoid this race condition, we set the socket to be
					 * invalid before calling shutdown()
					 *
					 * On OSX, close() can get send() out of hanging state, while
					 * shutdown() would lead to SIGPIPE */
					int saved_fd = MyProcPort->sock;
					MyProcPort->sock = -1;
					whereToSendOutput = DestNone;
#ifndef __darwin__
					shutdown(saved_fd, SHUT_WR);
#endif
					closesocket(saved_fd);
					return false;
				}
			}
		}
		pg_usleep(1000L);
	} while (true);
}
Exemplo n.º 17
0
/*
 * Used by "reader" qExecs to find the slot in the sharedsnapshotArray with the
 * specified slotId.  In general, we should always be able to find the specified
 * slot unless something unexpected.  If the slot is not found, then NULL is
 * returned.
 *
 * MPP-4599: retry in the same pattern as the writer.
 */
static SharedSnapshotSlot *
SharedSnapshotLookup(int4 slotId)
{
	SharedSnapshotSlot *slot = NULL;
	volatile SharedSnapshotStruct *arrayP = sharedSnapshotArray;
	int retryCount = gp_snapshotadd_timeout * 10; /* .1 s per wait */
	int index;

	for (;;)
	{
		CHECK_FOR_INTERRUPTS();

		LWLockAcquire(SharedSnapshotLock, LW_SHARED);

		for (index=0; index < arrayP->maxSlots; index++)
		{
			SharedSnapshotSlot *testSlot;

			testSlot = &arrayP->slots[index];

			if (testSlot->slotindex > arrayP->maxSlots)
			{
				LWLockRelease(SharedSnapshotLock);
				elog(ERROR, "Shared Local Snapshots Array appears corrupted: %s", SharedSnapshotDump());
			}

			if (testSlot->slotid == slotId)
			{
				slot = testSlot;
				break;
			}
		}

		LWLockRelease(SharedSnapshotLock);

		if (slot != NULL)
		{
			break;
		}
		else
		{
			if (retryCount > 0)
			{
				retryCount--;

				pg_usleep(100000); /* 100ms, wait gp_snapshotadd_timeout seconds max. */
			}
			else
			{
				break;
			}
		}
	}

	return slot;
}
Exemplo n.º 18
0
/*
 * pg_sleep - delay for N seconds
 */
Datum
pg_sleep(PG_FUNCTION_ARGS)
{
	float8		secs = PG_GETARG_FLOAT8(0);
	float8		endtime;

	/*
	 * We break the requested sleep into segments of no more than 1 second, to
	 * put an upper bound on how long it will take us to respond to a cancel
	 * or die interrupt.  (Note that pg_usleep is interruptible by signals on
	 * some platforms but not others.)	Also, this method avoids exposing
	 * pg_usleep's upper bound on allowed delays.
	 *
	 * By computing the intended stop time initially, we avoid accumulation of
	 * extra delay across multiple sleeps.	This also ensures we won't delay
	 * less than the specified time if pg_usleep is interrupted by other
	 * signals such as SIGHUP.
	 */

#ifdef HAVE_INT64_TIMESTAMP
#define GetNowFloat()	((float8) GetCurrentTimestamp() / 1000000.0)
#else
#define GetNowFloat()	GetCurrentTimestamp()
#endif

	endtime = GetNowFloat() + secs;

	for (;;)
	{
		float8		delay;

		CHECK_FOR_INTERRUPTS();
		delay = endtime - GetNowFloat();
		if (delay >= 1.0)
			pg_usleep(1000000L);
		else if (delay > 0.0)
			pg_usleep((long) ceil(delay * 1000000.0));
		else
			break;
	}

	PG_RETURN_VOID();
}
Exemplo n.º 19
0
/*
 * CheckpointWriteDelay -- control rate of checkpoint
 *
 * This function is called after each page write performed by BufferSync().
 * It is responsible for throttling BufferSync()'s write rate to hit
 * checkpoint_completion_target.
 *
 * The checkpoint request flags should be passed in; currently the only one
 * examined is CHECKPOINT_IMMEDIATE, which disables delays between writes.
 *
 * 'progress' is an estimate of how much of the work has been done, as a
 * fraction between 0.0 meaning none, and 1.0 meaning all done.
 */
void
CheckpointWriteDelay(int flags, double progress)
{
	static int	absorb_counter = WRITES_PER_ABSORB;

	/* Do nothing if checkpoint is being executed by non-checkpointer process */
	if (!AmCheckpointerProcess())
		return;

	/*
	 * Perform the usual duties and take a nap, unless we're behind schedule,
	 * in which case we just try to catch up as quickly as possible.
	 */
	if (!(flags & CHECKPOINT_IMMEDIATE) &&
		!shutdown_requested &&
		!ImmediateCheckpointRequested() &&
		IsCheckpointOnSchedule(progress))
	{
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
			ProcessConfigFile(PGC_SIGHUP);
			/* update shmem copies of config variables */
			UpdateSharedMemoryConfig();
		}

		AbsorbFsyncRequests();
		absorb_counter = WRITES_PER_ABSORB;

		CheckArchiveTimeout();

		/*
		 * Report interim activity statistics to the stats collector.
		 */
		pgstat_send_bgwriter();

		/*
		 * This sleep used to be connected to bgwriter_delay, typically 200ms.
		 * That resulted in more frequent wakeups if not much work to do.
		 * Checkpointer and bgwriter are no longer related so take the Big
		 * Sleep.
		 */
		pg_usleep(100000L);
	}
	else if (--absorb_counter <= 0)
	{
		/*
		 * Absorb pending fsync requests after each WRITES_PER_ABSORB write
		 * operations even when we don't sleep, to prevent overflow of the
		 * fsync request queue.
		 */
		AbsorbFsyncRequests();
		absorb_counter = WRITES_PER_ABSORB;
	}
}
Exemplo n.º 20
0
/*
 * pgarch_ArchiverCopyLoop
 *
 * Archives all outstanding xlogs then returns
 */
static void
pgarch_ArchiverCopyLoop(void)
{
	char		xlog[MAX_XFN_CHARS + 1];

	if (!XLogArchiveCommandSet())
	{
		ereport(WARNING,
		   (errmsg("archive_mode enabled, yet archive_command is not set")));
		/* can't do anything if no command ... */
		return;
	}

	/*
	 * loop through all xlogs with archive_status of .ready and archive
	 * them...mostly we expect this to be a single file, though it is possible
	 * some backend will add files onto the list of those that need archiving
	 * while we are still copying earlier archives
	 */
	while (pgarch_readyXlog(xlog))
	{
		int			failures = 0;

		for (;;)
		{
			/*
			 * Do not initiate any more archive commands after receiving
			 * SIGTERM, nor after the postmaster has died unexpectedly. The
			 * first condition is to try to keep from having init SIGKILL the
			 * command, and the second is to avoid conflicts with another
			 * archiver spawned by a newer postmaster.
			 */
			if (got_SIGTERM || !PostmasterIsAlive(true))
				return;

			if (pgarch_archiveXlog(xlog))
			{
				/* successful */
				pgarch_archiveDone(xlog);
				break;			/* out of inner retry loop */
			}
			else
			{
				if (++failures >= NUM_ARCHIVE_RETRIES)
				{
					ereport(WARNING,
							(errmsg("transaction log file \"%s\" could not be archived: too many failures",
									xlog)));
					return;		/* give up archiving for now */
				}
				pg_usleep(1000000L);	/* wait a bit before retrying */
			}
		}
	}
}
Exemplo n.º 21
0
/*
 * BgWriterNap -- Nap for the configured time or until a signal is received.
 */
static void
BgWriterNap(void)
{
	long		udelay;

	/*
	 * Send off activity statistics to the stats collector
	 */
	pgstat_send_bgwriter();

	/*
	 * Nap for the configured time, or sleep for 10 seconds if there is no
	 * bgwriter activity configured.
	 *
	 * On some platforms, signals won't interrupt the sleep.  To ensure we
	 * respond reasonably promptly when someone signals us, break down the
	 * sleep into 1-second increments, and check for interrupts after each
	 * nap.
	 *
	 * We absorb pending requests after each short sleep.
	 */
	if (bgwriter_lru_maxpages > 0 || ckpt_active)
		udelay = BgWriterDelay * 1000L;
	else if (XLogArchiveTimeout > 0)
		udelay = 1000000L;		/* One second */
	else
		udelay = 10000000L;		/* Ten seconds */

	while (udelay > 999999L)
	{
		if (got_SIGHUP || shutdown_requested ||
		(ckpt_active ? ImmediateCheckpointRequested() : checkpoint_requested))
			break;
		pg_usleep(1000000L);
		AbsorbFsyncRequests();
		udelay -= 1000000L;
	}

	if (!(got_SIGHUP || shutdown_requested ||
	  (ckpt_active ? ImmediateCheckpointRequested() : checkpoint_requested)))
		pg_usleep(udelay);
}
Exemplo n.º 22
0
/*
 * pgarch_MainLoop
 *
 * Main loop for archiver
 */
static void
pgarch_MainLoop(void)
{
	time_t		last_copy_time = 0;

	/*
	 * We run the copy loop immediately upon entry, in case there are
	 * unarchived files left over from a previous database run (or maybe the
	 * archiver died unexpectedly).  After that we wait for a signal or
	 * timeout before doing more.
	 */
	wakened = true;

	do
	{
		/* Check for config update */
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
			ProcessConfigFile(PGC_SIGHUP);
			if (!XLogArchivingActive())
				break;			/* user wants us to shut down */
		}

		/* Do what we're here for */
		if (wakened)
		{
			wakened = false;
			pgarch_ArchiverCopyLoop();
			last_copy_time = time(NULL);
		}

		/*
		 * There shouldn't be anything for the archiver to do except to wait
		 * for a signal ... however, the archiver exists to protect our data,
		 * so she wakes up occasionally to allow herself to be proactive.
		 *
		 * On some platforms, signals won't interrupt the sleep.  To ensure we
		 * respond reasonably promptly when someone signals us, break down the
		 * sleep into 1-second increments, and check for interrupts after each
		 * nap.
		 */
		while (!(wakened || got_SIGHUP))
		{
			time_t		curtime;

			pg_usleep(1000000L);
			curtime = time(NULL);
			if ((unsigned int) (curtime - last_copy_time) >=
				(unsigned int) PGARCH_AUTOWAKE_INTERVAL)
				wakened = true;
		}
	} while (PostmasterIsAlive(true));
}
Exemplo n.º 23
0
int
FileWrite(File file, char *buffer, int amount)
{
    int			returnCode;

    Assert(FileIsValid(file));

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

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

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;
    }

    return returnCode;
}
Exemplo n.º 24
0
Datum
lock_test2(PG_FUNCTION_ARGS)
{
	Oid			table_oid;
	text	   *lock_type;
	float8		sleep_time;
	const char *lock_type_str;
	LOCKMODE	lockmode;
	Relation	heapRelation;

	table_oid	= PG_GETARG_OID(0);
	lock_type	= PG_GETARG_TEXT_P(1);
	sleep_time	= PG_GETARG_FLOAT8(2);

	lock_type_str = text_to_cstring(lock_type);

	if (pg_strcasecmp(lock_type_str, "NOLOCK") == 0)
		lockmode = NoLock;
	else if (pg_strcasecmp(lock_type_str, "ACCESSSHARELOCK") == 0)
		lockmode = AccessShareLock;
	else if (pg_strcasecmp(lock_type_str, "ROWSHARELOCK") == 0)
		lockmode = RowShareLock;
	else if (pg_strcasecmp(lock_type_str, "ROWEXCLUSIVELOCK") == 0)
		lockmode = RowExclusiveLock;
	else if (pg_strcasecmp(lock_type_str, "SHAREUPDATEEXCLUSIVELOCK") == 0)
		lockmode = ShareUpdateExclusiveLock;
	else if (pg_strcasecmp(lock_type_str, "SHARELOCK") == 0)
		lockmode = ShareLock;
	else if (pg_strcasecmp(lock_type_str, "SHAREEXCLUSIVELOCK") == 0)
		lockmode = ShareRowExclusiveLock;
	else if (pg_strcasecmp(lock_type_str, "EXCLUSIVELOCK") == 0)
		lockmode = ExclusiveLock;
	else if (pg_strcasecmp(lock_type_str, "ACCESSEXCLUSIVELOCK") == 0)
		lockmode = AccessExclusiveLock;
	else
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("\"lock_mode\" is set to invalid string: %s", lock_type_str),
				 errhint("\"lock_mode\" must select one among NoLock, AccessShareLock, RowShareLock, RowExclusiveLock, ShareUpdateExclusiveLock, ShareLock, ShareExclusiveLock, ExclusiveLock, and AccessExclusiveLock")));

	elog(NOTICE, "enter lock %d as %s", table_oid, lock_type_str);

	heapRelation = relation_open(table_oid, lockmode);

	elog(NOTICE, "succeed locking %d as %s", table_oid, lock_type_str);

	pg_usleep(sleep_time * 1000000L);

	relation_close(heapRelation, lockmode);

	elog(NOTICE, "exit lock %d as %s", table_oid, lock_type_str);

	PG_RETURN_VOID();
}
Exemplo n.º 25
0
void
PleaseDebugMe(char *caller)
{
	int i;

	for (i = 0; i < 300;i++)
	{
		elog(LOG, "%s  --> Now would be a good time to debug pid = %d", caller, MyProcPid);
		elog(NOTICE, "%s  --> Now would be a good time to debug pid = %d", caller, MyProcPid);
		pg_usleep(1000000L);
	}
}
Exemplo n.º 26
0
/*
 * Stop walreceiver (if running) and wait for it to die.
 * Executed by the Startup process.
 */
void
ShutdownWalRcv(void)
{
	WalRcvData *walrcv = WalRcv;
	pid_t		walrcvpid = 0;

	/*
	 * Request walreceiver to stop. Walreceiver will switch to WALRCV_STOPPED
	 * mode once it's finished, and will also request postmaster to not
	 * restart itself.
	 */
	SpinLockAcquire(&walrcv->mutex);
	switch (walrcv->walRcvState)
	{
		case WALRCV_STOPPED:
			break;
		case WALRCV_STARTING:
			walrcv->walRcvState = WALRCV_STOPPED;
			break;

		case WALRCV_STREAMING:
		case WALRCV_WAITING:
		case WALRCV_RESTARTING:
			walrcv->walRcvState = WALRCV_STOPPING;
			/* fall through */
		case WALRCV_STOPPING:
			walrcvpid = walrcv->pid;
			break;
	}
	SpinLockRelease(&walrcv->mutex);

	/*
	 * Signal walreceiver process if it was still running.
	 */
	if (walrcvpid != 0)
		kill(walrcvpid, SIGTERM);

	/*
	 * Wait for walreceiver to acknowledge its death by setting state to
	 * WALRCV_STOPPED.
	 */
	while (WalRcvRunning())
	{
		/*
		 * This possibly-long loop needs to handle interrupts of startup
		 * process.
		 */
		HandleStartupProcInterrupts();

		pg_usleep(100000);		/* 100ms */
	}
}
Exemplo n.º 27
0
/*
 * pgarch_MainLoop
 *
 * Main loop for archiver
 */
static void
pgarch_MainLoop(void)
{
	time_t		last_copy_time = 0;
	time_t		curtime;

	/*
	 * We run the copy loop immediately upon entry, in case there are
	 * unarchived files left over from a previous database run (or maybe the
	 * archiver died unexpectedly).  After that we wait for a signal or
	 * timeout before doing more.
	 */
	wakened = true;

	do
	{

		/* Check for config update */
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
			ProcessConfigFile(PGC_SIGHUP);
			if (!XLogArchivingActive())
				break;			/* user wants us to shut down */
		}

		/* Do what we're here for */
		if (wakened)
		{
			wakened = false;
			pgarch_ArchiverCopyLoop();
			last_copy_time = time(NULL);
		}

		/*
		 * There shouldn't be anything for the archiver to do except to wait
		 * for a signal, ... however, the archiver exists to protect our data,
		 * so she wakes up occasionally to allow herself to be proactive. In
		 * particular this avoids getting stuck if a signal arrives just
		 * before we sleep.
		 */
		if (!wakened)
		{
			pg_usleep(PGARCH_AUTOWAKE_INTERVAL * 1000000L);

			curtime = time(NULL);
			if ((unsigned int) (curtime - last_copy_time) >=
				(unsigned int) PGARCH_AUTOWAKE_INTERVAL)
				wakened = true;
		}
	} while (PostmasterIsAlive(true));
}
Exemplo n.º 28
0
/*
 * CustomizableNextWALFileReady()
 *
 *	  Is the requested file ready yet?
 */
static bool
CustomizableNextWALFileReady()
{
	if (stat(WALFilePath, &stat_buf) == 0)
	{
		/*
		 * If it's a backup file, return immediately. If it's a regular file
		 * return only if it's the right size already.
		 */
		if (strlen(nextWALFileName) > 24 &&
			strspn(nextWALFileName, "0123456789ABCDEF") == 24 &&
		strcmp(nextWALFileName + strlen(nextWALFileName) - strlen(".backup"),
			   ".backup") == 0)
		{
			nextWALFileType = XLOG_BACKUP_LABEL;
			return true;
		}
		else if (stat_buf.st_size == XLOG_SEG_SIZE)
		{
#ifdef WIN32

			/*
			 * Windows 'cp' sets the final file size before the copy is
			 * complete, and not yet ready to be opened by pg_standby. So we
			 * wait for sleeptime secs before attempting to restore. If that
			 * is not enough, we will rely on the retry/holdoff mechanism.
			 * GNUWin32's cp does not have this problem.
			 */
			pg_usleep(sleeptime * 1000000L);
#endif
			nextWALFileType = XLOG_DATA;
			return true;
		}

		/*
		 * If still too small, wait until it is the correct size
		 */
		if (stat_buf.st_size > XLOG_SEG_SIZE)
		{
			if (debug)
			{
				fprintf(stderr, "file size greater than expected\n");
				fflush(stderr);
			}
			exit(3);
		}
	}

	return false;
}
Exemplo n.º 29
0
/*
 * CustomizableNextWALFileReady()
 * 
 *	  Is the requested file ready yet?
 */
static bool 
CustomizableNextWALFileReady()
{
	if (stat(WALFilePath, &stat_buf) == 0)
	{
		/*
		 * If its a backup file, return immediately
		 * If its a regular file return only if its the right size already
		 */
		if (strlen(nextWALFileName) > 24 &&
			strspn(nextWALFileName, "0123456789ABCDEF") == 24 &&
			strcmp(nextWALFileName + strlen(nextWALFileName) - strlen(".backup"),
				   ".backup") == 0)
		{
			nextWALFileType = XLOG_BACKUP_LABEL;
   			return true;
		}
		else
			if (stat_buf.st_size == XLOG_SEG_SIZE)
			{
#ifdef WIN32
				/*
				 * Windows reports that the file has the right number of bytes
				 * even though the file is still being copied and cannot be
				 * opened by pg_standby yet. So we wait for sleeptime secs
				 * before attempting to restore. If that is not enough, we
				 * will rely on the retry/holdoff mechanism.
				 */
			    pg_usleep(sleeptime * 1000000L);
#endif
				nextWALFileType = XLOG_DATA;
				return true;
			}

		/*
		 * If still too small, wait until it is the correct size
		 */
		if (stat_buf.st_size > XLOG_SEG_SIZE)
		{
			if (debug)
			{
			  	fprintf(stderr, "file size greater than expected\n");
				fflush(stderr);
			}
			exit(3); 
		}
	}

	return false;
}
Exemplo n.º 30
0
/*
 * Stop walreceiver (if running) and wait for it to die.
 */
void
ShutdownWalRcv(void)
{
	/* use volatile pointer to prevent code rearrangement */
	volatile WalRcvData *walrcv = WalRcv;
	pid_t walrcvpid = 0;

	/*
	 * Request walreceiver to stop. Walreceiver will switch to WALRCV_STOPPED
	 * mode once it's finished, and will also request postmaster to not
	 * restart itself.
	 */
	spin_lock(&walrcv->mutex);
	switch (walrcv->walRcvState) {
	case WALRCV_STOPPED:
		break;
	case WALRCV_STARTING:
		walrcv->walRcvState = WALRCV_STOPPED;
		break;

	case WALRCV_RUNNING:
		walrcv->walRcvState = WALRCV_STOPPING;
		/* fall through */
	case WALRCV_STOPPING:
		walrcvpid = walrcv->pid;
		break;
	}

	spin_unlock(&walrcv->mutex);

	/*
	 * Signal walreceiver process if it was still running.
	 */
	if (walrcvpid != 0)
		kill(walrcvpid, SIGTERM);

	/*
	 * Wait for walreceiver to acknowledge its death by setting state to
	 * WALRCV_STOPPED.
	 */
	while (walrcv_in_progress()) {
		/*
		 * This possibly-long loop needs to handle interrupts of startup
		 * process.
		 */
		handle_startup_proc_intr();
		pg_usleep(100000);		/* 100ms */
	}
}