Команда переезжает с самостоятельно поднятого PostgreSQL в облачный кластер и через неделю упирается в то, что ALTER SYSTEM не выполняется, pg_hba.conf не открыть, а нужного расширения нет в списке. Причина не в «урезанной» версии PostgreSQL: провайдер выдаёт роль без атрибута SUPERUSER и оставляет себе всё, что требует суперпользователя, ради failover и бэкапов, которые он делает за тебя. Дальше: что именно закрывает такая роль (опыт), что провайдеры публикуют о расширениях, параметрах, SLA и цене на 28 октября 2026, и как посчитать, сколько часов DBA стоит одна конфигурация. Если managed-кластер уйдёт в аварию, вспомнится failover и Patroni; бэкапы на своём сервере описаны в PITR из basebackup и WAL.
Кто делает что в managed PostgreSQL
Опыт 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 Cloud | VK Cloud | Selectel | Timeweb 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; прямое сравнение невозможно, пока не получены цены из калькуляторов.
Чек-лист
- Выпиши, какие расширения, параметры
postmasterи операции суперпользователя использует приложение сегодня (\dx,SELECT name FROM pg_settings WHERE context = 'postmaster' AND source <> 'default'). - Сверь выписку со страницами провайдера на дату принятия решения; недостающее зафиксируй в вопросе провайдеру письменно.
- Посчитай
MиSпо формулам выше с явнымиhиr, а не «на глаз». - Проверь путь выхода: как получить логическую копию и сколько часов займёт восстановление на своём сервере (стратегия бэкапов, RPO и RTO).