Роль и база для приложения
Новый пароль — ALTER ROLE appuser PASSWORD '…';, список ролей — \du в
psql, баз — \l.
PostgreSQL — реляционная СУБД: роли и базы, правила доступа pg_hba.conf, дамп pg_dump и восстановление pg_restore.
sudo systemctl start postgresql
в лабах служба выключена
pg_lsclusters
версия, порт, статус
sudo -u postgres psql
консоль суперпользователя
psql -h 127.0.0.1 -U appuser -d appdb
вход по TCP с паролем
sudo -u postgres psql -c 'TABLE pg_hba_file_rules'
правила доступа
sudo ss -tlnp | grep 5432
на каком адресе слушает
sudo -u postgres pg_dump -Fc -f /tmp/appdb.dump appdb
sudo -u postgres pg_restore -l /tmp/appdb.dump
оглавление
PostgreSQL — реляционная СУБД. Служба postgresql под systemd. В
Ubuntu сервер называется кластером: 16/main — версия и имя. Данные — в
/var/lib/postgresql/16/main, конфиги — в /etc/postgresql/16/main/, журнал
— /var/log/postgresql/postgresql-16-main.log.
Внутри сервера свои учётные записи — роли. Роль
postgres — суперпользователь. Роль и пользователь Linux — разные вещи:
psql -U appuser входит ролью appuser, кем бы ты ни был в системе.
Сервер проверяет подключение по очереди, и у каждой проверки свой отказ:
| Проверка | Что смотрит | Отказ |
|---|---|---|
| сеть | слушает ли сервер адрес и порт или сокет | Connection refused |
| правило | есть ли строка в pg_hba.conf |
no pg_hba.conf entry |
| вход | пароль или peer из этой строки | authentication failed |
psql без -h подключается через сокет
/var/run/postgresql/.s.PGSQL.5432 — для него действуют строки local, по
умолчанию peer. С -h 127.0.0.1 — по TCP, строки
host и пароль.
Два файла в /etc/postgresql/16/main/: postgresql.conf — параметры сервера,
pg_hba.conf — кто и как может войти. Какие файлы и значения сервер прочитал
на самом деле — SHOW hba_file;, SHOW listen_addresses;.
pg_hba.conf — правила доступа, по строке на правило. В Ubuntu по умолчанию:
| Поле | Что значит |
|---|---|
| TYPE | local — через сокет, host — по TCP |
| DATABASE | имя базы или all |
| USER | роль или all |
| ADDRESS | адрес клиента с маской; у local пусто |
| METHOD | как проверять: peer, scram-sha-256, reject |
peer пускает пользователя Linux только в роль с тем же именем, поэтому
суперпользователь входит как sudo -u postgres psql. scram-sha-256 —
пароль. reject — отказ без проверки.
Строки читаются сверху вниз, действует первая подходящая, остальные не
смотрятся. Строка reject выше разрешающей закрывает доступ даже с верным
паролем. Новое правило для конкретной базы и роли ставь выше общих.
Правку применяет sudo systemctl reload postgresql или
SELECT pg_reload_conf();. Что сервер прочитал, показывает представление
pg_hba_file_rules: номер строки, поля и столбец error. С ошибкой в файле
сервер его не принимает и работает по старым правилам, а в журнале —
pg_hba.conf was not reloaded.
По умолчанию listen_addresses = 'localhost' — только 127.0.0.1 и ::1, порт
5432. Чтобы принимать подключения из сети, нужны три вещи: адрес в
listen_addresses ('*' — все), строка host для адреса клиента в
pg_hba.conf и открытый порт в файрволе. listen_addresses
меняется только через sudo systemctl restart postgresql: после reload
параметр помечен pending_restart, а сервер слушает по-старому.
Свою настройку удобно держать отдельным файлом: postgresql.conf читает
каталог conf.d рядом с собой (include_dir = 'conf.d'), и обновление
пакета такой файл не трогает:
conf.d читается после строки include_dir в конце postgresql.conf, и
действует последнее значение. С listen_addresses = '*' в
postgresql.conf и '127.0.0.1' в conf.d/listen.conf сервер слушает
127.0.0.1. Откуда взято значение и ждёт ли оно перезапуска, показывает
pg_settings:
После правки файла и reload значение прежнее, pending_restart — t, а
в журнале /var/log/postgresql/postgresql-16-main.log:
Каждую строку каждого файла с её судьбой показывает pg_file_settings
(applied, error — например, setting could not be applied).
| Директива | Что делает | Пример |
|---|---|---|
listen_addresses postgresql.conf |
На каких адресах принимать TCP-подключения; '*' — на всех. Меняется только через restart. | listen_addresses = '*' |
port postgresql.conf |
Порт TCP и номер в имени сокета .s.PGSQL.5432. Меняется через restart. | port = 5432 |
password_encryption postgresql.conf |
Как хранить новые пароли ролей; пара к методу scram-sha-256 в pg_hba.conf. | password_encryption = scram-sha-256 |
max_connections postgresql.conf |
Сколько подключений разом; лишние получают too many clients. Меняется через restart. | max_connections = 100 |
log_connections postgresql.conf |
Писать в журнал каждое подключение — видно, с какого адреса и какой ролью входили. | log_connections = on |
local / host pg_hba.conf |
Тип строки — подключение через сокет или по TCP. | host appdb appuser 10.0.0.5/32 scram-sha-256 |
peer / scram-sha-256 / reject pg_hba.conf |
Метод проверки: имя пользователя Linux, пароль или отказ без проверки. | local all postgres peer |
Ничего не найдено. Попробуй запрос короче.
Новый пароль — ALTER ROLE appuser PASSWORD '…';, список ролей — \du в
psql, баз — \l.
Строка — адрес:порт:база:роль:пароль, * подходит к любому значению. Режим
— только 600: иначе psql пишет password file … has group or world access
и файл пропускает. Переменная PGPASSWORD важнее файла.
Логический дамп снимает pg_dump — команды и данные, из
которых база создаётся заново. Роли в него не входят: их сохраняет
pg_dumpall --globals-only.
| Формат | Команда | Восстанавливает |
|---|---|---|
| простой SQL | pg_dump -f appdb.sql appdb |
psql -f |
| custom | pg_dump -Fc -f appdb.dump appdb |
pg_restore |
| каталог | pg_dump -Fd -j 4 -f appdb.dir appdb |
pg_restore -j 4 |
Простой SQL читается глазами: CREATE TABLE, COPY с данными, setval для
счётчиков. В начале и в конце — строки \restrict и \unrestrict со случайным
ключом: защита psql от чужих команд в данных, так и должно быть.
Формат custom сжат, начинается с байтов PGDMP и
позволяет посмотреть оглавление и восстановить часть:
Над оглавлением — шапка архива: Archive created at 2026-10-20 10:05:53 UTC,
dbname: appdb и версии сервера. По ней видно, какая это копия и откуда. Данные
одной таблицы без восстановления печатает
pg_restore -f - -t orders /tmp/appdb.dump — определение таблицы и строки
COPY.
Новая пустая база — без конфликтов: код 0. Счётчик
id дамп восстанавливает строкой setval('public.orders_id_seq', 3, true) —
следующая вставка получит id 4.
Владельцы. createdb -O appuser задаёт владельца самой базы. Владельцев таблиц
pg_restore от postgres берёт из архива — строками
ALTER TABLE … OWNER TO appuser, и такая роль должна существовать. С
--no-owner владельцем станет тот, кто восстанавливает, а с
--no-owner --role=r — роль r.
| Ключ pg_restore | Что делает |
|---|---|
-l |
только оглавление архива |
-L список |
восстановить строки оглавления из файла |
-f - |
напечатать SQL вместо записи в базу |
--exit-on-error |
остановиться на первой ошибке |
--single-transaction |
всё или ничего: при ошибке откат |
--clean --if-exists |
удалить объекты перед созданием |
--create -d postgres |
создать базу с именем из дампа |
--no-owner --role=r |
владельцем объектов станет роль r |
Одинаковые число строк, сумма выборки и значение счётчика в источнике и копии
— данные совпадают. Владельца таблиц покажет \dt.
connection to server at "127.0.0.1", port 5432 failed: Connection refused
и Is the server running on that host and accepting TCP/IP connections?.
Служба не запущена (pg_lsclusters, systemctl status postgresql) или не
слушает этот адрес: sudo ss -tlnp | grep 5432, SHOW listen_addresses;.
Через сокет то же выглядит как No such file or directory и Is the server
running locally….
FATAL: no pg_hba.conf entry for host "127.0.0.1", user "appuser", database
"appdb", no encryption — ни одна строка не подошла к этому адресу, базе и
роли. Сообщение приходит дважды: psql пробует подключиться с SSL, потом без.
Добавь строку host appdb appuser <адрес>/32 scram-sha-256, reload и
проверь pg_hba_file_rules.
pg_hba.conf rejects connection for host … — подошла строка reject, она
стоит выше разрешающей.
Правило нашлось, пароль не подошёл. Для роли, которой нет, сервер пишет то же
самое — проверь \du. Пароль задаёт ALTER ROLE … PASSWORD; помни, что
PGPASSWORD перекрывает ~/.pgpass. fe_sendauth: no password supplied —
пароль спросили, а взять его неоткуда.
psql -U appuser без -h идёт через сокет, а там правило peer: пользователь
Linux должен называться как роль. Подключайся с -h 127.0.0.1 и паролем или
sudo -u postgres psql. role "student" does not exist — psql без -U берёт
роль по имени пользователя Linux.
Файл не перечитан или перечитан с ошибкой — тогда работают старые правила, а
pg_reload_conf() всё равно возвращает t. Ошибку покажет
SELECT line_number, error FROM pg_hba_file_rules WHERE error IS NOT NULL;,
в журнале — pg_hba.conf was not reloaded.
Восстановление в базу, где объекты уже есть: ошибка на каждом, в конце
pg_restore: warning: errors ignored on restore: 4, код 1, и часть данных
могла лечь поверх. Восстанавливай в новую пустую базу. --single-transaction
при первой ошибке откатывает всё. --create -d postgres при живой базе с тем
же именем — database "appdb" already exists.
pg_restore получил простой SQL — восстанавливай его psql -f. Обратная
ошибка: psql -f на custom-дампе — The input is a PostgreSQL custom-format
dump. Use the pg_restore command-line client….
trust пускает без пароля любого, кто подходит под строку. host all all
0.0.0.0/0 trust открывает все базы каждому, кто дотянется до порта.
--clean удаляет объекты перед созданием. В рабочей базе это замена живых
данных старыми из дампа. Сначала восстанови в отдельную базу и сверь.
start, reload, restart службы.sudo -u postgres.Есть неточность? Сообщить об ошибке в статье