Справочник DBA: базы данных изнутри читается по порядку

Статья 13.1 · раздел 13 «Инфраструктура и облако» · 95 из 109

Managed PostgreSQL или свой сервер: что закрыто ролью, что в тарифе и как считать

опубликовано
читать
≈ 7 мин
автор
среда и версия
PostgreSQL 18.6 в контейнере postgres:18, роль без SUPERUSER с pg_monitor, pg_read_all_settings и pg_signal_backend против суперпользователя; цены, расширения, SLA и параметры четырёх провайдеров со страниц на 28 октября 2026; опыт выполнен 28 октября 2026
содержание решать задачи SQL на собеседовании

Команда переезжает с самостоятельно поднятого PostgreSQL в облачный кластер и через неделю упирается в то, что ALTER SYSTEM не выполняется, pg_hba.conf не открыть, а нужного расширения нет в списке. Причина не в «урезанной» версии PostgreSQL: провайдер выдаёт роль без атрибута SUPERUSER и оставляет себе всё, что требует суперпользователя, ради failover и бэкапов, которые он делает за тебя. Дальше: что именно закрывает такая роль (опыт), что провайдеры публикуют о расширениях, параметрах, SLA и цене на 28 октября 2026, и как посчитать, сколько часов DBA стоит одна конфигурация. Если managed-кластер уйдёт в аварию, вспомнится failover и Patroni; бэкапы на своём сервере описаны в PITR из basebackup и WAL.

DBA / 01

Кто делает что в managed PostgreSQL

Разделение задач между провайдером и DBA в managed PostgreSQLСемь задач. Провайдер: железо и диск, failover через Patroni и Etcd у Timeweb, бэкапы и восстановление на момент времени у Selectel с хранением 7 дней. Закрыто ролью без SUPERUSER: ALTER SYSTEM, COPY PROGRAM, чтение pg_hba, расширения вне списка провайдера. DBA: параметры контекста postmaster через перезапуск, параметры уровня базы вроде work_mem, схема, индексы и планы запросов. 01 Железо, диск, замена узла VK Cloud: развёртывание и сопровождение на стороне сервиса провайдер 02 Failover Timeweb: связка Patroni и Etcd, запись идёт на одного лидера провайдер 03 Бэкап и восстановление на момент времени Selectel: хранение 7 дней, бэкап нельзя выгрузить провайдер 04 ALTER SYSTEM, COPY PROGRAM, pg_hba опыт: permission denied у роли без SUPERUSER закрыто 05 Расширение вне списка провайдера опыт: file_fdw и pg_buffercache требуют superuser закрыто 06 Параметры контекста postmaster Selectel: 18 параметров, смена перезагружает кластер DBA 07 work_mem, схема, индексы, планы опыт: ALTER DATABASE SET work_mem проходит без SUPERUSER DBA
Failover и бэкапы уходят провайдеру, права суперпользователя не достаются никому из клиентов, а запросы, схема и параметры уровня базы остаются у DBA.

Опыт 1: чего не может роль без SUPERUSER

В контейнере postgres:18 создана роль, похожая на выдаваемую провайдером: CREATEDB, CREATEROLE и три предопределённые роли (документация). Это модель, а не копия роли какого-либо провайдера: как именно устроена роль у каждого, страницы не описывают.

docker run -d --name dba-managed-vs-self-hosted-postgres -e POSTGRES_PASSWORD=pg postgres:18
docker exec -i dba-managed-vs-self-hosted-postgres psql -U postgres -c "CREATE ROLE cloudadmin LOGIN PASSWORD 'ca' CREATEDB CREATEROLE"
docker exec -i dba-managed-vs-self-hosted-postgres psql -U postgres -c "GRANT pg_monitor, pg_read_all_settings, pg_signal_backend TO cloudadmin"
docker exec -i dba-managed-vs-self-hosted-postgres psql -U postgres -c "CREATE DATABASE app OWNER cloudadmin"

Те же команды выполнены под cloudadmin, затем под postgres. Вывод роли без SUPERUSER:

app=> SELECT rolname, rolsuper, rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = current_user;
  rolname   | rolsuper | rolcreaterole | rolcreatedb 
------------+----------+---------------+-------------
 cloudadmin | f        | t             | t
app=> ALTER SYSTEM SET shared_buffers = '1GB';
ERROR:  permission denied to set parameter "shared_buffers"
app=> COPY (SELECT 1) TO PROGRAM 'id';
ERROR:  permission denied to COPY to or from an external program
DETAIL:  Only roles with privileges of the "pg_execute_server_program" role may COPY to or from an external program.
app=> SELECT left(pg_read_file('pg_hba.conf'), 40);
ERROR:  permission denied for function pg_read_file
app=> SELECT count(*) FROM pg_hba_file_rules;
ERROR:  permission denied for view pg_hba_file_rules
app=> CREATE EXTENSION file_fdw;
ERROR:  permission denied to create extension "file_fdw"
HINT:  Must be superuser to create this extension.
app=> CREATE EXTENSION pg_buffercache;
ERROR:  permission denied to create extension "pg_buffercache"
HINT:  Must be superuser to create this extension.
app=> CREATE EXTENSION pgcrypto;
CREATE EXTENSION
app=> SELECT pg_switch_wal() IS NOT NULL;
ERROR:  permission denied for function pg_switch_wal
app=> SELECT pg_reload_conf();
ERROR:  permission denied for function pg_reload_conf

Вывод для postgres: ALTER SYSTEM вернул ALTER SYSTEM, COPY — COPY 1, pg_hba_file_rules показала 7 строк, оба CREATE EXTENSION прошли, pg_switch_wal() и pg_reload_conf() вернули t. Отличие pgcrypto объясняет код: расширение, помеченное trusted, ставит любой владелец базы с правом CREATE, остальным нужен SUPERUSER (REL_18_6, src/backend/commands/extension.c, строки 1216–1227):

	if (control->superuser && !superuser())
	{
		if (extension_is_trusted(control))
			switch_to_superuser = true;
		else if (from_version == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("permission denied to create extension \"%s\"",
							control->name),
					 control->trusted
					 ? errhint("Must have CREATE privilege on current database to create this extension.")
					 : errhint("Must be superuser to create this extension.")));

Условие control->superuser && !superuser() срабатывает для расширения, требующего суперпользователя. Функция extension_is_trusted (строки 1174–1186) пропускает его, только если control-файл говорит trusted и у роли есть CREATE на базу; иначе ветка errhint("Must be superuser…") даёт подсказку из вывода выше. Поэтому список расширений у провайдера — это список того, что сам провайдер поставил от имени суперпользователя, плюс trusted-расширения из contrib.

Что роль всё же умеет, и что нет, видно на второй сессии: пока postgres выполнял SELECT pg_sleep(10), cloudadmin с pg_monitor увидел его запрос, но завершить процесс не смог; параметр уровня user менялся, а postmaster-параметры оставались недоступными.

app=> SELECT usename, left(query, 28) AS query FROM pg_stat_activity WHERE query LIKE '%sleeper%' AND pid <> pg_backend_pid();
 usename  |            query             
----------+------------------------------
 postgres | SELECT pg_sleep(10) /* sleep
app=> SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE query LIKE '%sleeper%' AND pid <> pg_backend_pid();
ERROR:  permission denied to terminate process
DETAIL:  Only roles with the SUPERUSER attribute may terminate processes of roles with the SUPERUSER attribute.
app=> ALTER DATABASE app SET work_mem = '64MB';
ALTER DATABASE
app=> SELECT name, setting, context FROM pg_settings WHERE name IN ('work_mem','shared_buffers','wal_level','archive_command') ORDER BY name;
      name       |  setting   |  context   
-----------------+------------+------------
 archive_command | (disabled) | sighup
 shared_buffers  | 16384      | postmaster
 wal_level       | replica    | postmaster
 work_mem        | 65536      | user

Завершающие строки (N rows) в выводах опущены. work_mem с контекстом user меняется на уровне базы без прав суперпользователя, shared_buffers и wal_level в контексте postmaster требуют правки конфигурации и перезапуска. В managed-кластере эту правку делает провайдер через консоль или API. Контейнер удаляется командой docker rm -f -v dba-managed-vs-self-hosted-postgres.

Что публикуют четыре провайдера на 28.10.2026

Только то, что нашлось на страницах документации и прайсов. Что не нашлось, помечено так.

Yandex CloudVK CloudSelectelTimeweb Cloud
Расширениятаблица для PostgreSQL 14–18 на странице расширений: pg_stat_statements, pg_repack, pgaudit, pg_cron, pgvector, postgis и другие; pg_buffercache есть для всех версий (с ролью mdb_admin), pgstattuple — для PG 14–17, в 18 его нет; «нельзя управлять расширениями командами SQL»одиннадцать разделов, среди них pg_stat_statements, pg_partman, pg_hint_plan, pg_stat_kcache, PostGIS, TimescaleDB, PgBouncerсписок на странице: часть требует роль dbaas_admin (pg_stat_statements, pg_buffercache, pg_repack, pg_cron, postgis, oracle_fdw, postgres_fdw), её нельзя выдать другим пользователямне нашлось на странице документации: список расширений
Параметры, которые не менятьстраница настроек не называет read-only; 15 подключений резервируются для служебных пользователей на хостне нашлось на проверенных страницах18 параметров требуют перезагрузки: shared_buffers, max_connections, shared_preload_libraries, max_wal_senders и другиене нашлось на странице
SLAна странице сервиса: чтение 99,99 %, запись 99,95 % для HA-кластеров; исключения не искалне нашлось на проверенных страницахна странице сервиса: для кластеров с репликой запись 99,95 %, чтение 99,99 %; исключения не искална странице: 99,98 %; условия не указаны
Бэкапыбесплатны, пока размер не превысит суммарное хранилище хостовавтоматические копии не тарифицируются, снимок диска тарифицируется за ГБеженедельная полная копия, ежедневная дельта, WAL каждые 10 минут, хранение 7 дней, выгрузить нельзя6 ₽/мес за 1 ГБ

По формуле простоя за 30 дней (43 200 минут): 99,95 % допускает 21,6 минуты, 99,98 % — 8,64, 99,99 % — 4,32. Пока на страницах не прочитаны условия компенсации и исключения, это верхний предел обещания, а не гарантия доступности.

Опыт 2: цена 8 vCPU, 32 ГБ, 500 ГБ и реплики

Формула для облака: M = 2 × (8·c + 32·r + 500·d) за 30 дней, где c — цена vCPU, r — цена 1 ГБ RAM, d — цена 1 ГБ диска; вторая копия — реплика с такими же ресурсами.

  • VK Cloud, прайс-лист, блок Cloud Databases, цены за 30 дней с НДС: Intel Ice Lake 1 061,63 ₽ за vCPU, RAM 278,31 ₽ за ГБ, SSD 16,59 ₽ за ГБ. Один инстанс: 8·1 061,63 + 32·278,31 + 500·16,59 = 8 493,04 + 8 905,92 + 8 295,00 = 25 693,96 ₽; с репликой M = 51 387,92 ₽. Резервные копии и трафик по странице тарификации не тарифицируются.
  • Yandex Cloud: на странице цен нет таблицы по классам хостов, есть только числа из примеров расчёта: 1,8792 ₽ за час 100 % vCPU Intel Ice Lake, 0,5072 ₽ за час 1 ГБ RAM, 3,744 ₽ за ГБ в месяц сетевого HDD. Цена SSD-диска не нашлась. Для хоста с HDD: (8·1,8792 + 32·0,5072)·720 + 500·3,744 = 22 510,08 + 1 872,00 = 24 382,08 ₽; с репликой 48 764,16 ₽. Это расчёт по числам примера, а не по таблице цен, и диск там медленнее SSD.
  • Selectel: цены не нашлись ни на странице сервиса, ни на странице конфигураций; она показывает только состав конфигураций, например 8 vCPU, 32 ГБ и 256 ГБ локального диска в линейке CPU; 500 ГБ возможны в Flex (локальный диск от 32 ГБ до 2 ТБ).
  • Timeweb Cloud: на странице сервиса указано «от 790 р» без конфигурации и бэкапы по 6 ₽/мес за ГБ; цены на 8 vCPU и 32 ГБ в тексте страницы не нашлись (калькулятор на ней грузится скриптом).

Для своего сервера цена складывается из аренды двух машин и работы DBA:

S = 2 · C + h · r

C — месячная стоимость одной машины с такими же ресурсами (аренда или амортизация), h — часы DBA в месяц на обновления, бэкапы, failover и дежурство, r — стоимость часа. Ни C, ни h, ни r здесь не измерены: это параметры твоей ситуации. Свой сервер выгоднее managed-кластера, пока h · r < M − 2 · C. Для VK Cloud правая часть равна 51 387,92 ₽ минус арендная плата за две машины; бэкапы, мониторинг и сеть своего сервера в C надо добавить самому.

Что из этого следует

  • Права суперпользователя не вернуть. Всё, что в опыте 1 дало permission denied, в managed-кластере делает провайдер или не делает никто: проверь по списку расширений и параметров, что нужное есть, до миграции.
  • Параметры postmaster меняются через перезагрузку. У Selectel это 18 параметров; план перехода должен учитывать окно перезапуска.
  • Бэкап можно не получить на руки. Selectel пишет «Бэкапы нельзя выгрузить»: для сценария «забрать копию на свой сервер» нужен pg_dump или логическая репликация, то есть проверка пути выхода до заключения договора.
  • Цену сравнивай по одной конфигурации. Для двух провайдеров из четырёх цена 8 vCPU и 32 ГБ с репликой не нашлась на страницах, для третьего посчитана по примеру с HDD; прямое сравнение невозможно, пока не получены цены из калькуляторов.

Чек-лист

  1. Выпиши, какие расширения, параметры postmaster и операции суперпользователя использует приложение сегодня (\dx, SELECT name FROM pg_settings WHERE context = 'postmaster' AND source <> 'default').
  2. Сверь выписку со страницами провайдера на дату принятия решения; недостающее зафиксируй в вопросе провайдеру письменно.
  3. Посчитай M и S по формулам выше с явными h и r, а не «на глаз».
  4. Проверь путь выхода: как получить логическую копию и сколько часов займёт восстановление на своём сервере (стратегия бэкапов, RPO и RTO).

Источники

Выжимки статей в Telegram: одна ловушка, код с выводом и ссылка на полный разбор. t.me/koddo_ru