Очистка базы данных 1С от данных по организациям прямыми SQL-запросами к СУБД



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

Преамбула:

Довелось мне как-то поддерживать БД 1С БП 2.0, в которой вели учет 100+(более СТА, КАРЛ!!!) организаций. Последующий перевод на 3.0 повлек за собой необходимость разделения этой БД на несколько. Разделение обуславливалось возможностью ведения учета ЗП в БП. В БП 2.0 система не ограничивала видимость объектов БД в зависимости от глобальной настройки ведения учета ЗП в БП, а тут — стала. Было принято решение о разделении БД.

База была клиент-серверной, на базе MS SQL.

Естественно, сразу было принято решение о том, что бы создать узел РИБ, и выгрузить в него данные по нужным организациям. Как оказалось, в данном случае появляются префиксы в номерах документов, чего категорически было делать нельзя + сам процесс формирования начального образа узла завершался ошибкой после 10-15 часов непонятных действий.

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

Пометил на удаление данные по не нужным организациям. Удаляемых объектов оказалось ~500к в одной базе и ~200к — в другой. Оставив процесс удаления на ночь, с утра я обнаружил, что прогресс не шибко продвинулся.

Не прерывая процесса удаление производилось в течении недели и скорость этого процесса была крайне низкая.

После примерно месяца мытарств с типовым удалением, которое так и не выполнилось до конца, мне пришлось создать данную обработку.

 

Амбула:

Обработка генерирует текст скрипта, соблюдая ссылочную целостность.

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

Другими словами:

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

 

С помощью сгенерированного скрипта весь процесс удаления длился 30-40 минут для каждой из баз.

Особенно актуально, если БД доступна в режиме 24/7.

 

Алгоритмы могут быть использованы более универсально, т.е. для удаления других объектов или в условиях других СУБД, но для этого придется доработать самостоятельно. 

Использование скрипта, естественно на свой страх и риск.

К версии платформы не чувствительна, т.е. должна и на 8.0 и на 8.3.16 работать одинаково.

 

P.S. я прекрасно знаю про лицензионные ограничения, но 1С не предоставляет никаких других типовых средств очистки БД сравнимой производительности.

 

UPD: Версия 1.4.0. Добавил возможность указывать максимальный уровень вложенности проверки ссылочной целостности. Внесены некоторые оптимизации в текст скрипта.

UPD: Версия 1.3.0 Добавлена возможность формирования скрипта для PostgreSQL. Исправлены ошибки сформированного скрипта версии 1.2.0.

UPD: Версия 1.2.0 Существенно переработан и оптимизирован алгоритм формирования скрипта. Добавлена возможность сохранять скрипт сразу в файл *.sql.

UPD: Версия 1.1.0 позволяет сохранять структуру метаданных и хранения данных в файлы и читать из файлов. Сделано для возможности отладки формирования скрипта в условиях, когда нет доступа к конфигурации.

37 Comments

  1. triviumfan

    Обработка генерирует текст скрипта, соблюдая ссылочную целостность.

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

    Другими словами:

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

    Скрипт учитывает, когда в регистре имеется запись со складом/договором удаляемой организации?:)

    Reply
  2. nomad_irk

    (1)Да, чистится все, включая таблицы оборотов и остатков регистров.

    Пересчет итогов после выполнить все же рекомендую, как и проверить на ссылочную/логическую целостность средствами конфигуратора 1С.

    Reply
  3. ogidni

    Классная обработка, может на пару дней скинете цену на одного шейкеля для бетатеста, я так сказать одним глазком гляну )

    Плюс поставил.

    Она только в Бух 2 работает? для бухи 2-ой не очень актуально, там можно через план обмена по организации обменяться — правда хвосты остаются.

    Reply
  4. nomad_irk

    Нет, работает для любой конфигурации вообще.

    Лично тестировал на БП3.0, ЗУП2.5, ERP2.5, УТ10.3, УПП 1.3.

    Даже в файловом варианте формирует скрипт, ессно применять его не к чему и негде 🙂

    Reply
  5. ogidni

    (4)

    ЗУП2.5, ERP2.5, УТ10.3, УПП 1.3.

    Круто, давай еще сделай восстановление последовательности в ERP на MSSQL

    Reply
  6. nomad_irk

    (5)это шибко круто в контексте изменения данных БД 1С прямыми запросами в СУБД 🙂

    Reply
  7. lunjio

    (5)

    новление последовательности в ERP на MSSQL

    На самом деле, когда база под > 200 ГБ, да что там 200, > 100-150 даже, другого выхода очистить быстро данные по определенным организациям не предоставляется возможным. Это трудно понять/осознать, пока не столкнешься. На этот случай обработку пришлось дорабатывать, которая покруче текущей.

    Reply
  8. nomad_irk

    (7)куда там еще может быть круче? 🙂

    Reply
  9. lunjio

    (8) Там далее нажимаешь удалить, он по отборам генерирует SQL скрипт на удаление, с учетом наложенных отборов, если галочка удалить движения документа, левым соединением соединяется по регистратору и удаляет из всех связаных регистров движения.

    Reply
  10. nomad_irk

    Дык моя обработка все тоже самое делает сразу, таблицы изменений/таблицы остатков и оборотов чистятся так же, т.е. выносится с базы вообще все, что связано с удаляемыми организациями.

    Ваша обработка гибче, согласен, но у меня не было задачи частично вынести данные по организациям в БД.

    Reply
  11. lunjio

    (10) Все верно, только эта для очень тонкой очистки используется, я могу выбирать какие документы обрабатывать, удалять не удалять из журнала и доп отборы, допустим удалять только отраженные в упр учете данные. При помощи этой обработки так же осуществляется сборка, разработчик ozaycev, я же ее сильно доработал под свои нужды исправив ошибки.

    Reply
  12. nomad_irk

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

    Reply
  13. lunjio

    (12) А тут можно и свернуть и удалить данные только по упр учета, оставив бух и вынести по организациям и много чего ) Как правило, часто требуется и свертка данных, наряду с удалением других организаций. Ни в коем случае не принижаю вашу разработку, но есть разработка которая охватывает более широкий спектр задач, т.к вы спросили куда круче. Вы молодец что выложили, я время не найду текущую сделать универсальной и под УФ и под ОФ и выложить, предварительно конечно с разрешения автора исходной, хотя она сильно перелопачена.

    Reply
  14. nomad_irk

    (13)да, согласен, погорячился я на счет «куда круче», я просто это в контексте только тотальной зачистки имел ввиду, если говорить в общем, то конечно же можно творить чудеса круче 🙂

    Reply
  15. DrZombi

    10 стар мани? да вы жмот с большой буквы…

    Reply
  16. Fox-trot
  17. nomad_irk

    (16) Да вы прям вообще свои знания и умения не цените 🙂

    Reply
  18. Fox-trot

    делай добро и бросай его в воду (с)

    Reply
  19. nomad_irk

    (18)Если все добро бросать в воду, можно и без штанов остаться…..

    Reply
  20. DoctorRoza

    (19) Делай добро и бросай его в воду. Оно не пропадет — добром к тебе вернется (Ух ты, говорящая рыба!)

    Reply
  21. nomad_irk

    (20) https://youtu.be/T_U7HxOzhWw слушаем припев 🙂

    Reply
  22. zubanovpavel

    Добрый день.

    Нетиповая УПП 125.1

    Ошибка после нажатия кнопки «Сформировать скрипт SQL»:

    {ВнешняяОбработка.ОчисткаОтДанныхОрганизации.МодульОбъекта(541)}: Метод объекта не обнаружен (НайтиСтроки)

    Массив = ТекСХД.НайтиСтроки(Отбор);

    Что дальше делать?

    Reply
  23. nomad_irk

    Платформа 1С какой версии?

    Предлагаю перевести общение в личные сообщения.

    Reply
  24. zubanovpavel

    Проверял на 8.3.12.1685.

    Reply
  25. nomad_irk

    (25)Ответил личным сообщением.

    Reply
  26. nomad_irk

    Результаты нагрузочного тестирования:

    БД ERP 2.4, доработанная, размер файла БД — 175ГБ на момент начала очистки.

    Удаление данных 1 организации из 7.

    Размер сгенерированного скрипта SQL — 48МБ, время выполнения — 2 часа 30 минут.

    Размер освобожденного пространства в файле БД — 63ГБ.

    Reply
  27. nomad_irk

    Обновил обработку. Скачавшим вышлю новую версию по запросу в личку с указанием e-mail.

    Reply
  28. vik80111

    1С:Предприятие 8.2 (8.2.19.130)

    Комплексная автоматизация, редакция 1.1 (1.1.4.1)

    Удаляю по Одной организации.

    Сразу выдает:

    Справочник.БанковскиеСчета. ЗАПИСЕЙ: 2

    Сообщение 207, уровень 16, состояние 1, строка 10

    Недопустимое имя столбца «Ref».

    Сообщение 137, уровень 15, состояние 1, строка 19

    Необходимо объявить скалярную переменную «@n».

    Сообщение 137, уровень 15, состояние 2, строка 20

    Необходимо объявить скалярную переменную «@n».

    Сообщение 137, уровень 15, состояние 1, строка 22

    Необходимо объявить скалярную переменную «@n».

    … и т.д.

    Сообщение 137, уровень 15, состояние 1, строка 124783

    Необходимо объявить скалярную переменную «@n».

    Сообщение 137, уровень 15, состояние 2, строка 124784

    Необходимо объявить скалярную переменную «@n».

    Сообщение 137, уровень 15, состояние 1, строка 124791

    Необходимо объявить скалярную переменную «@n».

    Сообщение 137, уровень 15, состояние 2, строка 124792

    Необходимо объявить скалярную переменную «@n».

    Файл скрипта прикрепил

    Reply
  29. nomad_irk

    (29) Обновил обработку. Если не сможете бесплатно обновиться, сообщите личным сообщением с указанием е-mail.

    Reply
  30. user1137549

    Конфигурация ЗУП 3.1.9. Ошибка при выполнении запроса:

    Справочник.ВидыДокументовВводДанныхДляРасчетаЗарплаты. ЗАПИСЕЙ: 4

    Msg 207, Level 16, State 1, Line 50

    Invalid column name ‘Ref’.

    Msg 137, Level 15, State 1, Line 2

    Must declare the scalar variable «@n».

    Msg 137, Level 15, State 2, Line 3

    Must declare the scalar variable «@n».

    Msg 137, Level 15, State 1, Line 5

    ………………………

    Прикрепил отрывок скрипта.

    Reply
  31. vik80111

    (30) Продолжим отладку…

    Сообщение 2714, уровень 16, состояние 1, строка 17

    В базе данных уже существует объект с именем «#tt3».

    Сообщение 2714, уровень 16, состояние 1, строка 30

    В базе данных уже существует объект с именем «#tt5».

    Сообщение 2714, уровень 16, состояние 1, строка 44

    В базе данных уже существует объект с именем «#tt5».

    и т.д.

    Сообщение 2714, уровень 16, состояние 1, строка 109548

    В базе данных уже существует объект с именем «#tt2».

    Сообщение 2714, уровень 16, состояние 1, строка 109555

    В базе данных уже существует объект с именем «#tt2».

    Сообщение 2714, уровень 16, состояние 1, строка 109562

    В базе данных уже существует объект с именем «#tt2».

    Reply
  32. nomad_irk

    Обновил до 1.4.0.

    Reply
  33. Andrewww_www

    Купили обработку, в ней есть проблема: количество «BEGIN TRANSACTION» больше, чем «COMMIT».

    Reply
  34. Andrewww_www

    Исправил ошибку, если надо — могу выслать обработку. Только как? Написать личное сообщение на этом сайте не могу

    Reply
  35. nomad_irk

    (35) можете указать место исправления, я исправлю и обновлю обработку.

    Reply
  36. Andrewww_www

    (36) в процедуре «ОбработатьЭлементыРекурсивно» после первого блока, начинающегося с «Если ЗначениеЗаполнено(ТекСХД_1) Тогда» не хватает:»

    Если ВывелиНачалоТранзакции И ЗначениеЗаполнено(ТекСХД_1) Тогда

    Текст.ЗаписатьСтроку(«COMMIT» + ?(ТипСУБД = 0, «», «;»));

    КонецЕсли;

    ВывелиНачалоТранзакции = Ложь;»

    И далее в блоке «Если НЕ ТекЗависимыйОбъект.ВидОбъекта = «РегистрСведений» Тогда» два раза встречается «Текст.ЗаписатьСтроку(«BEGIN TRANSACTION»);», после них надо добавить «ВывелиНачалоТранзакции = Истина;».

    Reply
  37. nomad_irk

    (37) Спасибо. В ближайшее время обновлю обработку.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *