В каких случаях эта статья может вам помочь:
- База поломалась не сильно (большая часть таблиц "Жива", и можно получать данные)
- Вы можете зайти в конфигуратор + запустить 1С в режиме отладки
Коротко что я сделал, для тех, кому некогда читать:
- Присоединить базу к MS SQL
- Проверить скриптом, или еще как ни будь, какие таблицы сломаны, много ли их
- Установить голую конфигурацию той же версии, что и ваша старая
- С помощью внешней обработки получить структуру базы 1с, и посмотреть, что поломалось в базе 1с.
- Создать новую базу в ms sql, и создать копии таблиц, поломанной базы, с переносом всех данных (из тех таблиц что выжили)
- В новой базе, вставить данные в поломанные таблицы, и голой базы
Теперь опишу полностью, что я делал. И дам все, что мне понадобилось в конце. (Статья будет большая)
Сразу говорю, статья сложная для понимания. Я 4 дня шел к этому рецепту. В голове я понимаю, что нужно делать. А расписать сложно!
Все изображения можно открыть в новой вкладке, в полном размере.
Предыстория: после вынужденного выключения виртуальной машины, на которой были базы 1с, Win10 умерла (перестала запускаться). У меня было 3 базы, из которых у двух, были бэкапы, у этой нет, по очень глупой причине (все временное становится постоянным). Никакие варианты восстановления не помогли. Я смог достать базу и виртуальной машины. Но она оказалась поломана и 1с не запускался. 4 дня упорной борьбы, привели меня к этому решению. В моём случае база восстановлена полностью. (я надеюсь).
Поехали. Я все делал на новой виртуалке, поэтому процесс будет с нуля.
1) Устанавливаем MS SQL (не ниже версии, которая была)
2) Устанавливаем сервер(платформу) 1с (Наверно тоже не ниже прошлой версии), я делал на более свежей.
3) Копируем файлы базы (.mdf .ldf) в папку ms sql (C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA)
4) Присоединяем битую базу в ms sql. Назовем её "old"
5) Создаем новую базу, назову ее "res", сюда будем восстанавливать базу.
6) Через администрирование серверов 1с, добавляем только базу old, а также создаем 1 новую (я назвал её clear - Тут будет чистая новая конфигурация). При добавлении базы old, я запретил 1с выполнять регламентные задачи, чтобы 1с не трогала эту базу.
В итоге получаем что-то подобное.
Возможно, что через какое-то время ваша старая база (old) может упасть в режим подозрительной (Suspect), для того, чтобы её достать из этого режима, выполним команды в ms sql (построчно)
EXEC sp_resetstatus 'old';
ALTER DATABASE old SET EMERGENCY
DBCC checkdb('old')
ALTER DATABASE old SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CheckDB ('old', REPAIR_ALLOW_DATA_LOSS)
ALTER DATABASE old SET MULTI_USER
Но я этого не делал. Так как, наверно, это может привезти к еще большей потере данных. Хотя кому-то это помогает полностью восстановить работоспособность 1с.
7) Теперь нам нужно понять масштаб бедствия, посмотреть, какие таблицы умерли. Для этого я написал небольшой скрипт на питоне (приложу к статье).
Скрипты написаны на питоне, для удобства конвертированы в .exe. Те, кто боится запускать непонятные файлы, насколько я знаю, антивирус тоже может ругаться на такой exe. Я приложил исходники скриптов в папке scripts\original_script. Вы можете их запустить самостоятельно, но потребуется установить python и библиотеку pymssql. Скрипт лежит в папке scripts\check_tables, запускать нужно файл check_tables.exe, НО сначала задайте данные для подключения к базе ms sql в файле scripts\check_tables\db_data.txt. Не меняйте структуру этого файла, а также не удаляйте кавычки. После запуска, скрипт получит список всех таблиц, и сделает запрос SELECT к каждой. Те таблицы которое выкинут ошибку, запишутся в список поломанных таблиц. На выходе у вас создастся файл tables, в папке скрипта, в нем вы увидите список битых таблиц ("error_tables"), а так же список всех таблиц в БД ("tables"), этот файл нам пригодится.
В моём случае сломались всего 3 таблицы (мне ооочень повезло). Теперь нужно понять следующий масштаб бедствия. Что это были за таблицы у 1с, и что в них должно лежать.
8) Сейчас нужно поставить чистую конфигурацию в базу clear. Обязательно той же версии что и была ваша конфигурация (я думаю вы это сделаете сами без меня).
9) Смотрим какие данные 1с у нас побились:
Запускаем старую побитую 1с. У меня в обычном режиме не запускалась, зато я смог это сделать в режиме отладки.
Запускаем 1с в режиме отладки, и будем получать структуру базы 1с. Если у вас не запустится 1с, то я не знаю, как действовать дальше. Так как нам нужно будет сопоставить таблицы, из поломанной базы, с таблицами из чистой конфигурации. Возможно, вы можете пропустить следующие шаги, и просто восстановить поломанные таблицы, оставив их пустыми, но как это повлияет на работу 1с, я не знаю. Для получения структуры, в папке 1s epf есть файл GetDatabaseStructure_v2.epf. Запускаем его в открывшимся окне 1с (файл -> открыть -> выбрать файл)
Здесь с помощью фильтра, или глазами. Находим названия битых, таблиц, которые мы получили с помощью скрипта. И смотрим какие данные у нас поломались.
В моем случае это: (запишите, это нам пригодится в следующем шаге)
Старые битые таблицы | данные 1с |
_InfoRg19196 | РегистрСведений.КэшПрограммныхИнтерфейсов |
_InfoRg19675 | РегистрСведений.НастройкиРасчетаЗарплатыРасширенный |
_RefSInf33550 | Справочник.УдалитьВидыОтправляемыхДокументов |
Из самого страшного на мой взгляд это "РегистрСведений.НастройкиРасчетаЗарплатыРасширенный". Я так понимаю тут лежат настройки расчета зарплаты. После восстановления, нужно будет сказать бухгалтеру что бы она проверила эти настройки.
10.1) Теперь нам нужно понять. Что в этих таблицах могло лежать. Можно ли их оставить пустыми. Или нужно вставить какие-то стандартные данные для нормальной работы. Тут нам и пригодится чистая конфигурация.
Запускаем чистую конфигурацию (я это делал так же в режиме отладки, мне так удобно. Хотя чистую базу можно запустить и полностью.) и в ней, так же запускаем этот файл(GetDatabaseStructure_v2.epf). Теперь мы ищем в каких таблицах лежат эти данные в новой конфигурации.
Проверив все наши битые данные в 1с, я получил следующее сопоставление
Старые битые таблицы (old) | данные 1с | новые таблицы (clear) |
_InfoRg19196 | РегистрСведений.КэшПрограммныхИнтерфейсов | _InfoRg30001 |
_InfoRg19675 | РегистрСведений.НастройкиРасчетаЗарплатыРасширенный | _InfoRg30524 |
_RefSInf33550 | Справочник.УдалитьВидыОтправляемыхДокументов | RefSInf26159 |
Теперь лезем в MS SQL, в новую базу clear, чтобы посмотреть, что лежит в живых таблицах, для чистой конфигурации. В двух таблицах, у новой конфигурации, пуcтые таблицы (нет данных), но в одной (_InfoRg30524) есть строка.
Это таблица с данными "РегистрСведений.НастройкиРасчетаЗарплатыРасширенный". Думаю, что тут лежат настройки для расчета зарплаты. К сожалению, старых данных у нас нету. Поэтому при восстановлении базы, будем использовать стандартные настройки из чистой базы. Так же мы видим, что у этой строки есть ссылки на какие-то данные в других таблицах (_Fld30621RRef, _Fld30625RRef). Нам нужно понять, на какие таблицы ссылаются эти колонки, а также, самое главное, проверить что ID в тех таблицах, совпадают между базами old и new. Так как если мы просто перенесем эту строку в восстановленную базу, но наша строка будет ссылается на несуществующий ID, 1с может поломается (тут я точно не знаю, мб 1с умная штука и сама сможет как то восстановить ссылочную целостность, но я не уверен)
10.2) Для того, чтобы проверить куда ссылается эта строка, мы опять открываем 1с (чистую конфигурацию), и лезем в структуру данных. Опять ищем нашу таблицу _InfoRg30524 и смотрим, на какие данные ссылаются эти колонки.
Получаем, куда ссылаются колонки
_Fld30621RRef -> ПорядокРасчетаСтоимостиЕдиницыВремени
_Fld30625RRef -> СпособУдержанияИзлишнеНачисленныхОтпускных
Теперь лезем в конфигуратор чистой базы и смотрим что это такое, и какие нам нужно искать таблицы.
Сначала найдем "РегистрСведений.НастройкиРасчетаЗарплатыРасширенный"
Далее смотрим, куда ссылаются наши данные, и получаем следующее сопоставление.
ПорядокРасчетаСтоимостиЕдиницыВремени
СпособУдержанияИзлишнеНачисленныхОтпускных
ПорядокРасчетаСтоимостиЕдиницыВремени -> ПеречислениеСсылка.ПорядокРасчетаСтоимостиЕдиницыВремениОплатыТруда
СпособУдержанияИзлишнеНачисленныхОтпускных -> ПеречислениеСсылка.СпособыУдержанияИзлишнеНачисленныхОтпускных
Возвращаемся в структуру данных и наконец находим на какие таблицы ссылаются наши колонки.
ПорядокРасчетаСтоимостиЕдиницыВремени -> ПеречислениеСсылка.ПорядокРасчетаСтоимостиЕдиницыВремениОплатыТруда -> Enum822
СпособУдержанияИзлишнеНачисленныхОтпускных -> ПеречислениеСсылка.СпособыУдержанияИзлишнеНачисленныхОтпускных -> Enum933
10.3) Лезем в ms sql. Открываем полученные таблицы в базе clear, и убеждаемся, что мы все поняли верно, и ссылки в таблице РегистрСведений.НастройкиРасчетаЗарплатыРасширенный/_InfoRg30524, ведут в полученные таблицы Enum822, Enum933
10.4) Надо убедиться, что в старой поломанной базе old, эти перечисления имеют тот же идентификатор, что и в чистой базе. Если это будет не так, нам придётся сопоставлять ID вручную.
Для этого, мы снова повторяем пункт 10.2 и 10.3, только уже для старой базы (old). Для того что бы найти таблицы с этими перечислениями и заглянуть в них. В итоге я получил следующие сопоставления
Чистая база (clear):
ПорядокРасчетаСтоимостиЕдиницыВремени -> ПеречислениеСсылка.ПорядокРасчетаСтоимостиЕдиницыВремениОплатыТруда -> Enum822
СпособУдержанияИзлишнеНачисленныхОтпускных -> ПеречислениеСсылка.СпособыУдержанияИзлишнеНачисленныхОтпускных -> Enum933
Битая база (old):
ПорядокРасчетаСтоимостиЕдиницыВремени -> ПеречислениеСсылка.ПорядокРасчетаСтоимостиЕдиницыВремениОплатыТруда -> Enum791
СпособУдержанияИзлишнеНачисленныхОтпускных -> ПеречислениеСсылка.СпособыУдержанияИзлишнеНачисленныхОтпускных -> Enum895
Теперь сопоставим данные таблиц
Чистая база (clear) | Старя база (old) |
Enum822 | Enum791 |
Enum933 | Enum895 |
Опять-таки, мне повезло. Спасибо 1С, в новой конфигурации, он создает перечисления с точно такими же ID. Пора переходить к восстановлению базы. Если бы это было не так, то мне бы пришлось сопоставлять ID ручками, и вставлять правильные значение, об этом дальше.
11.1) Для восстановления я написал второй скрипт, он копирует ТОЛЬКО живые таблицы, а также данные в них. Поломанные таблицы, будем копировать руками.
Скрипт лежит в папке scripts\copy_table, запускать нужно copy_table.exe. НО перед запуском заполните настройки подключения в файле scripts\copy_table\db_data.txt
Скрипт званого проверяет все таблицы, выбирает из них только целые, после чего копирует их командой SELECT * INTO FROM, в новую таблицу. Сейчас с помощью скрипта, мы копируем таблицы из сломанной базы (old) в новую пустую базу (res). Проверяем, что все удачно скопировано и идем дальше
11.2) Теперь нам осталось скопировать поломанные таблицы ручками, и при необходимости заполнить их данными.
Для копирования руками, заходим в ms sql в старую базу (old), кликаем правой кнопкой по поломанным таблицам -> создать скрипт -> используя CREATE -> новое окно
После получения скрипта, для создания таблицы, меняем базу old, на базу res, тем самым создавая новую таблицу в новой базе. В моем случае 3 раза.
Внимание! Мы скопировали базы без ключей и без индексов! После такого копирования запускать базу 1с НЕ НУЖНО. Так как 1с, без этих ограничений, начинает создавать кучу записей с одинаковым ID. После чего конфигуратор при экспорте начинает ругаться на это! Хотя это можно полечить отладчиком, но зачем нам лишние ошибки.
11.3) Теперь в моем случае осталось добавить одну строку в таблицу _InfoRg19675 (РегистрСведений.НастройкиРасчетаЗарплатыРасширенный), из чистой конфигурации (clear). Проверяю что строка вставилась, и на этом, моё восстановление закончено.
Для этого выполним команду:
12) Теперь мы подключаем базу res к серверу 1С. Нужно поставить галочку блокировка регламентных задач. Иначе 1с, своими фоновыми задачами, начинает что то делать в 1с, и так как у нас таблицы созданы без индексов, то ограничений никаких нет. И 1с создает в одной таблице кучу строчек с одинаковом ID.
Заходим в конфигуратор, и проверяем целостность базы 1с (Администрирование -> Тестирование и исправление). В моем случае ошибок не обнаружено, радуемся, и начинаем сразу делать бэкап конфигурации. НЕ ЗАПУСКАЯ 1С (Администрирование -> Выгрузка базы)
Вот теперь мы создаем в 1с сервере, чистую новую базу. Заходим в конфигуратор, загружаем нашу конфигурацию на сервер. И все! При загрузке конфигурации, 1С сам создаст новые таблицы, с правильными ключами, и индексами. Поэтому нам не пришлось их копировать! Проверяем и радуемся!
p.s.
В моем случае, восстановление оказалось достаточно простым. Хоть я и убил на это 4 дня, толком не спавши. В вашем случае могут поломаться таблицы, которые сильно взаимосвязаны с другими 1с. В этом случае придётся руками восстанавливать ссылочность, копятся в структуре конфигурации 1с (битой и чистой). Возможно даже долго. Но это реально я думаю. Ну а если у вас побились таблицы с важными данными, например сотрудниками, тогда я даже не знаю, что делать. Можно так же пробовать восстанавливать, создать в чистой конфигурации сотрудника, искать в конфигураторе, что на кого ссылается, и так далее. Как я и писал. В моём случае база оказалась слегка битой.
Есть еще один вариант восстановления. Через выгрузку и загрузку XML. Я его пробовал (вложу даже epf в папку с файлами), но это очень костыльный метод. Так как данные начинают задваиваться, и при проверке базы в конфигураторе, вылезает куча ошибок. Хотя конфигуратор их удачно лечит, но как это все скажется в будущем на базе я не знаю, поэтому и не стал его использовать. Там нужно знать, что именно копировать. Но на всякий случай скажу. Если решите попробовать. Я использовал импорт для 1с 8,2. Так как в дебаг режиме 8,3 не запускается. Так же скажу, что мне удавалось перенести данные. Но это очень кривой метод. Тем более опять-таки, битые таблицы перенести не удастся.
Надеюсь, эта статья никому не пригодится. Ну а если вдруг, то пробуйте.
Все файлы тут, yaDisk