Tengo un servidor PostgreSQL ( postgresql.service
) y un script de shell básico ( mobilizon-postgresql.service
que se ejecuta para proporcionar algunas afirmaciones sobre la base de datos a un tercer servicio (Mobilizon).
Naturalmente, mobilizon-postgresql.service
está configurado con una After=
dependencia para postgresql.service
:
# systemctl show mobilizon-postgresql.service | grep After=
After=basic.target system.slice systemd-journald.socket sysinit.target postgresql.service
Aunque después de una reconfiguración del sistema (que no afectó estas dependencias), veo el siguiente comportamiento en los registros:
1677672119.103035 myserver systemd[1]: Starting Mobilizon PostgreSQL setup...
...
1677672119.153192 myserver systemd[1]: Starting PostgreSQL Server...
Entonces, mobilizon-postgresql.service
se iniciaantesel inicio de postgresql.service
.
1677672119.279742 myserver mobilizon-postgresql-start[329444]: psql: error: could not connect to server: No such file or directory
1677672119.279742 myserver mobilizon-postgresql-start[329444]: Is the server running locally and accepting
1677672119.279742 myserver mobilizon-postgresql-start[329444]: connections on Unix domain socket "/run/postgresql/.s.PGSQL.543>
1677672119.283558 myserver systemd[1]: mobilizon-postgresql.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
1677672119.283707 myserver systemd[1]: mobilizon-postgresql.service: Failed with result 'exit-code'.
1677672119.289678 myserver systemd[1]: Failed to start Mobilizon PostgreSQL setup.
Entonces, por supuesto, mobilizon.postgresql
no se puede configurar una conexión a la base de datos.
1677672119.503881 myserver postgres[329458]: [329458] LOG: starting PostgreSQL 13.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11>
1677672119.512541 myserver postgres[329458]: [329458] LOG: listening on IPv4 address "0.0.0.0", port 5432
1677672119.512863 myserver postgres[329458]: [329458] LOG: listening on IPv6 address "::", port 5432
1677672119.519498 myserver postgres[329458]: [329458] LOG: listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
...
1677672119.871989 myserver systemd[1]: Started PostgreSQL Server.
Sólo más tarde postgresql.service
se informa que se ha iniciado por completo.
Este comportamiento va completamente en contra de mi comprensión de After=
. De systemd.unit(5)
:
Si la unidad foo.service contiene la configuración Before=bar.service y ambas unidades se están iniciando, el inicio de bar.service se retrasa hasta que foo.service haya terminado de iniciarse.
¿Estoy teniendo suposiciones erróneas aquí?
La versión de Systemd es 251.12, la distribución es NixOS 22.11
Respuesta1
¿Qué quiere decir systemd con "terminado el inicio"? man systemd.unit
dice
para las unidades de servicio, el inicio se considera completado a los efectos de Antes=/Después= cuando se han invocado todos sus comandos de inicio configurados y fallaron o informaron que el inicio fue exitoso.
Por lo tanto, debe buscar en el archivo de servicio postgresql para ver si está haciendo algo como bifurcar y poner su pid en un archivo, o usarlo sd_notify()
en su código para indicar "listo". No es muy útil.
Lamentablemente, la forma más fácil de solucionar esto es hacer que el mobilizon-postgresql
servicio espere a que exista el socket de dominio Unix, usando inotifywait
o similar, o agregarlo Restart=on-failure
y RestartSec=1
volver a intentarlo hasta que tenga éxito.
La idea de Systemd de cómo deberían funcionar las cosas es que usted crea una unidad de socket y cada vez que alguien intenta abrir ese socket, inicia un programa. En este caso, al iniciar su script, que abre el socket, inicia postgresql.
Respuesta2
(Mostrar unidades completas sería útil, por cierto)
After=
sin Wants=
o Requires=
no tiene el efecto que crees. Como man systemd.unit
se describe (en Before=, After=
):
Tenga en cuenta queesas configuraciones son independientes y ortogonales a las dependencias de requisitossegún lo configurado por
Requires=
,Wants=
,Requisite=
, oBindsTo=
. Es un patrón común incluir un nombre de unidad en las opcionesAfter=
yWants=
, en cuyo caso la unidad enumerada se iniciará antes que la unidad configurada con estas opciones.
(Énfasis añadido por el cartel)