Тонкости настройки Истории данных

02.12.19

База данных - Инструменты администратора БД

dbo._DataHistoryQueue0 - что это такое и как с этим бороться.

Добрый день!

Про настройки хранения истории данных написано много. Но мало информации о том, как же это все работает. Итак, при включении режима использования истории данных,

все реквизиты объекта записываются в метаданные, но для того чтобы увидеть сохраненную версию, необходимо выполнить команду

ИсторияДанных.ОбновитьИсторию();

Данная команда выполняется только с правами Администратор.

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

Данные=<Ссылка на объект>.ПолучитьОбъект();

Пользователь=ПользователиИнформационнойБазы.ТекущийПользователь();

ИсторияДанных.ЗаписатьВерсию(Данные,ТекущаяДата(),Пользователь.УникальныйИдентификатор,Пользователь.Имя,Пользователь.ПолноеИмя,ВидИзмененияДанных.Изменение);

Так как же это все таки работает???

Все версии данных, при сохранении объектов попадают в очередь (таблица dbo._DataHistoryQueue0 на сервере SQL), и накапливаются там, пока не выполнится команда

ИсторияДанных.ОбновитьИсторию();

Далее записи перемещаются в dbo._DataHistoryVersions, собственно из этой таблицы мы и видим данные, когда заходим в клиенте в раздел «История изменений»

Вроде бы ничего сложного, можно пользоваться.

Оказывается, есть нюансы:

Задача:

А) Необходимо вести историю данных, причем сохранять изменения, которые делали пользователи, а не регламентные задания.

Б) Так же необходимо учесть, если объект пересоздается в другом месте БД, необходимо перенести и его историю. Например: оборудование демонтировали. В БД есть два объекта 1) Оборудование подразделения и 2) Демонтированное оборудование подразделения. При демонтаже в первом объекте запись удаляется, а во-втором создается путем копирования части реквизитов (структуры объектов не одинаковые).

Решение:Для решения пункта А) нам необходимо в объектах использовать процедуру

Процедура ПослеЗаписи(ПараметрыЗаписи)

Данные=<Ссылка на объект>.ПолучитьОбъект();

Пользователь=ПользователиИнформационнойБазы.ТекущийПользователь();

ИсторияДанных.ЗаписатьВерсию(Данные,ТекущаяДата(),Пользователь.УникальныйИдентификатор,Пользователь.Имя,Пользователь.ПолноеИмя,ВидИзмененияДанных.Изменение);

КонецПроцедуры

, где Ссылка на объект – ссылка на объект, для которого необходимо записать версию, т.е. объект, которые мы только что записали.

            Почему после записи?

            Потому что версия формируется не из формы, а из сохраненной записи БД.

            Почему не используется

ИсторияДанных.ОбновитьИсторию();

?

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

ИсторияДанных.ОбновитьИсторию(); 

все эти версии будут привязаны к объекту.

            Для решения Б) нам придется немного схитрить. Дело в том, что готовой функции переноса истории с объекта в объект нет. Так что будем переписывать историю

            После записи во-второй объект («Демонтированное оборудование подразделения»), нам необходимо его получить и добавить историю, которая была у объекта Источника:

ДанныеИсточника=<Ссылка на объект источник>;

Демонтаж.Записать();

            Объект= ДанныеИсточника.ПолучитьОбъект();

            Отбор = Новый Структура;

    Отбор.Вставить("Данные", Объект.Ссылка);

            Версии = ИсторияДанных.ВыбратьВерсии(Отбор);

            ДанныеПриемника=Справочники.ДемонтированноеОборудование.НайтиПоКоду(Демонтаж.Код).ПолучитьОбъект();

            Пользователь=ПользователиИнформационнойБазы.ТекущийПользователь();

            Для Каждого Строка Из Версии Цикл

    Строка.Данные= ДанныеПриемника;

            ИсторияДанных.ЗаписатьВерсию(Строка.Данные,Строка.Дата,Строка.Пользователь,Строка.ИмяПользователя,Строка.ПолноеИмяПользователя,Строка.ВидИзмененияДанных,Строка.Комментарий,Строка.Транзакция,Строка.Узел);

            КонецЦикла;

, где Ссылка на объект – ссылка на объект источника, историю которого мы хотим передать новому объекту.

ВАЖНО!!!

После переноса истории данных, во-втором объекте будут видны только те поля истории, которые совпадают по наименованию и типу с первым объектом.

Поля, которые нужны только для отображения истории первого объекта, и не используются во-втором объекте можно скрыть от пользователей и не заполнять при переносе из первого объекта.

Вроде бы задача решена, но что нам делать с очередью ИсторииДанных, которая продолжает расти, увеличивая нашу базу не по дням, а по часам.

К сожалению, во встроенной функции  ИсторияДанных такой команды нет, поэтому пришлось делать костыльное решение. В SQL создал плановое задание из двух шагов:

Use <имя БД>
truncate table dbo._DataHistoryQueue0

USE [<имя БД>]
GO

DBCC SHRINKDATABASE(N'<имя БД>' )

GO

 

Первый шаг, чистить таблицу очереди истории данных

Второй шаг, сжимает БД.

Если второй шаг не выполнять, БД не уменьшится в размерах.

В итоге размер БД сократился в 20 раз. Именно столько накопилось в очереди за 2 месяца использования истории данных.

См. также

Автоподбор ролей для профилей и групп доступа в любых типовых базах 1С УТ 11, КА 2, ERP2, Розница 2/3, УНФ 16/3, БП 3, ЗУП 3 и подобных (УФ, Платформа 8.3.14+)

Инструменты администратора БД Роли и права 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Роли… Вы тратите много времени и сил на подбор ролей среди около 2400 в ERP или 1500 в Рознице 2, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 15.12.2023, версия 1.1.

12000 руб.

06.12.2023    2972    13    1    

34

SALE! 20%

Infostart УДиФ: Управление данными и формами

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

10000 8000 руб.

10.11.2023    3521    11    1    

34

SALE! 30%

PowerTools

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

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

3600 2520 руб.

14.01.2013    177734    1073    0    

849

Ускоренное проведение документов (x4), устранение ошибок 60/62 счетов и зачет авансов (Бухгалтерия 3.0)

Закрытие периода Инструменты администратора БД Корректировка данных Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Расширение «Оперативное проведение» в 4 раза уменьшает время проведения документов и закрытия месяца. Является комплексным решением проблем 62 и 60 счетов. Оптимизирует проведение при включенной функциональной опции «Раздельный учет НДС». Используется в более 10 организациях уже 2 года. Совместимо с конфигурацией Бухгалтерия 3.0 (+КОРП).

14400 руб.

29.04.2020    27374    79    146    

59

Система хранения присоединенных файлов в томах на диске

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

Конфигурация Комплексная автоматизация 1.1 (и УПП 1.3 тоже) хранит файлы и изображения в справочнике Хранилище дополнительной информации в реквизите Хранилище типа ХранилищеЗначений. Та же история с ВложениямиЭлектроннойПочты. Но при этом присоединенные файлы в Электронном документообороте хранит в томах на диске. Эта доработка позволяет использовать стандартный механизм хранения файлов, изображений и вложений электронных писем в томах на диске. При этом можно разделить тома хранения по объектам конфигурации.

4200 руб.

10.11.2015    61313    88    59    

73

"Менеджер потоков 2.1": УПП: "Восстановление партий"

Инструменты администратора БД Платформа 1С v8.3 1С:Управление производственным предприятием Россия Бухгалтерский учет Управленческий учет Платные (руб)

Как оптимизировать то, что, считалось, не поддается оптимизации? Как повысить доступность базы данных? Как проводить самую «времяемкую» операцию не по паре раз в неделю, а по несколько раз в день*? Ответ есть!

20000 руб.

12.09.2019    11745    5    9    

7

Брандмауэр для сервера 1С Предприятие 8 - внешнее управление сеансами

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

Управление возможностью начала и возобновления сеансов пользователей по различным условиям, ограничение общего числа возможных сеансов для работы с информационной базой, резервирование возможности работы с информационной базой определенных польззователей, запрет запуска нескольких сеансов для пользователя, журнализация событий начала (возобновления) и завершения (гибернации) сеансов, ведение списка активных сеансов для информационных баз кластера серверов

3600 руб.

06.02.2017    31109    31    18    

47

Хранилище файлов на SQL

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

Привязка файлов / сканов к объектам 1С с сохранением их на SQL-сервере

12000 руб.

09.10.2019    10982    5    8    

9
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Darklight 32 03.12.19 09:34 Сейчас в теме
Боже мой, что же у Вас всё так сумбурно написано :-( Вот так и не смог понять - ради чего это всё тут написано - что за такие сложности при работе с историей?

Я, просто, не использую типовой механизм, у меня очень давно используется самописное универсальное решение - и я просто не могу понять - откуда проблемы?
У самописки - было только два "тонких места" - это работа в РИБ (особенно когда возникло желание существенно "упаковать" данные истории - чтобы не использовать ссылки UID по 32 байта и не дублировать одинаковые строки); и вынос истории в отдельную базу (ибо хранить её - в той же базе - это бред "сивой кобылы", такой же, нет, ещё больший, как и бред хранить в той же базе присоединённые файлы - когда они есть почти у всех первичных документов в виде куче сканов).

А у Вас тут прям какие-то совершенно непонятные проблемы!

Ну ясен пень - что необходимость вызывать "ИсторияДанных.ОбновитьИсторию()" в основном это бред - историю придётся писать вручную, по старинке, через подписки на события через "ИсторияДанных.ЗаписатьВерсию(...)" - ибо, если кто-то сейчас пишет историю, то наверняка кто-то может её сейчас или через 5 минут уже анализировать (часто бывает - записываешь - и сразу смотришь - что там изменилось).
А переходить на отложенное выполонение через "ИсторияДанных.ОбновитьИсторию()" имеет смысл только выборочно - при массовых изменениях данных в обработках.

А вот, про перенос истории мне вообще не ясно - ЗАЧЕМ?

Как и про чистку таблицы "dbo._DataHistoryQueue0", она что - сама при вызове указанных выше функций записи истории не очищается?
frkbvfnjh; +1 1 Ответить
2. ZOKS_1 40 03.12.19 10:12 Сейчас в теме
(1)
Это все написано для тех кто использует стандартные механизмы платформы и не изобретает велосипед с регистрами.
Проблема которая здесь описана, связана с необходимостью вести историю данных исключая хранения ненужных версий данных, и необходимостью переноса истории данных, если объект был перемещен в другой справочник, или документ. При такой реализации использовать ИсторияДанных.ОбновитьИсторию() не получится, и очередь версий данных сама не почистится, а накопление очереди приведет к необоснованному росту БД со всеми вытекающими проблемами.
Вероятнее всего Вам не понятна статья, потому что вы с такими проблемами в своей работе не встречались.
-Denton-; Ranetka; AntonKulmetev; KilloN; +4 Ответить
3. Darklight 32 03.12.19 11:23 Сейчас в теме
(2)да, вероятно не встречался - ибо эта встроенная история бред бредом! Но статья у Вас всё равно сумбурно написана!
Dimasik2007; +1 4 Ответить
4. Glebis 13 04.12.19 16:46 Сейчас в теме
объект пересоздается в другом месте БД, необходимо перенести и его историю
. Несколько раз перечитал, но задачу "Б" так и не понял: что значит пересоздается, GUID остается?. Что за "другое место БД"?. Объекты одного типа или разных? У этих объектов часть реквизитов совпадает?
5. ZOKS_1 40 05.12.19 08:32 Сейчас в теме
(4)
Есть два документа1) Оборудование подразделения и 2) Демонтированное оборудование подразделения
В первом хранится оборудование, эксплуатируемое подразделением. В первом учитываются ремонты, простои, плановые остановки
Второй документ хранит оборудование, выведенное из эксплуатации и затраты по этому оборудованию за весь цикл его жизни.
Два документа имеют часть реквизитов одинаковых, а часть разных. Во-втором документе ТЧ аналогичная первому документу скрыта на форме и при переносе документа не заполняется. Пустая. А ТЧ затрат заполнена.
При выводе из эксплуатации оборудование из первого документа удаляется, а во-втором создается путем копирования одинаковых реквизитов(кроме ТЧ) и выборками из регистров затрат.
Время от времени специалистам необходимо видеть, какие работы проводились с оборудованием и кто вносил изменения в документ.
Так же демонтированное оборудование иногда возвращают в работу.
В связи с этим есть необходимость видеть всю историю по данному оборудованию.
GUID у объектов разные
Объекты одно типа
У этих объектов совпадают реквизиты только те, по которым необходимо видеть историю.
10. Натаshка 06.05.21 06:03 Сейчас в теме
(5) У меня ощущение, что не правильная архитектура выполненной задачи потом порождает всякие костыли. Могу ошибаться, но справочники 1) Оборудование подразделения и 2) Демонтированное оборудование подразделения - должен быть один справочник, у которого имеется статус.
maxim_ternavsky; user768319; 1C_Nami; anatox; +4 Ответить
6. AlexiyI 21.10.20 11:19 Сейчас в теме
Задача "А".
1. В примере обрабатывается только запись из формы (это же модуль формы в примере)?
2. Почему не использовать событие ПриЗаписи() объекта, а там уже установить условие, что запись выполняется пользователем (само условие опускаю)? В этом случае получать объект по ссылке не нужно, что избавит от тормозов.
3. В продолжение события ПриЗаписи() объекта. Будет ли в этом случае корректно отрабатывать транзакция? Т.е. не стоит писать историю при отказе.
4. Для случая "А" исключено создание регламентного задания с ОбновитьИсторию()? Если да, то получается, нужно обрабатывать запись истории для каждого объекта индивидуально?

Все равно не совсем понял логику. ОбновитьИсторию() делает то же самое, что и ЗаписатьВерсию(), только для всех объектов?
Я установил в конфигураторе использование истории данных БЕЗ каки-либо обработок. История пишется и просматривается. Теперь не понимаю, для чего ОбновитьИсторию()? Удалится ли история через какое-то время или что еще может случиться?
7. levante90 05.02.21 09:45 Сейчас в теме
История данных. Флаг - "Обновлять историю данных сразу после записи" в свойствах объекта.

У меня история данных становится доступной сразу, даже если флаг не установлен, хотя по идеи история должна помещаться в очередь и становится доступной после вызова метода ОбновитьИсторию() у менеджераИсторииДанных, по крайнее мере такая инфа на ИТС и зазеркалье. Получается метод ОбновитьИсторию для этих целей не нужен?

Скрины:
Свойства объекта - http://prntscr.com/yd12uv
Уже доступная история изменений - http://prntscr.com/yd165w
1serger; sertak; Shmell; +3 Ответить
8. Shmell 533 09.02.21 19:52 Сейчас в теме
(7) Такая же ситуация: копнув таблицы _datahistoryqueue0 и _datahistoryversions - обратил внимание, что при не установленном флаге как у вас - пишется все в _datahistoryqueue0 а в _datahistoryversions пусто. Но стоить вызвать просмотр истории версии данных, то запись мгновенно уходит из первой таблицы и попадает во вторую. Получается - принудительная обработка очереди.
Rans; sertak; +2 Ответить
12. NicholasUzunov 20.07.22 10:17 Сейчас в теме
(7) В форме обработки для просмотра истории (встроенная обработка конфигурации) в обработчике "При создании на сервере" вызывается метод "Обновить историю".
9. sertak 314 14.04.21 08:59 Сейчас в теме
Возникла подобная ситуация: в некоторых регламентных заданиях осуществляется перенос дат на текущую дату документов, отобранных по определенных критериям (чтобы у пользователей они были всегда сверху или снизу, сортировка в списках всегда по дате). И, соответственно, пишутся сотни версий, в которых нет ценной информации. Решил следующим образом (увидел пример, кстати, в какой-то обработке с инфостарта), код упрощен:
После получения объекта, в котором будет изменена дата:

ДокументОбъект = ИнвойсСсылка.ПолучитьОбъект();
ДокументОбъект.ДополнительныеСвойства.Вставить("НеДобавлятьВерсиюВИсторию", Истина);
ДокументОбъект.Дата = ТекущаяДата();
ДокументОбъект.Записать(?(ДокументОбъект.Проведен, РежимЗаписиДокумента.Проведение, РежимЗаписиДокумента.Запись));

В модуле обработчика подписки на событие ПриЗаписи:

Если Источник.ДополнительныеСвойства.Свойство("НеДобавлятьВерсиюВИсторию") И Источник.ДополнительныеСвойства.НеДобавлятьВерсиюВИсторию Тогда  
	Источник.ЗаписьИсторииДанных.Отказ = Истина;		
КонецЕсли;

Т.е., с помощью изменения реквизита Отказ структуры ЗаписьИсторииДанных можно гибко управлять созданием версии.
user1572509; METAL; tetraren; begemot; Shmell; simgo83; Aleskey_K; 1C_Nami; +8 Ответить
11. simgo83 69 02.09.21 10:31 Сейчас в теме
(9) В моем случае у документа был вариант "Использовать" и этого "Источник.ЗаписьИсторииДанных.Отказ = Истина; " не хватило
Сделал так:
ДокументОбъект.ЗаписьИсторииДанных.ОбновлятьИсториюСразуПослеЗаписи =Ложь;
ДокументОбъект.ЗаписьИсторииДанных.Отказ =Истина; 	

и стало норм
begemot; sertak; +2 Ответить
13. NicholasUzunov 20.07.22 10:20 Сейчас в теме
Не понятно а зачем две таблицы?
14. investec 01.05.23 18:10 Сейчас в теме
Таблица _DataHistoryQueue0 очищается при выполнении операции сжатия информационной базы.
15. bulpi 215 04.07.23 19:04 Сейчас в теме
Уважаемый автор, нужно БОЛЬШИМИ БУКВАМИ предупреждать о том, что Ваш скрипт очищает всю историю, которую никто ни разу не смотрел.
Оставьте свое сообщение