Продолжение. Предыдущие этапы:
Этап 2. Лечим базу.
На данном этапе рассмотрим пути исправления различных ошибок в файловой БД при помощи скриптов, использующих возможности компоненты 1CDLib. (Под скриптом здесь понимается обработка 1С:Предприятие 8.2, загружающая указанную компоненту либо из макета, либо из файла на диске, и содержащая определённый код на встроенном языке 1С, с использованием функций компоненты. Пример такой обработки есть в публикации, посвящённой компоненте).
В общем виде, скрипт выглядит так:
FileDB=Новый(«AddIn.T1CDLib.DB1CD»);
FileDB.OpenLogFile(ИмяЛога);
Состояние(«Чтение структуры файла»);
FileDB.Open1CDFile(ИмяФайла);
Состояние(«Обработка файла»);
// здесь выполняем различные операции по лечению базы
FileDB.CloseFile();
FileDB.CloseLogFile();
Состояние(«»);
В зависимости от списка проблем, составленного на этапе обследования, можно выполнить различные операции:
- 1. Если в заголовке базы указан неверный размер, то исправляем заголовок:
FileDB.FixMainStreamHeader();
- 2. Если есть таблицы с некорректным размером одного или нескольких объектов (описание, записи, BLOB, индексы):
-
FileDB.FixTableHeaders(«TABNAME»,Истина,Истина,Истина,Истина);
В моей практике бывали случаи, что chdbfl.exe при некорректном размере объектов какой-то таблицы не мог восстановить добрую половину данных этой таблицы, а вот после исправления размеров «терял» буквально пару-тройку записей, и это безо всякого изменения содержимого объектов такой таблицы.
3. Если есть некорректные записи в корневом объекте RootEntry:
Вывести содержимое корневого объекта в лог-файл можно так:FileDB.PrintRootEntry();
Удалить некорректную запись по индексу (нумерация — с 1) из корневого объекта:
FileDB.DeleteTableFromRootEntry(ИндексЗаписи);
Если содержимое какой-то потерянной таблицы нашлось в недрах файла БД (например, при помощи поиска в Hex-редакторе), но ссылка на неё отсутствует в корневом объекте, можно её добавить:FileDB.AddTableToRootEntry(ИндексБлокаЗаголовкаОписанияТаблицы);
Внимание: после манипуляций с корневым объектом нужно переоткрыть БД:FileDB.CloseFile();
FileDB.Open1CDFile(ИмяФайла); - 4. Если в перечне таблиц базы есть таблицы с окончаниями «OG», это означает, что база рухнула в процессе реструктуризации или ТиИ. В данном случае может помочь такая операция (удаление окончания из имени таблиц):
ArrayPres=FileDB.GetTablesArray(Ложь);
TablesArray=РазвернутьЗначение(ArrayPres);Для TabInd=1 По TablesArray.Count() Цикл
TableInfo=TablesArray[TabInd—1];
TableName=TableInfo.Name;
Если ВРег(Прав(TableName,2))=«OG» Тогда
МасПереимТаб.Добавить(TableName);
КонецЕсли;КонецЦикла;
Состояние(«Переименование таблиц»);
Для каждого ТекТаб из МасПереимТаб Цикл
FileDB.RenameTable(ТекТаб,Лев(ТекТаб,СтрДлина(ТекТаб)-2));
КонецЦикла;
Однако, надо понимать, что содержимое таких таблиц может не соответствовать текущей конфигурации БД. В случае ТиИ вероятность несоответствия невысока, а вот при прерванном обновлении может быть по-разному, но, в любом случае, попробовать стоит. - 5. Если содержимое каких-то таблиц безвозвратно потеряно, но есть не очень старый бэкап, то можно восстановить данные этих таблиц по состоянию на дату бэкапа:
МасПереносТаб=Новый Массив;
МасПереносТаб.Добавить(«Reference19»);
МасПереносТаб.Добавить(«Document192»);ПапкаБазы=«ПутьКПроблемнойБазе»;
ПапкаБазыПред=«ПутьКБазеИзБэкапа»;
ИмяФайла=ПапкаБазы+«1Cv8.1CD»;
ИмяФайлаПред=ПапкаБазыПред+«1Cv8.1CD»;FileDB=Новый(«AddIn.T1CDLib.DB1CD»);
Состояние(«Чтение структуры файла»);
FileDB.Open1CDFile(ИмяФайла);FileDB2=Новый(«AddIn.T1CDLib.DB1CD2»);
FileDB2.Open1CDFile(ИмяФайлаПред);Состояние(«Перенос таблиц»);
Для каждого ТекТаб из МасПереносТаб Цикл
TableName=ТекТаб;
ПапкаТаб=ПапкаБазыПред+TableName+«»;
ВремКат=Новый Файл(ПапкаТаб);
Если (НЕ ВремКат.Существует()) Тогда
СоздатьКаталог(ПапкаТаб);
КонецЕсли;FileNameDescription=ПапкаТаб+«Description»;
FileNameRecords=ПапкаТаб+«Records»;
FileNameBLOB=ПапкаТаб+«BLOB»;
FileNameIndexes=ПапкаТаб+«Indexes»;FileDB2.SaveTableDataToFile(TableName,FileNameDescription,FileNameRecords,FileNameBLOB,FileNameIndexes);
FileDB.LoadTableDataFromFile(TableName,FileNameDescription,FileNameRecords,FileNameBLOB,FileNameIndexes);
КонецЦикла;FileDB.CloseFile();
FileDB2.CloseFile();
- Естественно, ссылки на элементы этих таблиц, созданные после бэкапа, будут «битыми», однако это всё же лучше, чем ничего.
Нумерация пунктов соответствует рекомендуемому порядку операций: т.е., сначала нужно исправить заголовки базы и таблиц, затем «разобраться» с корневым объектом, а затем уже приступать к манипуляциям с таблицами.
Также нужно помнить, что после всех проделанных манипуляций очеь полезно «шлифануть» базу утилитой chdbfl.exe с установленной галкой «Исправлять обнаруженные ошибки». Эта процедура перепакует данные всех таблиц, избавив их от мусора и удалённых записей, а также полностью перестроит индексы (а из-за «протухших» индексов база может по-прежнему не запускаться ни в одном из режимов, хотя сами данные могут быть уже восстановлены полностью).
В следующей статье будут рассмотрены различные ситуации при наличии проблем в конфигурации (таблицах CONFIG и CONFIGSAVE).
Полезная статья, еще для серверных баз, только там больше ошибок, и все скорее всего просто не описать будет
спасибо за данную статью, очень полезная информация для меня
Да, весьма подробно изложено. Спасибо, похоже пригодится совсем скоро.
(3) soba, похоже кого-то отговорил от резервного копирования и ТиИ ?
Все проще. Бывают ситуации, когда ошибка в базе замечена спустя некоторое время, а данных уже навводили по самое небалуйся. Или еще пример. При переходе с БП2.0 на бухгалтерию строительной организации методом грубой силы загрузкой конфигурации без сравнения и объединения (спасибо заботливым разработчикам Импульса) кое-что нужно править 🙂
Интересно
А можно ли вылечить файловую базу ЗУП, если утилита chdbfl.exe и ТиИ ни чего не находят, база запускается, работает нармально, но при групповом расчете НДФЛ база падает со словами «Недостаточно памяти»?
(7) denis1c@, а почему Вы решили, что база содержит физические ошибки?
сколько сотрудников? какой релиз платформы и конфы?
(7) недавно сталкивался с подобным вопросом, проблема оказалась в неверно заполненной дате документа по одному из сотрудников: вместо 2013 года был указан 0013 год н.э. 🙂 В результате ЗУП пыталась выполнить какие-то расчеты за пару тысяч лет… Вероятность того, что это проблема БД крайне мала, на мой взгляд — копайте данные.
(7) denis1c@, запустите под отладчиком в режиме замера производительности и найдете момент «распутывая» от места проблемы. К тому же недавно также пришлось такое лечить, когда период регистрации/начисления у НДФЛ указали лет на 200 больше.
А автору огромное спасибо за тулзу — реально помогла поднять базу с минимальными потерями.
А каков физический предел размера файловой базы данных?
(11) s_uu, теоретически его нет. есть ограничение на размер каждого из объектов таблицы (записи, блобы, индексы) — чуть менее 4 Гб. Самих таблиц может быть очень много.
естественно, что на практике не всё так хорошо, но и не всё зависит от размера. если с базой активно работают более 5-ти человек одновременно, уже можно задумываться о серверной архитектуре, но есть и базы, прекрасно работающие и с 10-ю активными пользователями. так что всё индивидуально
(9) Благодарю за наводку. Открыл регистр сведений «НДФЛ сведения о доходах» и увидел такую картину: Месяц налогового периода — февраль 0013 г. Оказывается в системе ввели документ начисление по б.л. этой датой.
Спасибо всем за помощь. Проблема решена.
Круто было бы, если кто-нить сделает обработку для лечения базы всеми возможными способами =)
(14) SeiOkami, в данном вопросе универсализм не то, чтобы невозможен, а, скорее, вреден.
на мой взгляд, правильный алгоритм именно такой — анализ и фиксация проблем, потом — написание/применение «лечебного» скрипта, исправляющего конкретные проблемы конкретной базы
(15) это, конечно, да. Однако, если сделать что-то вроде помощника диагностики проблем и по результатам задаваемых вопросов предлагать то или иное решение. Как в Windows… только рабочее =)
Было бы удобно различные инструменты собрать под один GUI, да еще и с парсером логов… ну… и для полноты еще гравицапу добавить 🙂
полезно
Диск при чтении дает ошибки CRC в районе 8-10Мб от начала файла 1CD (БП2.0). Если там находится конфигурация поставщика, то можно ее взять из старого архива и перенести в копию 1CD (где сбойные блоки забиты нулями)?
Не стал разбираться — написал програмку, которая склеивает два 1CD-файла в один и все заработало.
Склеивание двух 1CD-файлов в один
Вот ссылка:
(19)
да, можно
подскажите как удобнее искать частичные данные таблицы что бы восстановить, так как саму таблицу не находит ни какая программа, и как понять есть ли правильная запись по ней в парамс или сама таблица повреждена, если повреждено описание то как посмотреть целые ли данные?
(12) Под rdp в файловой базе может работать до 30 чел и больше. хотя конечно от 30 лучше даже в этом режиме переходить на 1с-сервер. В сети по share база и на 2-3х пользователях виснет и ломается бывает. 4-5 уже много 🙂
скрипт не может переименовать таблицы ошибка компоненты на методе ренэйм, что не так?переименовывает с og на не og
подскажите как вытащить данные таблицы в hex, программно не выходит, таблица с og на конце
ну все равно спасибо за скрипт, хоть смог его запустить и что-то сделать
как получить число подскажите ИндексБлокаЗаголовкаОписанияТаблицы
База вылетает с ошибкой «не обнаружена таблица «_ACCUMRGT17934». Развернул архив, там эта таблица есть. подскажите можно ли ее отдельно перенести в поврежденную базу? как это сделать?
База вылетает без сообщений на выполнении команды
FileDB.OpenTable(0,»CONFIGSAVE»);
в предлагаемом Вами коде:
FileDB=Новый(«AddIn.T1CDLib.DB1CD»);
Состояние(«Чтение структуры файла»);
FileDB.Open1CDFile(ИмяФайла);
FileDB.OpenTable(0,»CONFIGSAVE»);
релиз платформы 8.3.11.2867, база была создана на релизе 8.3.11.2899.
Помогите, пожалуйста, очень нужно срочно восстановить базу данных, которая пострадала при незначительном изменении конфигурации, но доступ к бэкапам оказался потерян.