/* * Request the fault-prober to suspend probes -- no fault actions will * be taken based on in-flight probes until the prober is unpaused. */ bool gpvars_assign_gp_fts_probe_pause(bool newval, bool doit, GucSource source) { if (doit) { /* * We only want to do fancy stuff on the master (where we have a prober). */ if (ftsProbeInfo && AmIMaster()) { /* * fts_pauseProbes is externally set/cleared; * fts_cancelProbes is externally set and cleared by FTS */ ftsLock(); ftsProbeInfo->fts_pauseProbes = newval; ftsProbeInfo->fts_discardResults = ftsProbeInfo->fts_discardResults || newval; ftsUnlock(); /* * If we're unpausing, we want to force the prober to * re-read everything. (we want FtsNotifyProber()). */ if (!newval) { FtsNotifyProber(); } } gp_fts_probe_pause = newval; } return true; }
static void FtsLoop() { bool updated_bitmap, processing_fullscan; MemoryContext probeContext = NULL, oldContext = NULL; time_t elapsed, probe_start_time; probeContext = AllocSetContextCreate(TopMemoryContext, "FtsProbeMemCtxt", ALLOCSET_DEFAULT_INITSIZE, /* always have some memory */ ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); readCdbComponentInfoAndUpdateStatus(probeContext); for (;;) { if (shutdown_requested) break; /* no need to live on if postmaster has died */ if (!PostmasterIsAlive(true)) exit(1); if (got_SIGHUP) { got_SIGHUP = false; ProcessConfigFile(PGC_SIGHUP); } probe_start_time = time(NULL); ftsLock(); /* atomically clear cancel flag and check pause flag */ bool pauseProbes = ftsProbeInfo->fts_pauseProbes; ftsProbeInfo->fts_discardResults = false; ftsUnlock(); if (pauseProbes) { if (gp_log_fts >= GPVARS_VERBOSITY_VERBOSE) elog(LOG, "skipping probe, we're paused."); goto prober_sleep; } if (cdb_component_dbs != NULL) { freeCdbComponentDatabases(cdb_component_dbs); cdb_component_dbs = NULL; } if (ftsProbeInfo->fts_probeScanRequested == ftsProbeInfo->fts_statusVersion) processing_fullscan = true; else processing_fullscan = false; readCdbComponentInfoAndUpdateStatus(probeContext); getFailoverStrategy(&failover_strategy); elog(DEBUG3, "FTS: starting %s scan with %d segments and %d contents", (processing_fullscan ? "full " : ""), cdb_component_dbs->total_segment_dbs, cdb_component_dbs->total_segments); /* * We probe in a special context, some of the heap access * stuff palloc()s internally */ oldContext = MemoryContextSwitchTo(probeContext); /* probe segments */ FtsProbeSegments(cdb_component_dbs, scan_status); /* * Now we've completed the scan, update shared-memory. if we * change anything, we return true. */ updated_bitmap = probePublishUpdate(scan_status); MemoryContextSwitchTo(oldContext); /* free any pallocs we made inside probeSegments() */ MemoryContextReset(probeContext); cdb_component_dbs = NULL; if (!FtsIsActive()) { if (gp_log_fts >= GPVARS_VERBOSITY_VERBOSE) elog(LOG, "FTS: skipping probe, FTS is paused or shutting down."); goto prober_sleep; } /* * If we're not processing a full-scan, but one has been requested; we start over. */ if (!processing_fullscan && ftsProbeInfo->fts_probeScanRequested == ftsProbeInfo->fts_statusVersion) continue; /* * bump the version (this also serves as an acknowledgement to * a probe-request). */ if (updated_bitmap || processing_fullscan) { ftsProbeInfo->fts_statusVersion = ftsProbeInfo->fts_statusVersion + 1; rescan_requested = false; } /* if no full-scan has been requested, we can sleep. */ if (ftsProbeInfo->fts_probeScanRequested >= ftsProbeInfo->fts_statusVersion) { /* we need to do a probe immediately */ elog(LOG, "FTS: skipping sleep, requested version: %d, current version: %d.", (int)ftsProbeInfo->fts_probeScanRequested, (int)ftsProbeInfo->fts_statusVersion); continue; } prober_sleep: { /* check if we need to sleep before starting next iteration */ elapsed = time(NULL) - probe_start_time; if (elapsed < gp_fts_probe_interval && !shutdown_requested) { pg_usleep((gp_fts_probe_interval - elapsed) * USECS_PER_SEC); } } } /* end server loop */ return; }