Программное окружение

  • Debian 12;

  • PostgreSQL для 1с 17;

  • 1С 8.3.24.1819.

NB: С наименованием СУБД наблюдается некоторая неразбериха, т.к. на сайте разработчика написано что называется данный продукт именно PostgreSQL для 1C и ничего общего с Postgres Pro не имеет. Однако, пакеты для установки называются postgrespro-1c-{version} и на других ресурсах она обычно упоминается как PostgreS[QL] Pro для 1С. Так что как именовать её "правильно" решайте сами, я выбрал назвать по имени пакета для установки.

Задача

Реализовать традиционную схему управления правами доступа в связке 1С - СУБД в которой каждая база данных принадлежит строго определённому пользователю, не имеющему доступа к другим БД.

Решение

По сути, ключевым моментом является назначение прав на использование процедур на языке Си в базе template0. Почему при создании базы не срабатывает аналогичный параметр, установленный, как полагается по правилам, в базе template1 - это надо спрашивать, наверное, в 1С.

  1. Ставим СУБД и подключаемся

    # русский язык на время установки, иначе потом вручную менять придётся
    export LANG=’ru_RU.UTF-8’
    export LANGUAGE=’ru_RU.UTF-8’
    apt-get install postgrespro-1c-{version}
    su - postgres
    psql
  2. Настраиваем общие параметры

    \password postgres
    пароль_администратора_СУБД
    -- Разрешаем менять базу template0
    UPDATE pg_database SET datallowconn = true WHERE datname = 'template0';
    \c template0
    -- Включаем использование серверных процедур на C
    UPDATE pg_language SET lanpltrusted = true WHERE lanname LIKE 'c';
    \c postgres
    -- Запрещаем менять базу template0
    UPDATE pg_database SET datallowconn = false WHERE datname = 'template0';
  3. Создаём пользователя и настраиваем права

    CREATE ROLE user1c WITH LOGIN PASSWORD 'пароль для истории';
    \password user1c
    пароль_пользователя
    -- право на изменение языка сообщений, иначе 1С постоянно в логи мусорит
    GRANT SET ON PARAMETER lc_messages TO user1c;
    GRANT pg_execute_server_program TO user1c;
  4. Создаём базу, временно выдав права на создание базы

    ALTER ROLE user1c CREATEDB;
    -- создаём базу в консоли сервера, ibcmd или ещё как-то
    ALTER ROLE user1c NOCREATEDB;

Если с созданием база закончено - разрешение на создание серверных процедур на языке Си из базы template0 можно отобрать назад.

Комментарии (7)


  1. mixsture
    30.07.2025 20:56

    по схеме каждой БД свой пользователь

    А зачем? Обычно в идеологии постгреса стоит делать 1 БД = 1 инстанс. Иначе вы потеряете возможность двоичных бекапов (они делаются целиком на инстанс). Вы пытаетесь таки несколько БД развернуть в одном инстансе и каждой своего пользователя сделать?


    1. asatost Автор
      30.07.2025 20:56

      Обычно в идеологии постгреса стоит делать 1 БД = 1 инстанс.

      Видел рекомендации 1 БД = 1 сервер. Про 1 БД = 1 инстанс не встречалось. Где можно почитать?

      Иначе вы потеряете возможность двоичных бекапов (они делаются целиком на инстанс).

      Так и сделается бэкап всего инстанса со всеми базами, тут, если я правильно помню, проблем нет. Если Вам нужно восстановить из него только 1 базу, то это, опять же, насколько я помню, несколько обходным путём сделано, восстанавливаются все базы, просто не нужные восстанавливаются пустыми.

      Вы пытаетесь таки несколько БД развернуть в одном инстансе и каждой своего пользователя сделать?

      Именно так.


      1. mixsture
        30.07.2025 20:56

        Видел рекомендации 1 БД = 1 сервер. Про 1 БД = 1 инстанс не встречалось. Где можно почитать?

        https://www.postgresql.org/docs/current/app-pgbasebackup.html

        "pg_basebackup is used to take a base backup of a running PostgreSQL database cluster. The backup is taken without affecting other clients of the database, and can be used both for point-in-time recovery (see Section 25.3) and as the starting point for a log-shipping or streaming-replication standby server"

        Вот "...of a running PostgreSQL database cluster" и отсутствие опций в нем по выбору конкретной базы.

        Так и сделается бэкап всего инстанса со всеми базами, тут, если я правильно помню, проблем нет. Если Вам нужно восстановить из него только 1 базу, то это, опять же, насколько я помню, несколько обходным путём сделано, восстанавливаются все базы, просто не нужные восстанавливаются пустыми.

        Хорошо, вот кейс: на сервере 5 рабочих разных баз, только одну конкретную из них надо откатить из бекапа "на вчера". Как это сделать в вашей схеме, желательно недолго?


        1. XLeshiy
          30.07.2025 20:56

          Усложним, баз 200 (как у меня)


        1. asatost Автор
          30.07.2025 20:56

          https://www.postgresql.org/docs/current/app-pgbasebackup.html

          Так это же просто документация, а не рекомендации по конфигурации.

          Как это сделать в вашей схеме, желательно недолго?

          Прежде всего, сама 1С рекомендует pg_dump.
          Если использовать двоичные бэкапы то с pg_basebackup никак.
          С pg_probackup в отдельный инстанс: https://postgrespro.com/docs/postgrespro/current/app-pgprobackup#PBK-PARTIAL-RESTORE-OPTIONS и потом перенести в основной, если всё ок.


          1. mixsture
            30.07.2025 20:56

            Прежде всего, сама 1С рекомендует pg_dump.

            Это решение для маленьких баз. Я как-то 60гиговую выгружал между 2 и 3 часами. Для теста даже загрузил ее обратно: ~8 часов. Двоичные бекапы - меньше, чем за 30 минут справляются.

            С pg_probackup в отдельный инстанс: https://postgrespro.com/docs/postgrespro/current/app-pgprobackup#PBK-PARTIAL-RESTORE-OPTIONS и потом перенести в основной, если всё ок.

            А с 1 бд = 1 инстанс работает любой из инструментов и можно восстанавливаться без промежуточного места.


    1. aleks_public
      30.07.2025 20:56

      Находил видео с выступлением в двух частях Антона Дорошкевича. Там точно было

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