LINUX.ORG.RU
решено ФорумAdmin

PostgreSQL не хочет слушать порт на второй сети при загрузке. При старте сервиса все OK.

 ip-адрес, , ,


0

2

Имеется комп с PostgreSQL.

У него на eth0 несколько подсетей (далее нужна будет подсеть 222):

> ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 1c:6f:65:96:54:bc brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.95/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
...
    inet 192.168.222.95/24 brd 192.168.222.255 scope global eth0:7
       valid_lft forever preferred_lft forever

Чтобы PostgreSQL слушал порт на 222 подсети, сделана настройка:
Файл: /etc/postgresql/9.6/main/postgresql.conf
listen_addresses = 'localhost,192.168.222.95'

и
Файл: /etc/postgresql/9.6/main/pg_hba.conf
host    all             all              192.168.222.0/24        md5

Если после внесения этих настроек перезапустить сервис postgresql, то все стартует без ошибок, а порт 5432 слушается на IP-шниках 127.0.0.1 и на 192.168.222.95.

Но если перезагрузить компьютер, то порт 5432 на IP 192.168.222.95 не поднимается.

В логах следующие ошибки:
СООБЩЕНИЕ:  не удалось привязаться к сокету IPv6: Невозможно назначить запрошенный адрес
ПОДСКАЗКА:  Возможно порт 5432 занят другим процессом postmaster? Если нет, повторите попытку через несколько секунд.
СООБЩЕНИЕ:  не удалось привязаться к сокету IPv4: Невозможно назначить запрошенный адрес
ПОДСКАЗКА:  Возможно порт 5432 занят другим процессом postmaster? Если нет, повторите попытку через несколько секунд.
ПРЕДУПРЕЖДЕНИЕ:  не удалось создать принимающий сокет для "192.168.222.95"
СООБЩЕНИЕ:  передача вывода в протокол процессу сбора протоколов
ПОДСКАЗКА:  В дальнейшем протоколы будут выводиться в каталог "pg_log".


Вот здесь я нашел возможную причину: говорят что сервис postgresql стартует раньше, чем инитится сеть, поэтому не на локальном IP PostgreSQL не может подняться.

Тогда я проверяю зависимости сервиса postgresql:
# systemctl list-dependencies postgresql
postgresql.service
● ├─postgresql@9.6-main.service
● ├─postgresql@9.6-main.service
● ├─system.slice
● ├─network-online.target
● │ ├─connman-wait-online.service
● │ └─networking.service
● └─sysinit.target
●   ├─dev-hugepages.mount
●   ├─dev-mqueue.mount
●   ├─keyboard-setup.service
...

Видно, что postgresql@9.6-main.service и network-online.target запускаются в параллель, а надо сделать зависимую загрузку.

Поэтому создаю файл /etc/systemd/system/postgresql.service.d/override.conf следующего содержания:
[Unit]
Requires=network-online.target
After=network-online.target

Потом выполняю:
systemctl daemon-reload
systemctl restart postgresql

И смотрю зависимости через list-dependencies, а они не изменились. Перезагружаюсь - то же самое, зависимости все те же, и PostgreSQL не поднимает свой сокет на 192.168.222.95.

Вопрос: где что еще надо крутить?

★★★★★

Ответ на: комментарий от ksim

разве override не должен быть: /etc/systemd/system/postgresql@.service.d/override.conf

Попробовал так, но при выполнении systemctl list-dependencies (без указания сервиса, чтобы видеть все), тогда network-online.target вообще исчезает из дерева. Я ничего не понимаю.

> systemctl list-dependencies
default.target
● ├─acpi-support.service
● ├─aldd.service
● ├─fly-dm.service
● ├─ntp.service
● ├─parsec.service
● ├─sysstat.service
● ├─systemd-update-utmp-runlevel.service
● └─multi-user.target
●   ├─acpi-support.service
●   ├─aldd.service
●   ├─anacron.service
●   ├─atd.service
●   ├─avahi-daemon.service
●   ├─binfmt-support.service
●   ├─console-setup.service
●   ├─cron.service
●   ├─cups.path
●   ├─dbus.service
●   ├─libflygetexe-bin.service
●   ├─networking.service
●   ├─nscd.service
●   ├─ntp.service
●   ├─ofono.service
●   ├─parlogd.service
●   ├─parsec.service
●   ├─plymouth-quit-wait.service
●   ├─plymouth-quit.service
●   ├─postgresql.service
...

network-online.target - нет нигде, ищу через «/netw», «n»

А вот что с указанием сервиса:
> systemctl list-dependencies postgresql
postgresql.service
● ├─postgresql@9.6-main.service
● ├─postgresql@9.6-main.service
● ├─system.slice
● └─sysinit.target
●   ├─dev-hugepages.mount
●   ├─dev-mqueue.mount
●   ├─keyboard-setup.service
...

Цель network-online.target - куда-то исчезла.

Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 4)
Ответ на: комментарий от ksim
# systemctl list-dependencies postgresql@9.6-main.service
postgresql@9.6-main.service
● ├─system-postgresql.slice
● ├─network-online.target
● │ ├─connman-wait-online.service
● │ └─networking.service
● └─sysinit.target
●   ├─dev-hugepages.mount
●   ├─dev-mqueue.mount
●   ├─keyboard-setup.service
●   ├─kmod-static-nodes.service
●   ├─plymouth-read-write.service
●   ├─plymouth-start.service
●   ├─proc-sys-fs-binfmt_misc.automount
●   ├─quota.service
●   ├─resolvconf.service
●   ├─sys-fs-fuse-connections.mount
●   ├─sys-kernel-config.mount
●   ├─sys-kernel-debug.mount
●   ├─systemd-ask-password-console.path
●   ├─systemd-binfmt.service
●   ├─systemd-hwdb-update.service
●   ├─systemd-journal-flush.service
●   ├─systemd-journald.service
●   ├─systemd-machine-id-commit.service
●   ├─systemd-modules-load.service
●   ├─systemd-random-seed.service
●   ├─systemd-sysctl.service
●   ├─systemd-timesyncd.service
●   ├─systemd-tmpfiles-setup-dev.service
●   ├─systemd-tmpfiles-setup.service
●   ├─systemd-udev-trigger.service
●   ├─systemd-udevd.service
●   ├─systemd-update-utmp.service
●   ├─cryptsetup.target
●   ├─local-fs.target
●   │ ├─-.mount
●   │ ├─boot-efi.mount
●   │ ├─boot.mount
●   │ ├─mnt-workpart.mount
●   │ ├─parsecfs.automount
●   │ ├─systemd-fsck-root.service
●   │ └─systemd-remount-fs.service
●   └─swap.target
●     ├─dev-disk-by\x2duuid-4a6df81b\x2d7aef85bf2120.swap
●     └─dev-sda6.swap



С опцией -a листинг слишком длинный, мне его приходится по COM-порту перебрасывать, он затыкается. Выглядит так:

https://pastebin.com/jSxYu8iN

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea
postgresql@9.6-main.service
● ├─system-postgresql.slice
● ├─network-online.target

ну так всё норм выглядит теперь. postgresql сервис (который таргет) который ждёт запуска всех нод. сами ноды теперь ждут сети.

PS. Так же обращаю внимание, что network-online, не ждёт всех интерфейсов, и разрезолвится при первом поднявшемся.

ksim
()
Последнее исправление: ksim (всего исправлений: 2)
Ответ на: комментарий от ksim

network-online, не ждёт всех интерфейсов, и разрезолвится при первом поднявшемся

Видимо, в этом и проблема. Нужно какием-то волшебным образом дождаться поднятия всех интерфейсов.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

не знаю как это делается с connman по человечески, но /etc/systemd/system/connman-wait-online@.service

[Unit]
Description=Wait for network interface %i to be configured by ConnMan
Requisite=connman.service
After=connman.service
Before=network-online.target
DefaultDependencies=no
Conflicts=shutdown.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/connmand-wait-online -i %i
RemainAfterExit=yes

[Install]
WantedBy=network-online.target

и в постгресе

Requires=connman-wait-online@eth0
After=connman-wait-online@eth0

Опять же не уверен когда connman разрезолвит событие после первого или второго адреса. Можно написать свой скрипт который будет ждать нужного адреса на интерфейсе.

PS. ничего не тестил, может требует настройки где….

ksim
()

порт 5432 на IP 192.168.222.95 не поднимается

Кто назначает интерфейсу этот адрес?

network-online.target сам по себе не делает ничего. Тебе нужно настроить свой сетевой менеджер, чтобы он подцеплялся к этому таргету.

intelfx ★★★★★
()
Ответ на: комментарий от ksim

не знаю как это делается с connman по человечески, но /etc/systemd/system/connman-wait-online@.service

У меня сейчас есть файл-ссылка:

/etc/systemd/system/network-online.target.wants/connman-wait-online.service 

-> 

/lib/systemd/system/connman-wait-online.service

То есть, символа «@» в имени нет как у тебя, и, видимо это не шаблонная цель.(Я пока не понял как работают шаблоны в systemd). Содержимое этого файла следующее:
[Unit]
Description=Wait for network to be configured by ConnMan
Requisite=connman.service
After=connman.service
Before=network-online.target
DefaultDependencies=no
Conflicts=shutdown.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/connmand-wait-online
RemainAfterExit=yes

[Install]
WantedBy=network-online.target

Вот этот файл можно как-то изменить, чтобы он дожидался поднятия всех виртуальных интерфейсов или хотя бы заданного?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Так у тебя не connman, а /etc/network/interfaces. Найди как в твоём сетевом менеджере работает wait-online и включай соответствующий юнит, а не connman’овский.

Или переползай на systemd-networkd, он просто работает.

intelfx ★★★★★
()
Ответ на: комментарий от Xintrea

Судя по датам файлов, connman стоит изначально, ставится вместе с системой. Зачем он устанавливается - не знаю.

Он не активен? Не отвечает за настройку? Вся сеть только через ifupdown?

ksim
()
Ответ на: комментарий от intelfx

Кто назначает интерфейсу этот адрес?
network-online.target сам по себе не делает ничего. Тебе нужно настроить свой сетевой менеджер, чтобы он подцеплялся к этому таргету.

А разве не может быть такого, что в системе не нужен сетевой менеджер, и сеть просто конфигурируется /etc/network/interfaces ?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

А разве не может быть такого, что в системе не нужен сетевой менеджер, и сеть просто конфигурируется /etc/network/interfaces ?

Может. За сеть старого образца отвечает networking.service, смотри, где он поднимается.

Dimez ★★★★★
()
Последнее исправление: Dimez (всего исправлений: 1)
Ответ на: комментарий от ksim

Он не активен? Не отвечает за настройку? Вся сеть только через ifupdown?

UNIT                        LOAD   ACTIVE   SUB  DESCRIPTION
connman-wait-online.service loaded inactive dead Wait for network to be
connman.service             loaded inactive dead Connection service
Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 1)
Ответ на: комментарий от Xintrea

тогда, по идее, network-online.target должно быть достаточно в postgresql@.service, ну или хз как там ifupdown работает, если он выходит до того как закончит конфигурацию интерфейсов, то копать в сторону нормальных менеджеров сети.

ksim
()
Ответ на: комментарий от Xintrea

В может, можно просто какую-то задержку сделать, чтобы сеть со всеми интерфейсами успела подняться?

Я за такое работников увольняю :-)

Уж если хочешь костыль сделать и религия не позволяет перейти на использование нормальных менеджеров сети, сделай сервис который будет ждать появления нужного IP-шника и пропиши его в зависимости postgresql@

ksim
()
Ответ на: комментарий от ksim

Так я не администратор. Мне эти ваши конфигурярования сети и постгреса нафиг не сдались. Мне главное чтобы из других подсетей, которые у меня тоже используются, никто случайно на мой постгрес не запрыгнул. Соединение должно быть либо только локальное, либо только из 222 подсетки. Кто же знал что будет такая жопа с виртуальными интефейсами.

Уж если хочешь костыль сделать и религия не позволяет перейти на использование нормальных менеджеров сети, сделай сервис который будет ждать появления нужного IP-шника и пропиши его в зависимости postgresql@

Походу, это самое простое. А какой командой можно гарантированно проверить что виртуальный интерфейс поднялся?

Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 1)
Ответ на: комментарий от Xintrea

Так я не администратор.

это отмазка, пусть тогда администратор и делает.

А какой командой можно гарантированно проверить что виртуальный интерфейс поднялся?

Напиши вечный цикл bash который grepает ip a, и выходит в случае успеха, его запихнуть в ExecStartPre в service

while ! ip -o -4 a | grep -q '192.168.222.'; do
  sleep 0.2
done

дикие костыли :-( я этого, если что, не советовал.

PS. Вообще другие подсети должны быть VLANами.

ksim
()
Последнее исправление: ksim (всего исправлений: 1)
Ответ на: комментарий от ksim

Так я не администратор.
это отмазка, пусть тогда администратор и делает.

Я бы с радостью, но он не может. Он ужо год проработал и вчера от меня узнал что в python можно завершать функцию командой return. Я, наверно, раньше уволюсь чем он хоть что-то начнет делать.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от ksim

Напиши вечный цикл bash который grepает ip a, и выходит в случае успеха

И что, у меня система перестанет загружаться если в какой-то момент потребуется интерфейс отключить?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

можно просто какую-то задержку сделать

А вот этого совершенно точно делать не нужно, это костыль с непредсказуемым по поведению результатом.

anc ★★★★★
()
Ответ на: комментарий от Xintrea

Я бы с радостью, но он не может. Он ужо год проработал и вчера от меня узнал что в python можно завершать функцию командой return.

А какое отношение знание удава имеет к работе сисадмина?
Ну и что бы два раза не вставать, надеюсь вы не про вариант «впихнуть return посередине функции» ? Вопрос навеян именно вашей фразой «завершать функцию».

anc ★★★★★
()
Ответ на: комментарий от Xintrea

И что, у меня система перестанет загружаться если в какой-то момент потребуется интерфейс отключить?

Ага, похоже это можно разрулить через параметр TimeoutSec.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от anc

А какое отношение знание удава имеет к работе сисадмина?

Предполагается что админ будет заниматься какой-никакой автоматизацией своей работы

Ну и что бы два раза не вставать, надеюсь вы не про вариант «впихнуть return посередине функции» ? Вопрос навеян именно вашей фразой «завершать функцию».

Я про вариант что функция вообще может что-то возвращать. Насколько я понял, он думал что функция нужна для того, что бы что-то делать, а то что она может еще и что-то возвращать - было сюрпризом.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

И что, у меня система перестанет загружаться если в какой-то момент потребуется интерфейс отключить?

ты костыли пишешь, или что? Используй timeout для ограничения времени, можешь в systemd TimeoutStartSec засунуть. ну будет на 30 сек дольше стартовать postgres, это пусть ленивый админ потом решает.

Хочешь совета как решить проблему правильно?

вариант 1, который бы сделал я. bind всех интерфейсов и в firewall расписал бы правила кому можно. Понаделаете подсетей в будущем. Будет одно место для управления, главное админу сказать не забудь.

вариант 2, уже упоминался. Переписал бы управление сетью на тот же systemd-networkd, да и раскидал бы всё по VLANам, чтоб не было на одном физическом интерфейсе несколько подсетей.

ksim
()
Ответ на: комментарий от anc

При том, что если я переконфижу сеть так, что нужного интерфейса не будет, и забуду выключить ожидание в systemd, то рекомендуемый ksim бесконечный цикл никогда не завершится. Поэтому видимо нужно будет TimeoutSec использовать.

Но тогда встает другой вопрос: если сервис-проверялка завершится по таймоуту - значит неудачно - значит весь PostgreSQL не будет запущен?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

цикл никогда не завершится.

по умолчанию timeout у systemd 90 сек, то есть вечный цикл не страшен, разработчики сразу подумали о костылеписателях :-). если поставить -, код выхода проигнорится, в ExecStart пропиши /bin/true, то есть что-то типа:

ExecStartPre=-/usr/bin/timeout 30 /some/whildpath/waitforip.sh 192.168.222
ExecStart=/bin/true

ну и как результат максимальная задержка старта service будет 30 сек или пока ip не появится. Вот тебе и сервис, который ждёт до 30 сек твоего IP.

Можешь ExecStartPre прямо postgres@ override засунуть, будет отыскать проблему потом наверное быстрее.

ksim
()
Последнее исправление: ksim (всего исправлений: 3)
Ответ на: комментарий от Xintrea

Предполагается что админ будет заниматься какой-никакой автоматизацией своей работы

Какое отношение знание или не-знание удава имеет к автоматизации работы админа?

Я про вариант что функция вообще может что-то возвращать. Насколько я понял, он думал что функция нужна для того, что бы что-то делать, а то что она может еще и что-то возвращать - было сюрпризом.

Мы вроде про админа говорим, а не про программиста.

anc ★★★★★
()
Ответ на: комментарий от Xintrea

При том, что если я переконфижу сеть так, что нужного интерфейса не будет, и забуду выключить ожидание в systemd, то рекомендуемый ksim бесконечный цикл никогда не завершится. Поэтому видимо нужно будет TimeoutSec использовать.

И в результате, что в первом, что во втором случае оно так и не запустится и вам в любом случае придется выяснять кто виноват и что делать.

anc ★★★★★
()
Ответ на: комментарий от Xintrea

Забанить тебя чтоли, чтоб ты херню не писал.

А чё ты как недопограммист в доку не могёшь? А тут спрашиваешь по работе одмина? Одминишь? Так делай правильно, а не костыль. А то навернёшь говен, потом БД не стартует, проц нагружен и нихрена не понятно.

Кулхацкеры, ёба.

anonymous
()
Ответ на: комментарий от Xintrea

При том, что если я переконфижу сеть

Чот я туплю, тебе надо чтобы твой постгрес ждал твоего адреса или не надо? Или не всегда а в некоторых случаях?

sin_a ★★★★★
()