in automation/tinc/main/ext/qautils/gppylib/operations/buildMirrorSegments.py [0:0]
def buildMirrors(self, actionName, gpEnv, gpArray):
"""
Build the mirrors.
gpArray must have already been altered to have updated directories -- that is, the failoverSegments
from the mirrorsToBuild must be present in gpArray.
"""
testOutput("building %s segment(s)" % len(self.__mirrorsToBuild))
if len(self.__mirrorsToBuild) == 0:
logger.info("No segments to " + actionName)
return
self.checkForPortAndDirectoryConflicts(gpArray)
logger.info("%s segment(s) to %s" % (len(self.__mirrorsToBuild), actionName))
self.__verifyGpArrayContents(gpArray)
# make sure the target directories are up-to-date
# by cleaning them, if needed, and then copying a basic directory there
# the postgresql.conf in that basic directory will need updating (to change the port)
toStopDirectives = []
toEnsureMarkedDown = []
cleanupDirectives = []
copyDirectives = []
for toRecover in self.__mirrorsToBuild:
if toRecover.getFailedSegment() is not None:
# will stop the failed segment. Note that we do this even if we are recovering to a different location!
toStopDirectives.append(GpStopSegmentDirectoryDirective(toRecover.getFailedSegment()))
if toRecover.getFailedSegment().getSegmentStatus() == gparray.STATUS_UP:
toEnsureMarkedDown.append(toRecover.getFailedSegment())
if toRecover.isFullSynchronization():
isTargetReusedLocation = False
if toRecover.getFailedSegment() is not None and \
toRecover.getFailoverSegment() is None:
#
# We are recovering a failed segment in-place
#
cleanupDirectives.append(GpCleanupSegmentDirectoryDirective(toRecover.getFailedSegment()))
isTargetReusedLocation = True
if toRecover.getFailoverSegment() is not None:
targetSegment = toRecover.getFailoverSegment()
else: targetSegment = toRecover.getFailedSegment()
d = GpCopySegmentDirectoryDirective(toRecover.getLiveSegment(), targetSegment, isTargetReusedLocation)
copyDirectives.append(d)
self.__ensureStopped(gpEnv, toStopDirectives)
self.__ensureMarkedDown(gpEnv, toEnsureMarkedDown)
self.__cleanUpSegmentDirectories(cleanupDirectives)
self.__copySegmentDirectories(gpEnv, gpArray, copyDirectives)
# update and save metadata in memory
for toRecover in self.__mirrorsToBuild:
if toRecover.getFailoverSegment() is None:
# we are recovering the lost segment in place
seg = toRecover.getFailedSegment()
else:
seg = toRecover.getFailedSegment()
# no need to update the failed segment's information -- it is
# being overwritten in the configuration with the failover segment
for gpArraySegment in gpArray.getDbList():
if gpArraySegment is seg:
raise Exception("failed segment should not be in the new configuration if failing over to new segment")
seg = toRecover.getFailoverSegment()
seg.setSegmentStatus(gparray.STATUS_DOWN) # down initially, we haven't started it yet
seg.setSegmentMode(gparray.MODE_RESYNCHRONIZATION)
# figure out what needs to be started or transitioned
mirrorsToStart = []
primariesToConvert = []
convertPrimaryUsingFullResync = []
fullResyncMirrorDbIds = {}
for toRecover in self.__mirrorsToBuild:
seg = toRecover.getFailoverSegment()
if seg is None:
seg = toRecover.getFailedSegment() # we are recovering in place
mirrorsToStart.append(seg)
primarySeg = toRecover.getLiveSegment()
# The change in configuration to of the mirror to down requires
# that the primary also be change to change tracking if required.
if primarySeg.getSegmentMode() != gparray.MODE_CHANGELOGGING:
primarySeg.setSegmentMode(gparray.MODE_CHANGELOGGING)
primariesToConvert.append(primarySeg)
convertPrimaryUsingFullResync.append(toRecover.isFullSynchronization())
if toRecover.isFullSynchronization() and seg.getSegmentDbId() > 0:
fullResyncMirrorDbIds[seg.getSegmentDbId()] = True
# should use mainUtils.getProgramName but I can't make it work!
programName = os.path.split(sys.argv[0])[-1]
# Disable Ctrl-C, going to save metadata in database and transition segments
signal.signal(signal.SIGINT,signal.SIG_IGN)
try:
logger.info("Updating configuration with new mirrors")
configInterface.getConfigurationProvider().updateSystemConfig(
gpArray,
"%s: segment config for resync" % programName,
dbIdToForceMirrorRemoveAdd = fullResyncMirrorDbIds,
useUtilityMode = False,
allowPrimary = False
)
MPP_12038_fault_injection()
logger.info("Updating mirrors")
self.__updateGpIdFile(gpEnv, gpArray, mirrorsToStart)
logger.info("Starting mirrors")
self.__startAll(gpEnv, gpArray, mirrorsToStart)
logger.info("Updating configuration to mark mirrors up")
for seg in mirrorsToStart:
seg.setSegmentStatus(gparray.STATUS_UP)
for seg in primariesToConvert:
seg.setSegmentMode(gparray.MODE_RESYNCHRONIZATION)
configInterface.getConfigurationProvider().updateSystemConfig(
gpArray,
"%s: segment resync marking mirrors up and primaries resync" % programName,
dbIdToForceMirrorRemoveAdd = {},
useUtilityMode = True,
allowPrimary = False
)
MPP_12038_fault_injection()
#
# note: converting the primaries may take a really long time to complete because of initializing
# resynchronization
#
logger.info("Updating primaries")
self.__convertAllPrimaries(gpEnv, gpArray, primariesToConvert, convertPrimaryUsingFullResync)
logger.info("Done updating primaries")
finally:
# Reenable Ctrl-C
signal.signal(signal.SIGINT,signal.default_int_handler)