Динамическое обновление — это, конечно, нехорошо, но порой других возможностей просто нет. К примеру, компания, работающая 24/7 с количеством людей, работающих в базе, от 100 человек. Когда всех выгнать из базы и провести обновление очень затратно и необходимо заранее это согласовывать, тогда приходится использовать динамическое обновление. Сама ошибка заключется в том, что в момент записи в таблицу «Config» что-то произошло, что помешало корректно закончить данную процедуру. И существует два основных способа лечения этой проблемы:
— Первый — это удалить записи о том, что конфигурация обновлялась (не рекомендую, так как у меня не всегда корректно работало).
— Второй способ — перезаписать все данные в таблицы «Config» из резервной копии вашей рабочей базы.
Второй способ более надежный, но была проблема в том, что необходимо было поднимать и разворачивать SQL-ный бэкап, что занимало много времени.
И поэтому придумали простой и надежный механизм. Перед каждым динамическим обновлением просто сохранять таблицы «Config» и «ConfigSave» (Сохранять ConfigSave» не обязательно, мы делали, чтобы сохранить сделанные наработки в конфигурации).
Создал внешнюю обработку с двумя кнопками «Сохраниться перед динамическим обновлением» и «Восстановить данные после ошибки динамического обновления».
Копка «Сохраниться перед динамическим обновлением» вызывает процедуру:
Процедура Сохраниться()
//Подключение к SQL
Connection=Новый COMОбъект("ADODB.Connection");
Connection.ConnectionTimeOut =600;
Connection.Open("Provider=SQLOLEDB.1;Password=Пароль;Persist Security Info=True;User ID=Пользовать;Initial Catalog=SQL_ИмяБазы;Data Source=SQL_Сервер");
RecordSet=Новый COMОбъект("ADODB.Recordset");
RecordSet.CursorLocation=3;
RecordSet.LockType=2;
Запрос="[master].[dbo].[sp_backup_config_tables]";
RecordSet.Open(Запрос, Connection);
//Сохраняем информацию о последнем обновлении
СтруктураДанных=Новый Структура();
СтруктураДанных.Вставить("Пользователь",ПараметрыСеанса.ТекущийПользователь);
СтруктураДанных.Вставить("ДатаСохранения",ТекущаяДата());
СтруктураДанных.Вставить("ИмяСервера",ИмяКомпьютера());
ЗначениеВФайл (ПолноеИмяФайла,СтруктураДанных);
ТекстИзменений="";
Запрос="SELECT [FileName] FROM [SQL_ИмяБазы].[dbo].[ConfigSave]";;
RecordSet.Open(Запрос, Connection);
Если RecordSet.RecordCount>0 Тогда
RecordSet.MoveFirst();
Пока НЕ RecordSet.EOF() Цикл;
ТекстИзменений=ТекстИзменений+Символы.ПС+строка(RecordSet.Fields(0).Value);
RecordSet.MoveNext();
КонецЦикла;
КонецЕсли;
RecordSet.Close();
Сообщить("Данные сохранены. Будут изменены таблици:"+ТекстИзменений);
КонецПроцедуры
Копка «Восстановить данные после ошибки динамического обновления» вызывает процедуру:
Процедура Восстановить ()
//Подключение к SQL
Connection=Новый COMОбъект("ADODB.Connection");
Connection.ConnectionTimeOut =6000;
Connection.Open("Provider=SQLOLEDB.1;Password=Пароль;Persist Security Info=True;User ID=Пользовать;Initial Catalog=SQL_ИмяБазы;Data Source=SQL_Сервер");
Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText ="[master]. [dbo].[sp_restore_config_tables]";
Command.CommandType = 1;
RecordSet = Новый ComОбъект("ADODB.RecordSet");
RecordSet.CursorType = 3;
RecordSet.LockType = 2;
RecordSet = Command.Execute();
КонецПроцедуры
[master].[dbo].[sp_backup_config_tables] и [master]. [dbo].[sp_restore_config_tables]
Это процедуры в SQl.
[master].[dbo].[sp_backup_config_tables]
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
/*
** The system profile of the same type of agent will be used as a template for
** the parameters in this new user profile.
*/
ALTER procedure [dbo].[sp_backup_config_tables]
AS SET NOCOUNT ON
truncate table [dbo].[Config_Backup];
truncate table [dbo].[ConfigSave_Backup];
insert into [dbo].[Config_Backup]
select * from SQL_ИмяБазы.[dbo].[Config];
insert into [dbo].[ConfigSave_Backup]
select * from SQL_ИмяБазы.[dbo].[ConfigSave];
[master]. [dbo].[sp_restore_config_tables]
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_restore_config_tables] Script Date: 01/22/2024 11:48:09 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
/*
** The system profile of the same type of agent will be used as a template for
** the parameters in this new user profile.
*/
ALTER procedure [dbo].[sp_restore_config_tables]
AS
SET NOCOUNT ON
truncate table SQL_ИмяБазы.[dbo].[Config];
truncate table SQL_ИмяБазы.[dbo].[ConfigSave];
insert into SQL_ИмяБазы.[dbo].[Config]
select * from [dbo].[Config_Backup];
insert into SQL_ИмяБазы.[dbo].[ConfigSave]
select * from [dbo].[ConfigSave_Backup];
При нажатии кнопки «Восстановить данные после ошибки динамического обновления» блокировать работу пользователей не надо. Те, которые уже работают, ничего не заметят, а новые зайти не смогут.
Если раньше такая ошибка считалась критичной и время восстановления занимало до 1 часа, то теперь оно сократилось до 5 минут.
Update :
Статья о триггере , для сохранения таблицы Config перед обновлением //infostart.ru/public/327674/
(1) patimka, кэш чистить далеко не всегда помогает в силу того, что изменения в базу зачастую уже записаны и записаны как раз с ошибкой. кэш поможет, только если все сохранилось, а у пользователя нет изменений.
для скульных баз действительной хороший способ описан.
вопрос автору: обязательно в master процедуры добавлять или можно в любую другую базу? я не силен в языке запросов, так что можно пояснения по поводу имен объектов и что где храниться в итоге?
Отличная идея!
https://technet.microsoft.com/ru-ru/library/ms189799%28v=sql.105%29.aspx
Можно пойти еще дальше и автоматизировать создание бэкапов этих таблиц путем создания триггера.
Это не противоречит лицензионному соглашению 1С и не нужно будет руками запускать обработку
Шикарно.
Очень понравилось название «Восстановить данные после ошибки динамического обновления»
(2) Lord_Michael, Поместить процедуры можно куда угодно,важно чтобы к ним был доступ. Помещать их в рабочую базы не рекомендую , так как к примеру при загрузки данных средствами 1С (dtшник) ваша процедура затрется. А в мастере она будет в надежной сохранности. В итоги при сохранение, данные хранятся в DatabasesSystem DatabasesmasterTablesdbo.Config_Backup
где dbo.Config_Backup — это таблица , полностью скопированная с таблицы dbo.Config вашей рабочей базы
(3) ChiginAV, По началу так и хотели сделать,но в действительности реализовать не получилось. Дело в том что 1С использует SQL как хранилище данных , а сам процесс динамического обновления производит платформа и в SQL пишутся данные уже по факту. Отловить триггером этот механизм в платформе не получится, единственное что вы можете это получить момент когда таблица начнет меняться. Но для восстановления нужна таблица до изменения , поскольку остановить процесс записи в нее нельзя, а попытка замедлить этот процесс приводила к ошибкам в платформе. Да и сам процесс копирование записей занимает время, у меня это от 3 до 8 секунд ( Комплексная Автоматизация — 25847 строк в таблице Config и необходимо помнить,что каждая запись не просто текстовые данные, к примеру ячейка [BinaryData] — по сути архивированный файл с описанием метаданного ,а они бывают относительно тяжелыми, к примеру: запись содержащая файл с конфигурацией поставщика от Комплексной Автоматизации весит 261 МБ ).
(6) Kondratenko.as,http://main.1c-ei.ru/Home/help/object_config/depot работает именно на триггерах
(7) German, Вещь конечно хорошая но и денег стоит)
(7) German, Ну по презентации не понятно как именно она работает. А ссылка интересная,на досуги по изучаю. Но по мне ручной контроль этого менее трудозатратный. И скорее всего при разработке «Хранилища» были задействованы люди знающие как работает этот механизм в платформе 1С. В примере была предоставлена конфигурация ЗУП она довольно простая , разумней было бы показать примеры на УПП и уже на ней говорить о скорости работы. Я пробовал ставить триггер на изменение таблицы и копировал всю ее,а в «Хранилище» скорее всего сохраняется только измененные объекты. Распаковать и получить структуру конфигурации это не проблема V8Unpack20 в свободном доступе причем с его помощью можно не только распаковывать, но и обратно запаковать метаданное и поместить его в SQL , вопрос только в том на сколько это корректно и правильно. На мой взгляд о прямой записи в SQL стоит всерьез говорить только когда 1с выпустит API. 1С бывает сама внезапно перестает работать и сваливаться в дамп 🙂
(8) vslimv,
Само собой 🙂
почти 10 лет на промышеннЫХ базах используется
Неужели ж оно настолько часто происходит, что прям вот такая автоматизация нужна?
Просто восстановить конфиг из суточного бэкапа раз в год — не вариант?
(11) AlX0id, Происходит не так часто, но поскольку компания работает 24/7 то простой не кому не нужен, а если простой по вине программистов то время простоя вычитается из их жалования:-). Вся проблема во времени восстановления. А динамически обновляемся в день раз 4-5 точно.
(11) AlX0id, У кого-то раз в год) А кому-то не так везет)))
Однажды согрешила, 17 раз подряд динамически обновила) Повезло что ничего не упало)
судя по тексту храгимок есть вероятность восстановления конфига соседней базы. то есть если выполнить бекап одной базы, то с легкостью мона восстановить в другой
(15) Fox-trot, Данный пример был создан для одной рабочей базы,чтоб можно было сделать вызов из любой базы,а не только из рабочей…
(12) Kondratenko.as,
Ну мы тоже не редко обновляемся демонически. Необходимость пересадки конфы возникала лишь пару раз за последние пять лет (тьфу-тьфу-тьфу).
// ЗЫ. Вот прям сегодня вылезла «Нарушена целостность конфигурации» при старте конфигуратора у одного из клиентов. Сглазил чо ли.. Вроде обошлось отключением/подключением ИБ на сервере 1С..
(16) ну так а я те про что. сохраняешь в одной, восстанавливаешь в другой ))
(18) Fox-trot, Понятно, я тебя не правильно понял. Я думал ты как на ошибку указывал:).
На мой взгляд, это все костыли. Если база данных находится на MS SQL сервере выше или 2005 и база данных имеет Full логирование и бекапы трензакт лога то можно воспользоваться официальной инструкциейmsdn.microsoft.com и восстановить базу до момента нажатия на кнопочку «обновить базу данных». Ну, а по поводу очистки таблицы конфигурации это не всегда спасает.
интересная идея!
(20) narus1,
решение же как раз предлагается без потери данных, как в случае отката по всему логу транзакций — перетирается только таблица с конфигурацией
Согласен если это делает автомат. Но мне интересно посмотреть тому человеку в глаза который после динамического обновления не запускает предприятие, и к тому же 1с вылетает при самом обновлении. То есть если у тя при этом работают 100 клиентов в этом есть смысл. Как говориться вернуть в зад :-).
Добрый день!
В хранимой процедуре для создания копий лучше использовать
вместо
т.к. в случае с truncate вылетит ошибка если таблицы еще не созданы.
а у нас просто память течет на 1С Сервере после динамического обновления) потом юзеров выкидывает с ошибкой типа Недостаточно памяти на сервере) хотя там памяти этой еще завались
(12) А можно поточнее раскрыть «не так часто» (ну, если не тайна)?
У нас система всего лишь 12/5, сотня пользователей, обновления раз 10 в неделю (по дням неравномерно), страшное случилось 1 раз за 5 лет.
(25) gaglo, «не так часто» — Стабильно 1 раз в полгода)
(23) Zhilyakovdr, Зачем дропать? Вам тогда придется и создавать ее заново всякий раз , лишнее время тратить на выполнение
Показать
(24) AllexSoft, версия платформы не 8.3.5.1383 случайно? Там естьбаг с утечкой памяти рабочего процесса, в одной из наших организаций наблюдался.
(28) Puk2, 8.2.19 ) ту же беду наблюдал на 8.3.4.*, на последних 8.3.4 вроде убрали (ну во всяком случае так дико течь перестала)
(27) Kondratenko.as, можно и не дропать, но тогда предварительно, при первом запуске, необходимо убрать truncate иначе вылетит с ошибкой т.к. при первом запуске нет еще таблицы для очистки.
(30) Zhilyakovdr, Согласен с вами,просто я когда создавал таблицу, ее сразу и заполнял)
(31) Kondratenko.as, а зачем ее специально создавать…. MS SQL ее сам создаст…..
У кого нибудь получилось написать триггер?
(33) Zhilyakovdr, Ссылка на статью по триггеруhttp://infostart.ru/public/327674/
Товарищи а с postgresql будет работать?
(35) hiduk, нуна лишь малость допилить
Мне помогло для Postgresql :
Первые 2 пункта позволяют войти в конфигуратор, 3й пункт позволяет сохранять конфигурацию.
1) delete fr om configsave where FileName = ‘commit’
2) delete from configsave wh ere FileName = ‘dbStruFinal’
3) C:UserskubAppDataLocal1C1cv8 удаление всех папок кроме logs
Эта проблема только на Скуле бывает?? На ПостГре такое возможно??
(38)
http://1c.mista.ru/topic.php?id=773470
Полезная статья, надо будет испытать.
Хорошо. Однако если последствия ДО вылезли например через неделю. Как вариант у пользователя начала форма справочника номенклатура некорректно отображаться. Чистка кэша пользователя помогает но потом снова появляется, хотя ДО более не делалось
спасибо. за идею.