gifts2017

Восстановление работоспособности файловой базы. 2. Лечение

Опубликовал andrewks в раздел Администрирование - Тестирование и исправление

Восстановление работоспособности разрушенной файловой базы. Этап 2. Лечим базу.

Продолжение. Предыдущие этапы:

0. Введение

1. Обследование


Этап 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).

См. также

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

Комментарии

1. Dragon Ago (DragonAgo) 15.04.13 09:27
Полезная статья, еще для серверных баз, только там больше ошибок, и все скорее всего просто не описать будет
2. Александр (TrinitronHome) 15.04.13 20:06
спасибо за данную статью, очень полезная информация для меня
3. soba (soba) 16.04.13 16:20
Да, весьма подробно изложено. Спасибо, похоже пригодится совсем скоро.
4. Александр Ярошенко (teller) 17.04.13 09:53
(3) soba, похоже кого-то отговорил от резервного копирования и ТиИ ?
5. soba (soba) 17.04.13 13:50
Все проще. Бывают ситуации, когда ошибка в базе замечена спустя некоторое время, а данных уже навводили по самое небалуйся. Или еще пример. При переходе с БП2.0 на бухгалтерию строительной организации методом грубой силы загрузкой конфигурации без сравнения и объединения (спасибо заботливым разработчикам Импульса) кое-что нужно править :)
6. Евгений (wirg) 17.04.13 15:18
7. Денис Грачёв (denis1c@) 18.04.13 00:09
А можно ли вылечить файловую базу ЗУП, если утилита chdbfl.exe и ТиИ ни чего не находят, база запускается, работает нармально, но при групповом расчете НДФЛ база падает со словами "Недостаточно памяти"?
8. andrewks 18.04.13 08:06
(7) denis1c@, а почему Вы решили, что база содержит физические ошибки?
сколько сотрудников? какой релиз платформы и конфы?
9. Максим Полянский (yandextesting) 18.04.13 10:25
(7) недавно сталкивался с подобным вопросом, проблема оказалась в неверно заполненной дате документа по одному из сотрудников: вместо 2013 года был указан 0013 год н.э. :) В результате ЗУП пыталась выполнить какие-то расчеты за пару тысяч лет... Вероятность того, что это проблема БД крайне мала, на мой взгляд - копайте данные.
10. Sieg Heil (mdie) 18.04.13 12:56
(7) denis1c@, запустите под отладчиком в режиме замера производительности и найдете момент "распутывая" от места проблемы. К тому же недавно также пришлось такое лечить, когда период регистрации/начисления у НДФЛ указали лет на 200 больше.
А автору огромное спасибо за тулзу - реально помогла поднять базу с минимальными потерями.
11. Юленька (s_uu) 18.04.13 17:34
А каков физический предел размера файловой базы данных?
12. andrewks 18.04.13 17:40
(11) s_uu, теоретически его нет. есть ограничение на размер каждого из объектов таблицы (записи, блобы, индексы) - чуть менее 4 Гб. Самих таблиц может быть очень много.

естественно, что на практике не всё так хорошо, но и не всё зависит от размера. если с базой активно работают более 5-ти человек одновременно, уже можно задумываться о серверной архитектуре, но есть и базы, прекрасно работающие и с 10-ю активными пользователями. так что всё индивидуально
13. Денис Грачёв (denis1c@) 18.04.13 23:06
(9) Благодарю за наводку. Открыл регистр сведений "НДФЛ сведения о доходах" и увидел такую картину: Месяц налогового периода - февраль 0013 г. Оказывается в системе ввели документ начисление по б.л. этой датой.
Спасибо всем за помощь. Проблема решена.
14. Виталий Черненко (SeiOkami) 19.04.13 12:06
Круто было бы, если кто-нить сделает обработку для лечения базы всеми возможными способами =)
15. andrewks 19.04.13 13:11
(14) SeiOkami, в данном вопросе универсализм не то, чтобы невозможен, а, скорее, вреден.

на мой взгляд, правильный алгоритм именно такой - анализ и фиксация проблем, потом - написание/применение "лечебного" скрипта, исправляющего конкретные проблемы конкретной базы
16. Виталий Черненко (SeiOkami) 19.04.13 15:04
(15) andrewks, это, конечно, да. Однако, если сделать что-то вроде помощника диагностики проблем и по результатам задаваемых вопросов предлагать то или иное решение. Как в Windows... только рабочее =)
17. Алексей Карвацкий (AVK_Alex) 22.04.13 21:56
Было бы удобно различные инструменты собрать под один GUI, да еще и с парсером логов... ну... и для полноты еще гравицапу добавить :)
18. Александр Ширипов (shira84) 26.04.13 14:46
19. Сергей Зеленовский (zels) 15.04.14 23:44
Диск при чтении дает ошибки CRC в районе 8-10Мб от начала файла 1CD (БП2.0). Если там находится конфигурация поставщика, то можно ее взять из старого архива и перенести в копию 1CD (где сбойные блоки забиты нулями)?

Не стал разбираться - написал програмку, которая склеивает два 1CD-файла в один и все заработало.
Вот ссылка: Склеивание двух 1CD-файлов в один
20. andrewks 17.04.14 13:37
(19)
Если там находится конфигурация поставщика, то можно ее взять из старого архива и перенести в копию 1CD (где сбойные блоки забиты нулями)?


да, можно
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа