При автоматизации резервного копирования баз 1С на Linux-серверах с помощью утилиты ibcmd можно столкнуться с неприятной ситуацией: файл выгрузки .dt создается, имеет корректный размер, но при попытке его загрузить в информационную базу система выдает ошибку «Неверный формат файла для загрузки информационной базы» с уточнением «Ошибка формата потока». Проблема может воспроизводиться как при загрузке через конфигуратор на Windows-машине, так и при попытке восстановления той же утилитой ibcmd непосредственно на сервере.
В этой статье мы подробно разберем, почему возникает эта ошибка, как ее диагностировать и исправить, а также рассмотрим общие рекомендации по созданию надежных резервных копий.
Чаще всего корень проблемы кроется не в самой утилите ibcmd или особенностях операционной системы, а в распространенной ошибке при написании shell-скрипта для автоматизации выгрузки. Рассмотрим типичный ошибочный скрипт, который приводит к появлению этой проблемы.
Пример неверного скрипта:
#!/bin/sh
backupfolder=/backup/dt_dump
db_name=accounting
POSTFIX=`date +%d-%m-%Y_%H-%M-%S`
# ... другие переменные ...
dtfile=$backupfolder/$db_name-$POSTFIX.dt
# КРИТИЧЕСКАЯ ОШИБКА ЗДЕСЬ
if /opt/1cv8/x86_64/8.3.25.1374/ibcmd infobase ... dump ... $dtfile > $dtfile ; then
echo 'dt dump accounting has been created'
else
echo "dt dump accounting return non-zero code"
exit
fi
На первый взгляд все выглядит логично, но давайте внимательно посмотрим на команду запуска ibcmd. В конце строки присутствует оператор перенаправления стандартного вывода (stdout) > $dtfile. Выясним, что здесь происходит на самом деле.
ibcmd в качестве последнего аргумента уже принимает путь к файлу, в который нужно сохранить выгрузку (наша переменная $dtfile). Она самостоятельно открывает этот файл и записывает в него бинарные данные в нужном формате.ibcmd выводит в стандартный поток вывода служебную информацию о ходе процесса, например: [INFO] Выгрузка информационной базы в файл успешно завершена.> $dtfile перехватывает этот текстовый вывод и принудительно дописывает его в тот же самый файл .dt, куда ibcmd уже пишет бинарные данные.В результате получается «испорченный» файл: его бинарная структура нарушена текстовыми вставками. Платформа 1С при попытке прочитать такой файл не может распознать его формат и справедливо сообщает об «Ошибке формата потока».
Чтобы на 100% убедиться, что проблема именно в этом, выполним простую проверку. Откроем созданный .dt файл с помощью любого текстового редактора (например, nano или less в консоли Linux, или Notepad++ в Windows).
Так как это бинарный файл, большая часть его содержимого будет выглядеть как набор нечитаемых символов. Однако, если проблема в перенаправлении вывода, то в начале или в конце файла вы увидите осмысленный текст. Например:
Содержимое поврежденного .dt файла (фрагмент):
1CIBDmpF3��c�uM�- n۶m۶m۶m۶m۶m{��s� _t��3j��Z���bf -Da{[ C K#K K OY{ [INFO] Выгрузка информационной базы в файл успешно завершена
Наличие такой текстовой строки внутри файла — прямое доказательство того, что его структура повреждена из-за неверной работы со стандартными потоками вывода.
Теперь исправим наш скрипт. Решение очень простое — нужно убрать ошибочное перенаправление вывода. Однако лучшей практикой будет не просто убрать его, а перенаправить вывод в отдельный лог-файл. Это позволит нам в будущем отслеживать результаты выполнения скрипта и диагностировать возможные проблемы.
Пример исправленного и улучшенного скрипта:
#!/bin/sh
backupfolder=/backup/dt_dump
db_name=accounting
PREFIX=$db_name
POSTFIX=`date +%d-%m-%Y_%H-%M-%S`
db_user=имя_пользователя_pg
db_password=пароль_пользователя_pg
user_1c=пользователь_1с
password_1c=пароль_1с
# Сколько дней хранить файлы
keep_day=7
dtfile=$backupfolder/$PREFIX-$POSTFIX.dt
logfile=$backupfolder/$PREFIX-$POSTFIX.log
# Запускаем выгрузку, направляя текстовый вывод в отдельный лог-файл
if /opt/1cv8/x86_64/8.3.25.1374/ibcmd infobase \
--dbms=PostgreSQL \
--db-server=localhost \
--db-user=$db_user \
--db-pwd=$db_password \
--db-name=$db_name \
dump \
--user=$user_1c \
--password=$password_1c \
$dtfile > $logfile 2>&1; then
echo "Выгрузка $db_name успешно завершена. Лог: $logfile"
else
echo "Ошибка при выгрузке $db_name. Подробности в логе: $logfile"
exit 1
fi
# Удаление старых резервных копий
find $backupfolder -name "*.dt" -mtime +$keep_day -delete
find $backupfolder -name "*.log" -mtime +$keep_day -delete
Проанализируем ключевое изменение:
Вместо > $dtfile мы используем конструкцию > $logfile 2>&1. Разберем ее по частям:
> $logfile: перенаправляет стандартный вывод (stdout), то есть все информационные сообщения, в файл лога.2>&1: перенаправляет стандартный поток ошибок (stderr) туда же, куда и стандартный вывод (то есть в наш лог-файл).Таким образом, мы достигаем двух целей: сам .dt файл создается в чистом виде, без посторонних данных, а вся служебная информация о процессе (как успешная, так и сообщения об ошибках) аккуратно сохраняется в отдельном текстовом файле для последующего анализа.
Хотя ошибка в скрипте является самой частой причиной в описанном сценарии, данная проблема может возникать и по другим причинам. Рассмотрим их, чтобы иметь полную картину.
.dt файл, созданный на более новой версии платформы (например, 8.3.25), в информационную базу, работающую на более старой версии (например, 8.3.24). Убедитесь, что версии платформы на источнике и приемнике совпадают или версия приемника новее.%APPDATA%\1C\1cv8 и %LOCALAPPDATA%\1C\1cv8)..dt может формально завершиться успешно, но сам файл будет содержать некорректные данные. Перед созданием выгрузки рекомендуется выполнять проверку логической целостности через конфигуратор (Тестирование и исправление).В заключение, всегда помните о важности проверки созданных резервных копий. Регулярно проводите тестовое восстановление бэкапов на отдельном сервере, чтобы быть уверенными в их работоспособности в критический момент.