Skip to content

Instantly share code, notes, and snippets.

@QQGoblin
Created December 24, 2021 08:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save QQGoblin/4c80f2b370507cc235fba1a621f57db6 to your computer and use it in GitHub Desktop.
Save QQGoblin/4c80f2b370507cc235fba1a621f57db6 to your computer and use it in GitHub Desktop.
【Patroni源码阅读】处理启动过程中PG(启动超时或者需要failover)
class Ha(object):
def handle_starting_instance(self):
"""Starting up PostgreSQL may take a long time. In case we are the leader we may want to
fail over to."""
# Check if we are in startup, when paused defer to main loop for manual failovers.
if not self.state_handler.check_for_startup() or self.is_paused():
# pg 不是strartup状态或者patroni处于paused状态
self.set_start_timeout(None)
if self.is_paused():
self.state_handler.set_state(self.state_handler.is_running() and 'running' or 'stopped')
return None
# state_handler.state == 'starting' here
# 处理starting状态的pg
if self.has_lock():
# 当前节点是leader
if not self.update_lock():
# 更新Leader状态状态失败,这时可能该节点已经不是leader了
# 此时立即停止pg
logger.info("Lost lock while starting up. Demoting self.")
self.demote('immediate-nolock')
return 'stopped PostgreSQL while starting up because leader key was lost'
# 依然是leader,根据超时时间判断启动逻辑
timeout = self._start_timeout or self.patroni.config['master_start_timeout']
time_left = timeout - self.state_handler.time_in_state()
if time_left <= 0:
# 超时,判断能不能进行主备切换,如果可以立即停止当前的Master
if self.is_failover_possible(self.cluster.members):
logger.info("Demoting self because master startup is taking too long")
self.demote('immediate')
return 'stopped PostgreSQL because of startup timeout'
else:
return 'master start has timed out, but continuing to wait because failover is not possible'
else:
# 还未超时,判断此时是否要failover发生,如果有正常退出postgres进程,并让出leader
msg = self.process_manual_failover_from_leader()
if msg is not None:
return msg
return 'PostgreSQL is still starting up, {0:.0f} seconds until timeout'.format(time_left)
else:
# Use normal processing for standbys
logger.info("Still starting up as a standby.")
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment