Восстановление базы из DT, если она не хочет восстанавливаться

14.04.22

База данных - Архивирование (backup)

Решение некоторых проблем при восстановлении базы из dt.

Как говорится, админы делятся на тех, кто делает бекапы, и тех, кто уже делает. А из тех, кто уже делает, выделяются те, кто эти бекапы проверяют (народная мудрость).

К сожалению, если есть выгрузка базы в .dt, есть ненулевой шанс эту выгрузку не загрузить обратно, с чем мне в последнее время несколько раз и пришлось столкнуться. И это даже не касается крупных баз, которые не могут загрузиться в файловый вариант. Просто файловая база может быть незначительно повреждена, так что при работе это незаметно, и выгружаться нормально, но выгруженные повреждения не дадут базу загрузить обратно. Например, в результате повреждения в таблице образовалось несколько пустых строк, но по таблице построен уникальный индекс. Или образовалось null-значение в поле с ограничением not null. Или строковые данные повредились, и 1С из строкового поля "на 10 символов" выгрузит 200 символов мусора. Все эти проблемы всплывают только при попытке воспользоваться выгрузкой.

 

 

К сожалению, формат DT закрытый, и просто так проблемы в нём поправить нельзя. Мне в таких случаях помогла загрузка базы в серверный вариант с PostgreSQL.

Во-первых, PostgreSQL молча обрезает слишком длинные строки. А во-вторых, используя триггеры, можно модифицировать данные при загрузке, чтобы исправить ошибки. Работать в PostgreSQL можно из "штатной" утилиты pgAdmin.

1С загружает базу в следующем порядке:

1. удаляются таблицы базы если они были

2. Создаётся и загружается таблица CONFIG и прочие служебные таблицы и создаётся новая структура таблиц.

3. Таблицы заполняются данными

4. После заполнения очередной таблицы создаются индексы, и начинается заполнение следующей таблицы.

Возможно, встретится ошибка с таким сообщением:

Попытка вставки неуникального значения в уникальный индекс: РегистрСведений.ЦеныНоменклатуры
23502: ERROR:  null value in column "_fld16137_type" violates not-null constraint
DETAIL:  Failing row contains (0001-01-01 00:00:00, \x00000000000000000000000000000000, \x00000000000000000000000000000000, \x00000000000000000000000000000000, 0.00, f, null, \x00000000, \x00000000000000000000000000000000, f, \x00000000000000000000000000000000, 0).
CONTEXT:  COPY _inforg16131, line 6537

Ключевое здесь сообщение "null value in column "_fld16137_type" violates not-null constraint". Тогда можно поступить следующим образом:

Нужно создать триггерную функцию такого вида:

CREATE OR REPLACE FUNCTION public.qqqq()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$

BEGIN
  IF (NEW._period IS NULL)
	OR(NEW._recordertref IS NULL)OR(NEW._recorderrref IS NULL)THEN
    RETURN NULL;
  END IF;
  IF NEW._lineno IS NULL THEN
    NEW._lineno=0;
  END IF;
  IF NEW._active IS NULL THEN
    NEW._active=false;
  END IF;
  IF NEW._fld18947rref IS NULL THEN
    NEW._fld18947rref='\\x00000000000000000000000000000000';
  END IF;
  IF NEW._fld18950 IS NULL THEN
    NEW._fld18950=0;
  END IF;
  RETURN NEW;
END
$BODY$;

Для каждой таблицы с такими проблемами по своей функции. Здесь имена полей нужно брать из сообщения об ошибках. В этом примере - если не заполнен _period или _recordertref или _recorderrref запись просто пропускается. Если не заполнены остальные поля - им присваиваю значение. Скорее всего это повреждённые записи, с утерянными или мусорными данными, решение тут надо принимать на месте - возможно стоит просто пропустить эту запись. Если нужно запись сохранить - значение нужно смотреть по типу использования

При загрузке 1С не удаляет триггерные функции, но назначить триггер придётся таблице после её создания. Это можно попробовать сделать через событийный триггер (см. ниже), но я делал есть вручную. Нужно назначить таблице триггер, указать созданную триггерную функцию и событие - BEFORE INSERT

 

 

Создать можно в диалоге, или таким запросом:
 

CREATE TRIGGER tbl1_flt
    BEFORE INSERT
    ON public._acc50
    FOR EACH ROW
    EXECUTE FUNCTION public.qqqq();

Где tbl1_flt - произвольно заданное имя
_acc50 - имя таблицы, вставку в которую данных фильтруем
qqqq() - имя созданной триггерной функции

Т.е. сначала нужно создать функцию, затем начать загрузку, и когда таблица появилась - назначить триггер.

Если загрузка прерывается по ошибке неуникальных данных:

Попытка вставки неуникального значения в уникальный индекс:
23505: ERROR:  could not create unique index "_inforg16131_1" РегистрСведений.ЦеныНоменклатуры
DETAIL:  Key (_fld1224, _period, _fld16132rref, _fld16133rref, _fld16134rref)=(0, 0001-01-01 00:00:00, \x00000000000000000000000000000000, \x00000000000000000000000000000000, \x00000000000000000000000000000000) is duplicated.

Это уже этап создания индексов по загруженным данным. В этом сообщении мусорные данные, но они могут быть и не мусорными. В этом случаем нам могут помочь СОБЫТИЙНЫЕ ТРИГГЕРЫ PostgreSQL. В отличие от строчных такой триггер может вызываться перед выполнением SQL команды create index, что позволит подчистить лишнее.

Нужно сначала создать функцию, в которой будем чистить лишние данные. К сожалению, есть сложности с определением какая именно команда и над каким объектом вызывается, возможно возникающие исключения будем гасить. Пример такой функции, удаляющей данные:

CREATE OR REPLACE FUNCTION public.asnitch()
    RETURNS event_trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$

DECLARE
  r record;
BEGIN
--	r:=pg_event_trigger_ddl_commands();
--    RAISE NOTICE 'snitch: % %', tg_event, tg_tag;
	BEGIN
		DELETE FROM _inforg16131
		WHERE _fld16132rref='\\x00000000000000000000000000000000'
		AND _fld16133rref='\\x00000000000000000000000000000000';
	EXCEPTION
		WHEN others THEN
	END;
	BEGIN
		DELETE FROM _inforg16131
		WHERE _fld16132rref='\\x008593706655162bac11eb41f32fa23c';
	EXCEPTION
		WHEN others THEN
	END;
END;
$BODY$;

Здесь я просто удаляю мешающие данные, их можно было удалить и на этапе загрузки в прошлом способе. Но если есть цель оставить из неуникальных записей только одну, придётся писать запрос в обработчике событийного триггера.

Функция создана, теперь надо создать триггер. В диалоге:

 

 

Или запросом:

CREATE EVENT TRIGGER sss ON DDL_COMMAND_START
    WHEN TAG IN ('CREATE INDEX')
    EXECUTE PROCEDURE public.asnitch();

Таким образом функция будет вызываться перед каждым созданием индексов, и можно производить разные манипуляции над данными.

Для интересующихся - ссылка на документацию по PostgreSQL на русском

восстановление данных

См. также

Архивирование (backup) Журнал регистрации Поиск данных Системный администратор Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 1С:Управление торговлей 11 Платные (руб)

База данных «сама» меняет данные в документах/справочниках? Тогда данный журнал регистрации изменений документов в 1С для Вас! Практически не влияет на скорость записи объектов за счет быстрого алгоритма! Скорость работы почти в 2 раза выше типового механизма «История изменений». Позволяет следить за изменениями и удалением в любых ссылочных объектах конфигурации, с возможностью архивации по HTTP(!) или COM, и сверткой данных. А так же, может восстановить состояние реквизитов (значения) до момента изменения или удаления объекта из базы. Есть ДЕМО-база где можно самостоятельно протестировать часть функционала! Работает на любых платформах выше 8.3.14+ и любых конфигурациях! Версия 3.1 от 24.08.2023!

21600 руб.

15.05.2017    43092    12    24    

40

Архивирование (backup) Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Данная разработка позволит решить вопрос с резервным копированием Ваших баз в автоматическом режиме, расположенных на сервере 1С. Система умеет ставить блокировки на вход, блокировать фоновые задания, принудительно отключать сеансы пользователей. И все это система делает в автоматически при создании бэкапа (или через команду). Выгрузка происходит в родной формат 1С - .dt. Так же система умеет архивировать данные выгрузки с установкой пароля. Умеет менять расширение файла zip или dt на любое указанное вами, что позволит сохранить выгрузки от шифровальщика. Может удалять старые копии выгрузок, оставляя указанное количество резервных копий, начиная с самой поздней.

6000 руб.

06.11.2012    71284    623    45    

83

Архивирование (backup) Системный администратор Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Программа позволяет выполнять автоматическое создание копий файловых и серверных информационных баз 1С Предприятие 8 и размещение копий в облаке Яндекс.Диск, локальном или сетевом ресурсе.

1200 руб.

03.09.2014    15164    15    6    

21

Архивирование (backup) Администрирование СУБД Системный администратор Россия Бесплатно (free)

Постараюсь объяснить, зачем нужно резервное копирование именно журнала транзакций, а не только базы данных, и почему я словно сбросил груз, настроив его - как, покажу, естественно. Кстати, будут скрипты T-SQL (с подробными комментариями) - отличный способ сделать администрирование базы более уютным.

04.12.2023    7669    n_mezentsev    15    

27

Архивирование (backup) Системный администратор Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данной инструкции будет описано, как с помощью pgAdmin, bat-файлов и планировщика заданий Windows организовать резервное копирование, восстановление и хранение копий баз данных.

07.10.2022    23473    sapervodichka    37    

144

Архивирование (backup) Системный администратор Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Захотелось клиентам выгрузку архива баз, и выгрузку в дт, готовые скрипты с сети не заработали. Может, кому-то поможет. Релиз 8.3.18.1741.

1 стартмани

25.08.2022    5185    3    Gnom-Gluck    6    

7
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 785 15.04.22 00:17 Сейчас в теме
"К сожалению, формат DT закрытый".
Будут проблемы с DT - приходите ко мне - формат DT знаю, умею, могу...
user1263364; kser87; maXon777; +3 Ответить
2. Pasha1st 844 15.04.22 08:46 Сейчас в теме
(1) Да я тоже его смотрел, и даже точечно исправления вносил. Как-то нет желания повторять :)
Тогда вопрос по .dt - я правильно понял что данные таблиц идут в порядке следования в DBSchema (который идёт как "Database" после данных спецтаблиц)? И список полей надо оттуда же парсить?
6. kser87 2452 15.04.22 14:03 Сейчас в теме
(1) напиши статью, оценим
zaic; kraynev-navi; +2 Ответить
15. user1263364 22.03.23 22:29 Сейчас в теме
(1)Есть проблемы, как связаться?
16. Pasha1st 844 23.03.23 09:54 Сейчас в теме
(15) Если есть проблема с восстановлением - контакт отправил в личку
29. user2056692 22.02.24 21:59 Сейчас в теме
Здравствуй, сможешь файл dt исправить, после выгрузки не загружается . Выдает ошибку неверный формат
30. zaurdmailru 02.03.24 12:26 Сейчас в теме
(1)Добрый день!
Нужна помощь с восстановлением файла dt. кроме него ничего не осталось (. При загрузке выдает ошибку Неверный формат фала, ошибка потока
31. Pasha1st 844 02.03.24 18:15 Сейчас в теме
(30) добрый день. Выложите файл и пришлите ссылку в личку, посмотрю. Но если "ошибка потока" в данном случае шансов мало
32. user990935 29.03.24 13:58 Сейчас в теме
(1) Есть проблема с dt. неверный формат файла для загрузки информационной базы . Кто может помочь?
3. Sedaiko 586 15.04.22 11:59 Сейчас в теме
Самый надежный вариант - не делать "бэкапы" в dt.
Для файловой базы - копируется и zip'уется 1cv8.1cd, для клиент-серверной - средствами СУБД.
*.dt служит для переноса данных между разными СУБД

и к тому же делать "бэкапы" в dt всегда дольше, чем длятся правильные способы резервного копирования
IgorS; marsohod; Borisych; v3132; +4 Ответить
4. Pasha1st 844 15.04.22 12:53 Сейчас в теме
(3) ну пользователи обычно не понимают таких тонкостей.
Вот одна из историй - база слегка попортилась, клиент самостоятельно решил вылечить - выгрузил в dt, и попробовал загрузить обратно туда же. Копию 1cd не делал, исходный запоролся, и остался только dt который не загружался...
8. RustIG 1720 15.04.22 19:50 Сейчас в теме
(4) почем нынче восстановление базы? тыщ 10 поди за результат?
7. RustIG 1720 15.04.22 19:49 Сейчас в теме
(3) выгружаю дт для переноса файловых баз клиентов к себе на ноут - файл дт весит меньше, чем файл 1cd - быстрее копируется по интернету
9. Pasha1st 844 15.04.22 22:53 Сейчас в теме
(7) потому что в .dt 1. нет мусора, 2.он сжатый (практически zip). Если 1сд сжать архиватором получится примерно такой же размер, особенно если перед этим сделать сжатие в ТиИ.
oleg-x; SerVer1C; +2 Ответить
5. kser87 2452 15.04.22 14:02 Сейчас в теме
Интересная идея грузить dt в серверные базы. Возьму на заметку
10. user1777567 11.05.22 13:21 Сейчас в теме
Добрый день! Есть база dt под восстановление с такой же ошибкой, напишите, кто может восстановить
11. mmill 11.01.23 12:03 Сейчас в теме
добрый день! схожая ситуация, но ничего не помогло, готов оплатить работу , кто может помочь?
12. Pasha1st 844 11.01.23 16:26 Сейчас в теме
13. seelikon 20.02.23 11:38 Сейчас в теме
Доброго времени суток, кто может помочь с восстановление баз данных 1с?
14. Pasha1st 844 20.02.23 14:50 Сейчас в теме
22. nksk 04.10.23 12:05 Сейчас в теме
(14) почту можно , нужна помощь
17. Askol2 30.03.23 08:00 Сейчас в теме
Создал триггерную функцию, после чего создаю для таблицы триггер, но ошибка вида при загрузке DT Никуда не уходит.

null value in column "_fld16137_type"
Так как
1С загружает базу в следующем порядке:
1. удаляются таблицы базы если они были
И триггер, который я создавал для таблицы исчезает вместе с ней и соответственно, не исполняется. Может триггер по другому как-то завести надо?
18. Pasha1st 844 30.03.23 08:59 Сейчас в теме
(17) надо поймать момент
сначала создать функцию, потом запустить загрузку и следить - как появится нужная таблица - создать триггер. можно попробовать ещё создать триггер на событие создания таблицы и там создавать триггер на вставку, но мне хватало и вручную создать в нужный момент
nathanholn; Askol2; +2 Ответить
19. Pasha1st 844 09.04.23 13:11 Сейчас в теме
Столкнулся с дубликатами в таблице params, и отловить нужный момент стало практически невозможно. Причина - у таблицы filename - первичный ключ, он создаётся вместе с созданием таблицы. Пришлось адаптировать.
1. создаём триггерную функцию на вставку - тут как обычно. Назовём её public.q1()
Тело:
  IF EXISTS(SEL ECT FR OM params WHERE filename=NEW.filename) THEN
    RETURN NULL;
  END IF;
  RETURN NEW;

2. Создаём функцию событийного триггера, срабатывать он будет после создания таблицы, и создавать нужный триггер на вставку, тело:
  BEGIN
    CREATE TRIGGER params_flt
      BEFORE INSERT
      ON public.params
      FOR EACH ROW
      EXECUTE FUNCTION public.q1();
  EXCEPTION
    WHEN others THEN
  END;
Показать

3. Собственно создаем событийный триггер, срабатывающий после создания таблицы:
CRE ATE   EVENT TRIGGER sss ON DDL_COMMAND_END
    WHEN TAG IN ('CRE ATE   TABLE')
    EXECUTE PROCEDURE public.asnitch();


Итого таблица будет создана сразу с нужным триггером и не надо будет ловить момент.
nathanholn; +1 Ответить
20. nathanholn 17.05.23 16:24 Сейчас в теме
Здравствуйте! Как с Вами связаться, такая же проблема с DT файлом. Спасибо!
21. Pasha1st 844 17.05.23 19:52 Сейчас в теме
(20) Ответил в личку
nksk; nathanholn; +2 Ответить
23. пользователь 04.10.23 12:06
Сообщение было скрыто модератором.
...
24. nksk 04.10.23 12:07 Сейчас в теме
26. nksk 04.10.23 12:24 Сейчас в теме
Здравствуйте! Как с Вами связаться, такая же проблема с DT файлом. Спасибо!
25. nksk 04.10.23 12:07 Сейчас в теме
27. Pasha1st 844 04.10.23 12:44 Сейчас в теме
(25) в личном сообщении дал контакт, опишите проблему
28. gusst5 18.10.23 23:27 Сейчас в теме
(27) Добрый день. Скиньте контакт в личку, у меня похожая проблема.
Прикрепленные файлы:
Оставьте свое сообщение