Ситуация, когда база данных 1С:Предприятие на платформе PostgreSQL внезапно перестает работать, выдавая сообщения о "Критической ошибке словаря" или отсутствии связей (relation does not exist), является одной из самых сложных в практике системного администратора и программиста. Особенно критично это выглядит, когда обнаруживается пропажа нескольких тысяч таблиц в SQL-базе по сравнению с эталонной копией. Разберем пошагово, как проанализировать такую проблему, реанимировать Конфигуратор и попытаться спасти данные.
Первым делом проанализируем ситуацию. Ошибка "relation does not exist" в контексте 1С обычно означает, что платформа пытается обратиться к таблице (например, _Const15353 или _Config), которой физически нет в схеме public базы данных PostgreSQL. Выясним основные причины, почему это происходит:
base/, но информация о них в системной таблице pg_class может быть повреждена.Посмотрим на логи. Если pg_log сыпет ошибками типа could not receive data from client, это свидетельствует о принудительном разрыве соединений со стороны сервера 1С из-за внутренних критических исключений.
Если при попытке зайти в Конфигуратор вы получаете ошибку "При обновлении данных после последней реструктуризации произошла критическая ошибка", значит, повреждена основная таблица конфигурации. Проанализируем метод "подмены" таблицы config из исправной базы того же релиза.
Для этого выполним следующие действия в SQL-консоли (например, через pgAdmin):
COPY config TO 'D:/config_OK.txt';DELETE FROM config;COPY config FROM 'D:/config_OK.txt';Важно: Этот метод поможет зайти в Конфигуратор, но не решит проблему с данными в режиме "Предприятие". Если после этого возникает ошибка "Пользователь ИБ не идентифицирован", воспользуемся следующим запросом для сброса состояния реструктуризации:
UPDATE SchemaStorage SET Status = 100;
Это заставит систему считать, что последняя операция со схемой данных была успешно завершена.
Проанализируем ситуацию с количеством таблиц. Если в "живой" копии их 7000, а в упавшей 2000 — это значит, что 5000 таблиц (справочники, документы, регистры) были либо удалены, либо переименованы в процессе неудачного ТиИ. Выясним причину ошибки при восстановлении через pg_restore. Часто она выглядит так: ERROR: relation "public.v8usersog" does not exist. Это происходит потому, что pg_restore пытается создать индекс на таблицу, которая еще не создана. В таком случае попробуйте восстанавливать базу поэтапно: сначала только структуру (схему), затем данные, и только в конце — индексы.
Когда таблиц слишком много для ручного копирования, а стандартный бэкап не разворачивается, можно написать внешнюю обработку 1С, которая через COM-соединение и драйвер ODBC подключится к двум базам (старой копии и "битой" базе) и попытается синхронизировать их структуру. Рассмотрим пример кода такой обработки.
Сначала установим соединение с базами:
Процедура ПолучитьСоединениеСБазами()
// Настройка параметров подключения для PostgreSQL
ConnectionString = "Driver={PostgreSQL Unicode};Server=localhost;Port=5432;Database=BuhSever;Uid=postgres;Pwd=*****;";
ConnectionT = Новый COMОбъект("ADODB.CONNECTION");
Попытка
ConnectionT.Open(ConnectionString);
Сообщить("Связь с основной базой установлена.");
Исключение
Сообщить("Ошибка подключения: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Далее разберем алгоритм, который перебирает список таблиц и копирует данные. Этот метод использует команду SQL COPY, которая работает значительно быстрее, чем построчный перебор SELECT/INSERT.
Функция СкопироватьТаблицу(ИмяТаблицы)
// 1. Выгружаем данные из поврежденной (но содержащей новые данные) базы в файл
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = ConnectionT;
Команда.CommandText = "COPY " + ИмяТаблицы + " TO 'D:/tables/" + ИмяТаблицы + ".csv'";
Попытка
Команда.Execute();
Исключение
Возврат Ложь; // Таблицы нет в источнике
КонецПопытки;
// 2. Загружаем в базу-приемник (старую исправную копию)
КомандаK = Новый COMОбъект("ADODB.Command");
КомандаK.ActiveConnection = ConnectionK;
КомандаK.CommandText = "DELETE FROM " + ИмяТаблицы; // Очищаем старые данные
КомандаK.Execute();
КомандаK.CommandText = "COPY " + ИмяТаблицы + " FROM 'D:/tables/" + ИмяТаблицы + ".csv'";
КомандаK.Execute();
КонецФункции
Важное примечание: При использовании этого метода помните, что 1С хранит бинарные данные (хранилища значений) в полях типа bytea. При выгрузке в обычный CSV-файл спецсимволы могут исказиться. Рассмотрим альтернативу — использование двоичного формата (COPY BINARY), который гарантирует сохранность данных.
Если таблицы отсутствуют и в файловой системе (размер папки базы существенно уменьшился), то единственным выходом остается восстановление из последнего бэкапа и ручной ввод данных за недостающий период. Проанализируем, как избежать этой ситуации в будущем:
pg_dump по расписанию (как минимум раз в сутки).postgresql.conf установите log_statement = 'ddl', чтобы видеть все изменения структуры базы..dt или SQL-копии.Если у вас есть файлы с данными, но нет самих таблиц в базе, можно попробовать воспользоваться сторонними утилитами, такими как pgfutter. Она позволяет автоматически создавать структуру таблицы на основе CSV-файла. Пример использования в .bat файле:
@Echo off
FOR %%a IN (d:\tables\*.csv) DO (
echo Обработка файла: %%~nxa
pgfutter.exe --host "localhost" --port "5432" --db "BuhSever" --schema "public" --table %%~na --user "postgres" --pw "password" csv %%~nxa
)
Однако стоит учитывать, что 1С предъявляет специфические требования к типам полей (например, точность numeric, типы boolean и timestamp), поэтому созданная автоматически структура может не подойти для работы платформы напрямую без правки метаданных в таблице DBSchema.
Подведем итог: восстановление базы 1С на PostgreSQL при потере 5000 таблиц — задача почти невозможная без актуальной копии. Тем не менее, использование методов подмены таблицы config, сброса статуса SchemaStorage и прямого переноса данных через SQL COPY дает шанс на частичное спасение информации.