Сообщество / Базы данных

Дамп восстановился, а приложение не пустили: про роли в PostgreSQL

nesterov
Junior
Сообщения: 45
Репутация: 34
Дата регистрации:
08.08.2026
АВТОР ТЕМЫ31 окт. 2026 г., 17:00 (GMT+3)
Переносил небольшую базу на чистый сервер. Это учёт для знакомой мастерской: заказы, клиенты, пара справочников. Postgres, одна база, одно приложение, которое ходит в неё под своим пользователем. Резервные копии делались каждую ночь через pg_dump в custom-формате и уезжали на другую машину. Пробное восстановление когда-то тоже делали. Казалось, переезд займёт полчаса.

На новом сервере поставил ту же мажорную версию, создал пустую базу и запустил восстановление:

pg_restore -d имя_базы /путь/к/дампу.dump


Полетели строки. Сначала ошибки про владельца: роль такая-то не существует. Потом про GRANT. В конце pg_restore сообщил, что ошибки были, но он их проигнорировал. Таблицы на месте, количество строк сходится с тем, что я записал перед переносом. Формально данные восстановлены.

Приложение при этом не запустилось. Его пользователя на новом сервере просто не было, а все объекты в базе теперь принадлежали postgres, потому что владельца назначить было некому.

Причина простая, и о ней почему-то вспоминают при первом переезде, а не при настройке копий. pg_dump сохраняет одну базу: схему, данные, права на объекты внутри неё. Роли и их пароли к конкретной базе не относятся, они общие для всего кластера. В дамп одной базы они не попадают. Тестовое восстановление когда-то прошло без вопросов, потому что делалось на том же сервере, где все роли уже были.

Выхода два, и они для разных случаев.

Первый — сохранять глобальные объекты отдельно:

pg_dumpall --globals-only > globals.sql


Там роли, их атрибуты, членство в группах, табличные пространства. Нужны права суперпользователя. Восстанавливается этот файл до pg_restore, тогда владельцы и права встают на свои места. Одно предупреждение: в файле лежат хэши паролей ролей. Это не открытый текст, но и не то, что можно хранить рядом с дампом в общей папке. Обращаться с ним стоит как с секретом.

Второй — сознательно отказаться от исходных владельцев:

pg_restore --no-owner --no-privileges --role=новая_роль -d имя_базы дамп.dump


Так объекты достанутся указанной роли, а права потом выдаются заново. Это удобно, когда переносишь базу в другое окружение, где роли и так другие. Но надо понимать, что исходная схема прав теряется. Если в базе было несколько ролей с разным доступом, придётся вспоминать, кому что выдавали.

Я в тот раз пошёл вторым путём: роль одна, восстановить её руками несложно. Потом добавил выгрузку globals в ночное задание и отдельно переписал проверку копии. Раньше проверка была такой: файл есть, размер разумный, pg_restore --list читает оглавление. Это подтверждает, что дамп не битый. Это не подтверждает, что из него можно поднять работающую систему на чистой машине.

Ещё пара мест, которые на чистом сервере могут вести себя иначе, чем на старом. Я их не встретил, но проверяю. Расширения: дамп содержит CREATE EXTENSION, а пакет расширения на новом сервере должен быть установлен. Локаль и правила сортировки базы: если на новой системе другая библиотека сортировки, порядок строк и индексы по тексту могут вести себя не так, как вы привыкли. Про это у Postgres есть отдельные предупреждения в документации, лучше прочитать до переноса, а не после.

В итоге для себя я перестал считать копией один файл дампа. Копия — это дамп, globals, записка с версией Postgres и списком расширений, и одна проверка на машине, где нет ничего от старого сервера.

Кому интересно сравнить: как вы храните глобальные объекты? Отдельным файлом рядом с дампом, в менеджере секретов, или роли у вас описаны в коде развёртывания и из копий их сознательно исключают? Последний вариант мне кажется чище, но я его ни разу не доводил до конца на маленьком проекте, где всё держится на одном человеке.
0
C
che32
Junior
Сообщения: 34
Репутация: 30
Дата регистрации:
05.09.2026
31 окт. 2026 г., 18:08 (GMT+3)
Дочитал и пошёл смотреть, что у меня дома копируется. За кинетиком стоит мини-ПК с семейным фотоархивом, внутри постгрес. Каждую ночь дамп уезжает на флешку, воткнутую в роутер. Скрипт я писал сам год назад и, честно, им гордился.

Открыл его. Одна строка: pg_dump, база, файл. Про роли ни слова. Выходит, при переезде фотки жены я восстановлю, а приложение спросит, кто я такой. Это не резервная копия, это сувенир на память о том, что копия была.

Дописал рядом вторую строку, отдельным файлом:

pg_dumpall --globals-only -f /путь/globals.sql


Там роли и табличные пространства, без данных. Восстанавливать сначала его, потом уже сам дамп, тогда владельцам будет кого назначить. Одно но: в этом файле лежат хэши паролей ролей. А флешка в роутере у меня видна всей домашней сети, включая ноутбук сына с его модами для игр. Так что globals.sql я туда класть не стал, пусть живёт там, где доступ только у меня.

Пробное восстановление на пустом сервере пока не делал. Сегодня суббота, Хэллоуин, младшая требует фотографировать её в костюме, то есть пополнять тот самый архив, который я до сих пор не умею поднять целиком. Займусь на неделе, проверю, что приложение реально заходит, а не что таблицы на месте.
0