Skip to content

Instantly share code, notes, and snippets.

@QQGoblin
Created December 23, 2021 12:36
Show Gist options
  • Save QQGoblin/cc6e63fc40d0ace5ebaac9f65f3c0822 to your computer and use it in GitHub Desktop.
Save QQGoblin/cc6e63fc40d0ace5ebaac9f65f3c0822 to your computer and use it in GitHub Desktop.
【Patroni源码阅读】Postgresql 启动PG
class Postgresql(object):
def start(self, timeout=None, task=None, block_callbacks=False, role=None):
"""Start PostgreSQL
Waits for postmaster to open ports or terminate so pg_isready can be used to check startup completion
or failure.
:returns: True if start was initiated and postmaster ports are open, False if start failed"""
# make sure we close all connections established against
# the former node, otherwise, we might get a stalled one
# after kill -9, which would report incorrect data to
# patroni.
# 关闭之前打开的postgresql连接
self._connection.close()
# postgresql正在运行
if self.is_running():
logger.error('Cannot start PostgreSQL because one is already running.')
self.set_state('starting')
return True
if not block_callbacks:
self.__cb_pending = ACTION_ON_START
self.set_role(role or self.get_postgres_role_from_data_directory())
self.set_state('starting')
self._pending_restart = False
try:
if not self._major_version:
self.configure_server_parameters()
configuration = self.config.effective_configuration
except Exception:
return None
self.config.check_directories()
self.config.write_postgresql_conf(configuration)
self.config.resolve_connection_addresses()
self.config.replace_pg_hba()
self.config.replace_pg_ident()
options = ['--{0}={1}'.format(p, configuration[p]) for p in self.config.CMDLINE_OPTIONS
if p in configuration and p not in ('wal_keep_segments', 'wal_keep_size')]
if self.cancellable.is_cancelled:
return False
with task or null_context():
if task and task.is_cancelled:
logger.info("PostgreSQL start cancelled.")
return False
self._postmaster_proc = PostmasterProcess.start(self.pgcommand('postgres'),
self._data_dir,
self.config.postgresql_conf,
options)
if task:
task.complete(self._postmaster_proc)
start_timeout = timeout
if not start_timeout:
try:
start_timeout = float(self.config.get('pg_ctl_timeout', 60))
except ValueError:
start_timeout = 60
# 等待进程的端口打开
if not self._postmaster_proc or not self.wait_for_port_open(self._postmaster_proc, start_timeout):
return False
# 检查启动是否完成,主要逻辑在 check_startup_state_changed()和pg_isready()接口中,原理是反复调用:pg_isready -U postgres -p 5432, 并且返回信息
# return_codes = {0: STATE_RUNNING,
# 1: STATE_REJECT,
# 2: STATE_NO_RESPONSE,
# 3: STATE_UNKNOWN}
ret = self.wait_for_startup(start_timeout)
if ret is not None:
return ret # True启动成功
elif timeout is not None:
return False
else:
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment