/* * We get here when a session has been idle for a while (waiting for the * client to send us SQL to execute). The idea is to consume less resources while sitting idle, * so we can support more sessions being logged on. * * The expectation is that if the session is logged on, but nobody is sending us work to do, * we want to free up whatever resources we can. Usually it means there is a human being at the * other end of the connection, and that person has walked away from their terminal, or just hasn't * decided what to do next. We could be idle for a very long time (many hours). * * Of course, freeing gangs means that the next time the user does send in an SQL statement, * we need to allocate gangs (at least the writer gang) to do anything. This entails extra work, * so we don't want to do this if we don't think the session has gone idle. * * We can call cleanupIdleReaderGangs() to just free some resources, or cleanupAllIdleGangs() to * free up everything possible on the segDB side. At the moment, I can't find a reason to * use cleanupIdleReaderGangs(), but it we wanted to, we would have two timeouts: The first * when we free the reader gangs, and the second later time free the writer gang. * My current thinking is that it is better to free all the gangs as soon as we decide * the session is idle. * * P.s: Is there anything we can free up on the master (QD) side? I can't think of anything. * */ static void HandleClientWaitTimeout(void) { elog(DEBUG2,"HandleClientWaitTimeout"); /* * cancel the timer, as there is no reason we need it to go off again. */ disable_sig_alarm(false); /* * Free gangs to free up resources on the segDBs. */ if (gangsExist()) { cleanupAllIdleGangs(); } }
/* * FtsHandleGangConnectionFailure is called by createGang during * creating connections return true if error need to be thrown */ bool FtsHandleGangConnectionFailure(SegmentDatabaseDescriptor * segdbDesc, int size) { int i; bool dtx_active; bool reportError = false; bool realFaultFound = false; bool forceRescan=true; for (i = 0; i < size; i++) { if (PQstatus(segdbDesc[i].conn) != CONNECTION_OK) { CdbComponentDatabaseInfo *segInfo = segdbDesc[i].segment_database_info; elog(DEBUG2, "FtsHandleGangConnectionFailure: looking for real fault on segment dbid %d", segInfo->dbid); if (!FtsTestConnection(segInfo, forceRescan)) { elog(DEBUG2, "found fault with segment dbid %d", segInfo->dbid); realFaultFound = true; /* that at least one fault exists is enough, for now */ break; } forceRescan = false; /* only force the rescan on the first call. */ } } if (!realFaultFound) { /* If we successfully tested the gang and didn't notice a * failure, our caller must've seen some kind of transient * failure when the gang was originally constructed ... */ elog(DEBUG2, "FtsHandleGangConnectionFailure: no real fault found!"); return false; } if (!isFTSEnabled()) { return false; } ereport(LOG, (errmsg_internal("FTS: reconfiguration is in progress"))); forceRescan = true; for (i = 0; i < size; i++) { CdbComponentDatabaseInfo *segInfo = segdbDesc[i].segment_database_info; if (PQstatus(segdbDesc[i].conn) != CONNECTION_OK) { if (!FtsTestConnection(segInfo, forceRescan)) { ereport(LOG, (errmsg_internal("FTS: found bad segment with dbid %d", segInfo->dbid), errSendAlert(true))); /* probe process has already marked segment down. */ } forceRescan = false; /* only force rescan on first call. */ } } if (gangsExist()) { reportError = true; disconnectAndDestroyAllGangs(); } /* * KLUDGE: Do not error out if we are attempting a DTM protocol retry */ if (DistributedTransactionContext == DTX_CONTEXT_QD_RETRY_PHASE_2) { return false; } /* is there a transaction active ? */ dtx_active = isCurrentDtxActive(); /* When the error is raised, it will abort the current DTM transaction */ if (dtx_active) { elog((Debug_print_full_dtm ? LOG : DEBUG5), "FtsHandleGangConnectionFailure found an active DTM transaction (returning true)."); return true; } /* * error out if this sets read only flag, at this stage the read only * transaction checking has passed, so error out, but do not error out if * tm is in recovery */ if ((*ftsReadOnlyFlag && !isTMInRecovery()) || reportError) return true; elog((Debug_print_full_dtm ? LOG : DEBUG5), "FtsHandleGangConnectionFailure returning false."); return false; }