postgresql.service 如何知道要启动哪些 postgresql 实例?

ice*_*bit 3 systemd postgresql

我已经安装的Postgres在Ubuntu 16.04 9.5它创建postgresql.servicepostgresql@.service

我知道postgresql.service生成所有启用的 postgres 实例,我可以调用一个特定的实例,postgresql@9.5-main但它postgresql@.service是一个模板文件,我看不到实例字符串(由模板中的 %i 或 %I 表示)所在的任何地方被路过postgresql.service

如何postgresql.service知道启用了哪些实例,以及如何将它们传递给 systemd 模板文件?

Mar*_*erg 6

To answer this, start with checking the contents of the two files in question. If you aren't sure where to find them, you can search the package contents for systemd files:

 dpkg -L postgresql-common| grep systemd
Run Code Online (Sandbox Code Playgroud)

From looking at the postgresql.service file you can see you not doing much at all:

# systemd service for managing all PostgreSQL clusters on the system. This
# service is actually a systemd target, but we are using a service since
# targets cannot be reloaded.

[Unit]
Description=PostgreSQL RDBMS

[Service]
Type=oneshot
ExecStart=/bin/true
ExecReload=/bin/true
RemainAfterExit=on

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

From the comments, we learn that the file is being used as a systemd "target". Moving on to the template file:

# systemd service template for PostgreSQL clusters. The actual instances will
# be called "postgresql@version-cluster", e.g. "postgresql@9.3-main". The
# variable %i expands to "version-cluster", %I expands to "version/cluster".
# (%I breaks for cluster names containing dashes.)

[Unit]
Description=PostgreSQL Cluster %i
ConditionPathExists=/etc/postgresql/%I/postgresql.conf
PartOf=postgresql.service
ReloadPropagatedFrom=postgresql.service
Before=postgresql.service

[Service]
Type=forking
# @: use "postgresql@%i" as process name
ExecStart=@/usr/bin/pg_ctlcluster postgresql@%i --skip-systemctl-redirect %i start
ExecStop=/usr/bin/pg_ctlcluster --skip-systemctl-redirect -m fast %i stop
ExecReload=/usr/bin/pg_ctlcluster --skip-systemctl-redirect %i reload
PIDFile=/var/run/postgresql/%i.pid
SyslogIdentifier=postgresql@%i
# prevent OOM killer from choosing the postmaster (individual backends will
# reset the score to 0)
OOMScoreAdjust=-900
# restarting automatically will prevent "pg_ctlcluster ... stop" from working,
# so we disable it here. Also, the postmaster will restart by itself on most
# problems anyway, so it is questionable if one wants to enable external
# automatic restarts.
#Restart=on-failure
# (This should make pg_ctlcluster stop work, but doesn't:)
#RestartPreventExitStatus=SIGINT SIGTERM

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

The interesting directives are:

PartOf=postgresql.service
ReloadPropagatedFrom=postgresql.service
Run Code Online (Sandbox Code Playgroud)

If you aren't sure where find the docs for a systemd directive, you can check: man systemd.directives. From there, we find both these directives in man systemd.unit.

Your biggest clue comes when you enable the service:

sudo systemctl enable postgresql@9.6
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql@9.6.service ? /lib/systemd/system/postgresql@.service.
Run Code Online (Sandbox Code Playgroud)

Putting it all together:

  • The symlink is how systemd knows to boot up PostgreSQL 9.6 when the server starts.
  • The PartOf= and ReloadPropagatedFrom= directives handle making sure that stop, start, restart and reload on the postgresql service end up applying to all the related installed PostgreSQL instances.