gifts2017

Восстановление удаленной информации в базе 1С 8.2 на SQL

Опубликовал Евгений Кузнецов (kuzev) в раздел Администрирование - Тестирование и исправление

Случайно были удалены документы в рабочей бухгалтерской базе. Встал вопрос: «Что делать?». Имеем SQL-бэкапы за предыдущий день и текущий день с уже удаленными документами. Либо восстанавливать ночной бэкап за предыдущий день и повторять все операции за вчерашний день, либо восстанавливать бэкап за текущий день и...

 

Предыстория.

Организация ведет бухгалтерский учет в корпоративной базе по нескольким организациям в типовой 1С 8.2 БП КОРП на SQL 2008. По ночам делаются бэкапы на ленточку. Утром очередного дня обнаружилось, что по нескольким организациям «поехала» отчетность, «краснота», нет документов и пр. В ходе оперативного анализа журнала регистрации выяснилось, что в ночь было запущено удаление документов по нескольким организациям, в частности «авансовых отчетов» (причину выводим за скобки). Ночной бэкап был сделан, пока шел процесс удаления документов, т.е. утром не оказалось полноценной копии базы, чтобы сделать восстановление штатными средствами.
Примечание: удаление документов выполнялось командой Удалить() без контроля ссылочной целостности.

Данная новость настигла меня, когда я был вдали от офиса, компьютера и интернета. Чуть позже я понял, что в этом был небольшой плюс для меня, т.к. не ощущал того, что в этот момент происходит в бухгалтерии, в службе ИТ и других подразделениях. Голова была холодной, что позволяло мыслить свободнее.

 

Варианты решений.

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

2. Восстановить базу из бэкапа от прошедшей ночи. Затем экспортом-импортом перенести недостающие документы из копии базы от предыдущей ночи. Можно, но… в этом случае придется перепроводить эти документы + восстанавливать последовательность по всем организациям. У нас это займет около месяца, а вчерашняя отчетность нужна сегодня (!).

3. Это решение – не простое, а, как оказалось, золотое... Восстановить базу из бэкапа от прошедшей ночи. Затем, зная структуру таблиц базы данных, экспортировать соответствующие данные средствами СУБД из копии базы от предыдущей ночи. Я только слышал, что иногда делают что-то подобное с 1С-овскими базами. Конечно, этот вариант нелегитимный, но у меня не оставалось другого выбора. Скажу честно, все делал в первый раз.

 

Процедура восстановления.

Через пару часов я добрался до компа и интернета. OpenVPN рулит. За это время сисадмин развернул копии баз от прошедшей и предыдущей ночи. Пришлось срочно искать внешнюю обработку, которая предоставляет информацию о структуре базы данных. Таковая была найдена на жестком диске (скачивал ранее с источника - http://infostart.ru/public/16282/).

Обработка показала следующее. Данные по документу «авансовый отчет» хранятся в семи таблицах, в двух из них данных не было. Итого необходимо перенести информацию из пяти таблиц (отмечены цветом):

 

Метаданные Имя таблицы хранения Назначение
Имя таблицы
 Документ.АвансовыйОтчет  Document101  Основная
 Документ.АвансовыйОтчет
 Документ.АвансовыйОтчет  DocumentChngR1514  РегистрацияИзменений
 
Документ.АвансовыйОтчет.ТабличнаяЧасть.ВозвратнаяТара  Document101.VT1427  ТабличнаяЧасть
 Документ.АвансовыйОтчет.ВозвратнаяТара
Документ.АвансовыйОтчет.ТабличнаяЧасть.ВыданныеАвансы  Document101.VT1441  ТабличнаяЧасть
 Документ.АвансовыйОтчет.ВыданныеАвансы
 Документ.АвансовыйОтчет.ТабличнаяЧасть.ОплатаПоставщикам  Document101.VT1446  ТабличнаяЧасть
 Документ.АвансовыйОтчет.ОплатаПоставщикам
 Документ.АвансовыйОтчет.ТабличнаяЧасть.Прочее  Document101.VT1464  ТабличнаяЧасть
 Документ.АвансовыйОтчет.Прочее
 Документ.АвансовыйОтчет.ТабличнаяЧасть.Товары  Document101.VT1491  ТабличнаяЧасть
 Документ.АвансовыйОтчет.Товары

 

Запускаем SQL Management Studio. Команда INSERT в помощь. Т.к. на момент создания бэкапа данные были удалены частично, то пришлось предварительно удалить данные в таблицах-приемниках, чтобы при добавлении не было задвоений. Ура! Несколько тысяч документов с табличными частями «переехали» из базы-источника в базу приемник. «Простите, но где проводки?» - спросила бухгалтер. Мне казалось, что они останутся в базе после такого «жесткого» удаления документов. Возникшая ситуация напомнила мне вариант № 2.

Что там с проводками? Проводки хранятся в регистре бухгалтерии «Хозрасчетный». Структура оказалась следующая:

 

Метаданные Имя таблицы хранения Назначение
Имя таблицы
 РегистрБухгалтерии.Хозрасчетный  AccRg468  Основная
 РегистрБухгалтерии.Хозрасчетный
 РегистрБухгалтерии.Хозрасчетный  AccRgChngR505  РегистрацияИзменений
 
 РегистрБухгалтерии.Хозрасчетный  AccRgAT0481  ИтогиПоСчетам
 
 РегистрБухгалтерии.Хозрасчетный  AccRgAT1500  ИтогиПоСчетамССубконто1
 
 РегистрБухгалтерии.Хозрасчетный  AccRgAT2501  ИтогиПоСчетамССубконто2
 
 РегистрБухгалтерии.Хозрасчетный  AccRgAT3502  ИтогиПоСчетамССубконто3
 
 РегистрБухгалтерии.Хозрасчетный  AccRgCT503  ИтогиМеждуСчетами
 
 РегистрБухгалтерии.Хозрасчетный  AccRgED504  ЗначенияСубконто
 

 

В моем случае данные бухгалтерского регистра нельзя было так просто взять и переписать полностью из одной таблицы в другую, т.к. в нем хранится информация не только по документу «авансовый отчет», а также проводки за предыдущий день.

Пришлось использовать все туже команду INSERT, но с условием, что из базы-источника копируются записи только для документов, которые находятся в таблице документа «авансовый отчет» базы-приемника. Отбор по уникальному номеру не составил труда. Сначала были перенесены данные «основной» таблицы, затем таблицы со «значениями субконто». Переносить «итоги» я посчитал нецелесообразным.
«Документы и проводки есть, но отчетность все равно кривая» - сказала бухгалтер.
Время шло, позади полдня, все на нервах, просят выполнить вариант № 1.

«Кривая отчетность из-за того, что кривые итоги» - подумал я. Попросил подождать еще полчаса, чтобы пересчитать итоги. И...о чудо! Результаты всех устраивают. Осталось сделать превращение (бэкап-ресторе или детач-аттач, кому и что больше нравится) полученной базы в рабочую.

 

В качестве заключения.

На все ушло часа три. Это притом, что все делалось впервые и на свой страх и риск.
Чуть позже обнаружилось, что отсутствуют «авансовые отчеты» в «журнале операций», но изложенным выше способом данные были скопированы в рабочую базу. Структура журнала документа «журнал операций» следующая:

 

Метаданные Имя таблицы хранения Назначение
Имя таблицы
 ЖурналДокументов.ЖурналОпераций  DocumentJournal6336  Основная
 ЖурналДокументов.ЖурналОпераций

 

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

 

PS
Это моя первая публикация, поэтому не судите строго. Буду рад, если кому-нибудь пригодится изложенная идея. «Велосипед» - скажете? Ну, кому – как.
Если появятся вопросы по конкретике, то постараюсь дополнить в статье.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. А Р (p1l1gr1m) 27.10.12 02:29
Замечательный вариант, сам, скорее всего выбрал бы второй способ. Респект за смелость.
Однако должен заметить, что если использовать программный перенос, то нет необходимости что-либо перепроводить. Можно абсолютно так же, как и документы, перенести и движения регистров и это будет довольно быстро.
2. Олег Филиппов (comol) 29.10.12 09:01
1) Структура таблиц может отличаться. Названия приводить в тексте не нужно - нужно их получать для каждой базы индивидуально (ПолучитьСтруктуруХранения())
2) За день нет нужды этим пользоваться. УниверсальнаяВыгрузкаЗагрузкаДанныхXML воплне справится...
3. Евгений Кузнецов (kuzev) 29.10.12 09:32
Отвечаю по пунктам:
1) структуру таблиц я специально привел для описания конкретной ситуации, чтобы сделать понятней для читателя.
2) к сожалению, не имел опыта использования данной обработки для подобной задачи.
Собственно, твое видео годичной давности - http://infostart.ru/public/95672/, http://comol.livejournal.com/5062.html - направило меня на поиск пути решения =)
4. Алекс Ю (AlexO) 29.10.12 09:45
(3) kuzev,
2) За день нет нужды этим пользоваться. УниверсальнаяВыгрузкаЗагрузкаДанныхXML воплне справится...

совершенно верно, и даже более - этим совершенно нет нужды пользоваться.
Не посыпалась сейчас - посыпится потом.
"Результат всех устраивает". А потом, когда будут массовые лакуны в документах и пустые значения в регистрах -что скажете, 1с все удалила, ничего не знаю??
Крайне опасная публикация, считаю, если оставлять - то только с заголовком красным цветом "не повторяйте, это опасно!"
alon; comol; +2 Ответить 1
5. Олег Филиппов (comol) 29.10.12 10:28
(4) AlexO, Согласен. Нужна если потёрли где-то в начале года и потом всё перепровели.. если физически выгрузкой загрузкой XML не получится из за объема данных...
6. Ловыгин Антон (wunderland) 29.10.12 13:05
Молодец. Смелый решительный человек, с головой и руками. Но к замечаниям в обсуждении отнесись внимательно и серьезно.
7. Олег Филиппов (comol) 29.10.12 13:16
Сорри, поставлю "-", а то народ щас "+" ов наставит и все так делать начнут.. а это всё-таки эксклюзив... в 99% случаев эта задача не так решается :(
8. Евгений Кузнецов (kuzev) 29.10.12 13:23
(7) comol, ты противоречишь сам себе =) Ведь я воспользовался твоей идеей на практике применительно к своей ситуации.
9. Олег Филиппов (comol) 29.10.12 13:34
(8) kuzev, Ну я показывал на примере типового РС... и как раз с целью оптимизации скорости. В твоём случае и восстановление более сложное и вопрос скорости так остро не стоит. Просто восстановил копию и штатной обработкой перегрузил что нужно...
10. Евгений Кузнецов (kuzev) 29.10.12 13:46
(9) comol, я согласен дописать в конце статьи, что результат можно получить штатной обработкой. Только подтвердить это не могу.
Если обобщать, то тогда любой материал, размещенный здесь, "опасен", т.к. является плодом человеческих мыслей и труда. Человеческий фактор и все такое... Есть этот плод никто не заставляет. Каждый решает сам, пробовать его или нет.
Сейчас, спустя время, можно рассуждать о правильности того или иного варианта. В тот момент я выбрал путь и пошел по нему. Опять же, исходя из собственного опыта и имеющихся знаний.
11. Олег Филиппов (comol) 29.10.12 14:05
(10) kuzev, Я вот реально задумался чтобы свою публикацию снять... Не предполагал что она так может быть использована...
12. Олег Филиппов (comol) 29.10.12 14:07
(10) kuzev, "горе от ума" получилось. В вашем случае более простой способ был так же более правильным...
13. Михаил Кащенко (Visitizer) 29.10.12 14:08
Народ - вы усложняете себе жизнь
задача решается очень просто
1. поднимаем рядом бекап
2. переносим удаленный докмент в рабочую базу одним из известных вам способов:
1. обычным обменом данными - включая движения по регистру (самый простой)
2. ручками сериализуем все данные в одной базе и во второй поднимаем из хмл файла

в этом случае ничего перепроводить не надо, т.к. вы с документом поднимаете и движения по нему, и внутренний идентификатор документа остается такой-же как и был

p.s. - не забывайте делать бекапы логов - можно откатить базу на любой момент времени с точностью до секунды
32ops; absolutblohin; ansonat; Новенький_2209; comol; +5 Ответить 2
14. Евгений Кузнецов (kuzev) 29.10.12 14:10
(11) comol, это уже попахивает цензурой и запретом свободы мысли =)
15. Евгений Кузнецов (kuzev) 29.10.12 14:14
(13) Visitizer, спасибо. Чуть позже попробую этот вариант на тех же данных.
16. Игорь Хитров (Новенький_2209) 29.10.12 21:27
(12) comol, Олег! Было время, я часто заходил к вам в блог и читал много интересной и полезной информации. Планируете ли Вы возобновить постинг? ;)
17. Макас (makas) 30.10.12 09:37
А чем не подошел такой способ переноса данных http://infostart.ru/public/115115/
-----
Написанное в статье только для программистов со стажем, а подобные проблемы надо решать и главбухам. Поэтому я считаю такой способ = опасным. Для себя.
18. Евгений Кузнецов (kuzev) 30.10.12 09:43
19. Макас (makas) 30.10.12 11:31
(18) kuzev, всегда, пожалуйста :)
20. Анянов Михаил (insurgut) 31.10.12 09:01
Сума сойти - что за изобретение велосипеда?

Есть обработка ВыгрузкаЗагрузкаДанныхXML82.epf (поставляется с конвертацией данных или на диске ИТС) - неоднократно документооборот перетаскивал из "упавшей базы". Тысячи документов. И все красиво каждый раз.
21. Tatiana ANSONA (ansonat) 31.10.12 09:36
А вот у меня не всегда срабатывает эта обработка. Особенно, когда прошло длительное время от бэкапа и нужно перетащить не все данные, а с отбором.
22. Валерий Дубовой (Valerich) 31.10.12 11:10
(21) а там и отбор можно сделать
23. Vitaliy 1 (Valiko77) 31.10.12 11:13
Респект за решение, вполне пригодно. Главное пользоваться осторожно.
Только я вот не понял, как ты этот INSERT генерил в SQL ?
24. Tatiana ANSONA (ansonat) 31.10.12 11:47
(22) Valerich, не спорю, можно, но не всегда так как нужно. В любом случае, альтернативные варианты имеют право быть. Хотя, да - вышеописанный достаточно опасен. В любом случае, восстановление упашей базы всегда подводными камнями чревато. Обработка с движениями тоже может напортить.
25. Евгений Кузнецов (kuzev) 31.10.12 11:49
(23) Valiko77, как то так:

INSERT INTO [ACC_CORP_DESTINATION].[dbo].[_Document101]
([_IDRRef]
,[_Marked]
,[_Date_Time]
,[_NumberPrefix]
,[_Number]
,[_Posted]
,[_Fld1409RRef]
,[_Fld1410]
,[_Fld1411]
,[_Fld1412]
,[_Fld1413RRef]
,[_Fld1414RRef]
,[_Fld1415]
,[_Fld1416]
,[_Fld1417RRef]
,[_Fld1418]
,[_Fld1419RRef]
,[_Fld1420RRef]
,[_Fld1421]
,[_Fld1422]
,[_Fld1423]
,[_Fld1424]
,[_Fld1425]
,[_Fld1426RRef])
SELECT
[_IDRRef]
,[_Marked]
,[_Date_Time]
,[_NumberPrefix]
,[_Number]
,[_Posted]
,[_Fld1409RRef]
,[_Fld1410]
,[_Fld1411]
,[_Fld1412]
,[_Fld1413RRef]
,[_Fld1414RRef]
,[_Fld1415]
,[_Fld1416]
,[_Fld1417RRef]
,[_Fld1418]
,[_Fld1419RRef]
,[_Fld1420RRef]
,[_Fld1421]
,[_Fld1422]
,[_Fld1423]
,[_Fld1424]
,[_Fld1425]
,[_Fld1426RRef]
FROM [ACC_COPRP_SOURCE].[dbo].[_Document101]
26. Рамиль Хафизов (jump0) 31.10.12 15:15
Выгрузкой в идентичную было бы правильнее.
27. cratos2 (CratosX) 31.10.12 21:25
(13) Visitizer, был случай в одной организации, где делали ночные копии баз и ежечасный инкремент. Для возможности хранения данных из-за нехватки места на HDD приходилось стандартно оставлять недельные на 2 месяца, месячные на полгода и т.п.
В итоге потребовалось поднять базу годичной давности (для исправления ошибок учёта путём сравнения прежних ключевых значений, которые тогда не казались ключевыми) - и наверное вы догадались, что годичные бэки потёрлись.

P.S. Можно всё, вопрос цены
28. Alex Steiner (OrsoBear) 01.11.12 09:07
Смело! Сильно!
Что-то похожее тоже делал.
Но обычно разворачиваю копию в новой базе, а потом импортом для идентичных баз перекидываю необходимые документы и подчиненную информацию.
29. Анянов Михаил (insurgut) 07.11.12 20:45
(21) ansonat, потому что конфигурация изменилась? Так загружаем текущую конфигурацию на старый бэкап, обновляем и спокойно переносим данные.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа