При администрировании баз данных 1С:Предприятие на СУБД PostgreSQL администраторы часто сталкиваются с необходимостью оптимизации дискового пространства. Одним из очевидных решений кажется вынос файлов базы данных или отдельных таблиц на удаленный сервер или сетевое хранилище (NAS) с помощью механизма табличных пространств (tablespace). Однако при попытке указать сетевой UNC-путь вида \\server\share\ система выдает критическую ошибку. Рассмотрим, почему это происходит и как решить данную проблему несколькими способами.
Рассмотрим стандартную ситуацию. Администратор пытается перенести базу данных «1С:Управление торговлей» на СУБД PostgreSQL, расположенную на Windows-сервере, во вновь созданное табличное пространство на удаленном сетевом ресурсе. При выполнении SQL-запроса по переносу или созданию базы данных СУБД возвращает ошибку, а в логах PostgreSQL регистрируются следующие записи:
WARNING: could not open directory "pg_tblspc/53730430/PG_9.6_201608131/53834047": No such file or directory
ERROR: could not create directory "pg_tblspc/53730430/PG_9.6_201608131/53834047": Invalid argument
STATEMENT: ALTER DATABASE "ut-g" SET TABLESPACE ger;
Основной маркер проблемы здесь — системная ошибка Invalid argument (недопустимый аргумент) при попытке СУБД создать каталог внутри папки pg_tblspc. Выясним глубокие технические причины такого поведения операционной системы и СУБД.
Проанализируем архитектуру СУБД PostgreSQL. Механизм табличных пространств в ней реализован через создание файловых ссылок. В каталоге установки СУБД (внутри папки data/pg_tblspc) создаются указатели на реальные физические каталоги, где хранятся файлы таблиц.
В операционной системе Windows для реализации этих указателей СУБД PostgreSQL по умолчанию использует механизм NTFS Junction Points (точки соединения операционной системы). У этого механизма есть жесткое архитектурное ограничение: точки соединения могут указывать исключительно на локальные пути файловой системы NTFS. Они физически не умеют работать с сетевыми путями UNC (начинающимися с двойного обратного слэша \\).
Когда мы выполняем команду создания табличного пространства, указывая сетевую папку, PostgreSQL пытается создать файловую связь типа Junction. Windows блокирует эту операцию и возвращает ошибку недействительного аргумента (Invalid argument), в результате чего создание или перенос базы данных аварийно завершается.
Помимо ограничений файловой системы, существуют еще две серьезные проблемы:
postgresql-x64-14) запускается под локальной системной учетной записью (NETWORK SERVICE или локальным пользователем postgres). Этот пользователь не имеет никаких прав доступа к ресурсам локальной сети и другим серверам. Даже если вы подключили сетевой накопитель как диск Z: под своей учетной записью администратора, служба СУБД этот диск просто «не увидит», так как службы работают в изолированном окружении (Session 0).fsync). Протоколы сетевого доступа к файлам (SMB/CIFS) не гарантируют абсолютной надежности выполнения этих низкоуровневых команд. При малейшем сетевом сбое, потере пакетов или перезагрузке файлового сервера база данных 1С гарантированно получит повреждение таблиц (состояние «dirty read» или разрушение заголовков файлов данных).Разберем три основных метода решения этой проблемы — от наиболее надежного к компромиссным.
Для высоконагруженных систем, таких как базы данных 1С:Предприятие, настоятельно рекомендуется использовать только локальные физические накопители (желательно твердотельные диски SSD или NVMe Enterprise-класса). Если на основном системном диске сервера СУБД заканчивается свободное место, оптимальным решением будет:
D:\) или примонтировать его в пустую папку на диске C:\.D:\pg_data_ts\).Если физически установить диски в сервер невозможно, а свободное место есть только на удаленном сетевом хранилище (NAS или SAN), подключать его необходимо не как сетевую папку (SMB), а как блочное устройство. Для этого используется протокол iSCSI.
При таком подходе удаленный дисковый массив будет восприниматься операционной системой Windows как полноценный локальный жесткий диск, подключенный по шине SCSI. Это полностью решает проблему ограничений NTFS Junctions и обеспечивает корректную работу команд СУБД. Разберем этот процесс по шагам:
diskmgmt.msc). Система обнаружит новый неинициализированный диск. Нажмите на него правой кнопкой мыши, выберите «Инициализировать диск», укажите стиль разделов GPT.E:\), выберите файловую систему NTFS и обязательно укажите размер кластера 64 КБ для оптимальной производительности СУБД.E:\ каталог (например, E:\pg_tablespaces\ts_1c) и в свойствах папки на вкладке «Безопасность» добавьте пользователя, под которым работает служба СУБД PostgreSQL, предоставив ему «Полный доступ».Теперь вы можете спокойно создавать табличное пространство в pgAdmin или через консоль запросов, указав путь E:\pg_tablespaces\ts_1c. Ошибок не возникнет, так как для операционной системы и СУБД этот накопитель является локальным.
Если развернуть iSCSI технически невозможно и вам крайне необходимо задействовать именно стандартную сетевую папку Windows (SMB), можно обойти ограничение СУБД, заменив стандартные Junction Points на символические ссылки файловой системы (Symbolic Links), которые умеют работать с сетевыми путями UNC.
Важное предупреждение: Данный метод является недокументированным обходным решением. Администратор берет на себя все риски потери целостности базы данных 1С при возникновении сетевых неполадок!
Рассмотрим по шагам, как реализовать этот метод:
SERVER_PG$).services.msc), найдите службу PostgreSQL. Откройте ее свойства, перейдите на вкладку «Вход в систему» и переключите переключатель с «Локальная система» на «С учетной записью». Укажите доменного пользователя, у которого есть доступ к сетевой папке, и введите его пароль. Перезапустите службу.gpedit.msc). Перейдите по пути: Конфигурация компьютера -> Конфигурация Windows -> Параметры безопасности -> Локальные политики -> Назначение прав пользователя -> Создание символических ссылок. Добавьте туда пользователя, от имени которого теперь работает служба PostgreSQL.pg_tblspc.
CREATE TABLESPACE ger LOCATION 'C:\pg_dummy_dir';
net stop в командной строке.C:\Program Files\PostgreSQL\...\data\pg_tblspc\. Вы увидите созданную точку соединения (Junction), которая выглядит как ярлык папки с числовым именем (например, 53730430). Удалите этот ярлык./D (создание символической ссылки на каталог, поддерживающей UNC), связав числовой OID с удаленным сервером:
mklink /D "C:\Program Files\PostgreSQL\9.6.5-4.1C\data\pg_tblspc\53730430" "\\10.0.0.121\share\Program Files\PostgreSQL\data"
ALTER DATABASE "ut-g" SET TABLESPACE ger;
Мы проанализировали причины возникновения ошибки недействительного аргумента при работе с сетевыми путями в PostgreSQL и разобрали три метода устранения неполадки. Настоятельно рекомендуем использовать Решение 1 или Решение 2 как наиболее отказоустойчивые и обеспечивающие сохранность ваших учетных данных 1С.