Предыстория такая: Позвонил бухгалтер, говорит, не могу поменять ФИО у ФизЛица. 1С пишет, мол "Критическая ошибка словаря...." дальше не помню.
Полез разбираться, и правда ошибка.
В Конфигураторе попытался сделать копию базы... 1С упала с ошибкой "ошибка субд error: <имя_таблицы> relation does not exist"
Сделал копию средствами PostgreSQL, запустил Тестирование и исправление
Оно тоже на середине упала с такой же ошибкой, конфигуратор закрылся
При попытки открыть конфигуратор ошибка:
"При обновлении данных после последней реструктуризации произошла критическая ошибка"...
Чуть погуглив, понял, что упала таблица с самой конфигурацией
Средствами SQL скопировал таблицу конфы и с точно такого же релиза, в упавшую базу, а именно:
copy config to 'D:/config_OK.txt' - из рабочей копии с таким же релизом
delete from config - в упавшей базе
copy config from 'D:/config_OK.txt' - в упавшей базе
В конфигуратор затем пустило, но при попытке открытия в Предприятий ошибка:
"Пользователь ИБ не идентифицирован"
Помогло вот это: (из просторов инета)
UPD ATE SchemaStorage SE T Status = 100
И в саму базу в итоге не заходит, ТИИ не делает, копию не делает.
Полез сравнить таблицы в SQL, а их кол-во в упавшей базе, СИЛЬНО МЕНЬШЕ, чем в рабочей копии.
см. скрины
Предложения восстановить из копии не реальны, т.к. ей более 2х месяцев. (((((
Базе конец, или есть какой-ньть скрипт, который может скопировать все таблицы из "копии" в "рабочую упавшую"...
Руками не реально, более 5000 таблиц куда-то делось. Надежда на то, что данные в этих таблицах это не документы и справочники. Бух плачут.
(5) pg_log на момент ТИИ при вылетевшей ошибке говорит вот это:
< 2021-09-21 18:38:44.092 MSK >LOG: database system was shut down at 2021-09-21 18:38:19 MSK
< 2021-09-21 18:38:44.093 MSK >FATAL: the database system is starting up
< 2021-09-21 18:38:44.102 MSK >LOG: database system is ready to accept connections
< 2021-09-21 18:38:44.134 MSK >FATAL: the database system is starting up
< 2021-09-21 18:40:56.827 MSK >ERROR: relation "_const15353" does not exist at character 26
< 2021-09-21 18:40:56.827 MSK >STATEMENT: SEL ECT
T1._Fld15354
FR OM _Const15353 T1 LIMIT 2
< 2021-09-21 18:40:56.827 MSK >WARNING: there is no transaction in progress
< 2021-09-21 18:41:23.735 MSK >ERROR: relation "_constchngr14800" does not exist at character 22
< 2021-09-21 18:41:23.735 MSK >STATEMENT: SEL ECT COUNT(*) FR OM _ConstChngR14800
WH ERE
(_NodeTRef NOT IN (select TabID fr om _tmpRCT))
< 2021-09-21 18:41:23.736 MSK >WARNING: there is no transaction in progress
(36)"В конфигуратор затем пустило, но при попытке открытия в Предприятий ошибка:
"Пользователь ИБ не идентифицирован"" - в конфигураторе открыть конфигурацию , снять конфигурацию с поддержки сохранить ( не обновляя ИБ ) , и загрузить эту же конфигурацию из файла ( заменив существующую) , Сохранить и обновить ИБ. Проверить
(38) Вы гляньте скриншоты... меня очень пугает разница в количестве таблиц в живой старой копии, но уже обновленной до релиза погибшей БД и кол-во таблиц в погибшей БД
В копии 7328 таблиц
В упавшей 2312 таблиц....
5000 таблиц разница, думаю это конец)
(8) Знаю, но я не написал выше, что изначально выгрузил базу средствами SQL, но в чистую беэкап загружаться тоже не хочет, ругается на индексы какие-то.
Спокойно начал искать причину, еще раз восстановил из копии
Ругается на то, что восстанавливается INDEX, а такой таблицы в базе нет
pg_restore: creating INDEX "public.byshowog"
pg_restore: [archiver (db)] Error from TOC entry 87716; 1259 913655 INDEX byshowog postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.v8usersog" does not exist
Command was: CRE ATE INDEX byshowog ON public.v8usersog USING btree (show);
Константы и перечисления у вас там походу померли. Может что-то (кто-то) грохнул "пустые" таблицы? Оптимайз какой-нить...
Что далеать?
Ну я бы при отсутствии бэкапа попробовал бы сначала понять, какие таблицы каким представлениям принадлежат: https://infostart.ru/public/796664/ Дальше я бы порпоблвал бы скопировать константы и перечисления - они меняются редко.
Дальше бы просто двигался по списку таблиц, отсутствующих в рабочей системе, и создавал бы их, при возможности загружал бы их из старого бэкапа (если это справочники древние) или просто бы игнорил (если они пустые или это регистры сведений с адресными классификаторами, например).
Ну и до победного...
Да, предварительно сохранил бы кластер куда-нить.
Вспоминается: админы делятся на тех, кто делает бэкап, и тех, кто его уже делает...
(2) Это всё ясно, но 5000 таблиц!!! Руками не реально сделать.
Как вариант подумываю о скрипте, который по сравнил бы все таблицы рухнувшей базы с древним бэкапом и создал не достающие, скопировав их из живой базы.
Но я совсем не спец в написании под SQL...
Если есть кто возьмётся написать такой скрипт, то заплачу за него)
У пользователей нет.
Админы там бузрукие... на вопрос почему нет копий... "А нам такую задачу не ставили"... вот как-то так.
Былого у меня осталась копия базы с крайнего обновления.
Диск с базой мог начать сыпаться потихоньку. Посмотреть на наличие ошибок, smartmontools или утилитой к диску.
Желательно сделать новый кластер PostgreSQL(initdb) на заведомо исправном диске, там загрузить в новую, пустую базу "копию средствами PostgreSQL" и потом проводить эксперименты.
Диск с базой мог начать сыпаться потихоньку. Посмотреть на наличие ошибок, smartmontools или утилитой к диску.
Желательно сделать новый кластер PostgreSQL(initdb) на заведомо исправном диске, там загрузить в новую, пустую базу "копию средствами PostgreSQL" и потом проводить эксперименты.
(25) Это я сам хз как произошло. Возможно был отключен ранее.... база передана в 2020г.
Да и журнал 1С думаю ничего бы нам не сказал, он же не пишет логи как SQL... а база окончательно упала после ТИИ.
1. Поставить Бухов перед фактом, что вот база, но в ней нет 2.5 месяцев...
2. Скрипт средствами SQL, который перетащит не достающие таблицы из копии в рабочую базу. Скрипт пока не ясно как такой написать. Как руками перетаскивать таблицы - это без проблем, но их там адское количество. НО В ЭТО РЕШЕНИЕ, ЧТО ОНО ВОССТАНОВИТ БАЗУ Я ВЕРЮ НЕ БОЛЕЕ ЧЕМ НА 10%
Чую они отключены админом кто Postgree ставил, т.к. на старом сервере была нехватка места, отключали некоторые логи на самом деле. Но вот видимо конфиг со старого сервера на новый перетащили(
В общем для себя нашёл вот такое вот решение, которое из упавшей базы перекидывает таблицы в копию базы, с надеждой, что в перенесенных таблицах будут "свежие данные".
Написал обработку, в которой указываются параметры "упавшей" базы и параметры "старой копии" (всё указывается в коде).
Обработка перебирает все таблицы из "упавшей" БД, выгружается их в csv (можно в txt) файла, имя файла=имя_таблицы.
Затем загружает выгруженные таблицы в рабочую копию базы, заменяя одноименные таблицы.
Вот такая вот простая логика.
Обработка во вложении.
Код вот (писалось на очень скорую руку, было не до красоты коды, но всё в целом там понятно):
Перем ConnectionT;
Перем ConnectionK;
Процедура ПолучитьСоединениеСУбитойБазой()
Сервер = "localhost";
Порт = "5432";
База = "BuhSever";
Source = "PostgreBuhTrash";
Пользователь = "postgres";
Пароль = "*****";
ConnectionT = Новый COMОбъект("ADODB.CONNECTION");
ConnectionT.Provider = "MSDASQL.1";
ConnectionT.ConnectionString = "Driver={PostgreSQL Unicode};data source="+Source+";Server="+Сервер+";Port=" +
Порт+";Database="+База+";Uid="+Пользователь+";Pwd="+Пароль+";STMT="+"utf8";
Попытка
Состояние("Подключение к базе PostgreSQL...");
ConnectionT.open();
Сообщить("База PostgreSQL Trash подключена");
Исключение
Сообщить("Не могу подключиться к базе PostgreSQL Trash");
КонецПопытки;
КонецПроцедуры
Процедура ПолучитьСоединениеСКопиейБазы()
Сервер = "localhost";
Порт = "5432";
База = "RestoreBuhSever";
Source = "PostgreBuhRes";
Пользователь = "postgres";
Пароль = "*****";
ConnectionK = Новый COMОбъект("ADODB.CONNECTION");
ConnectionK.Provider = "MSDASQL.1";
ConnectionK.ConnectionString = "Driver={PostgreSQL Unicode};data source="+Source+";Server="+Сервер+";Port=" +
Порт+";Database="+База+";Uid="+Пользователь+";Pwd="+Пароль+";STMT="+"utf8";
Попытка
Состояние("Подключение к базе PostgreSQL K...");
ConnectionK.open();
Сообщить("База PostgreSQL K подключена");
Исключение
Сообщить("Не могу подключиться к базе PostgreSQL K");
КонецПопытки;
КонецПроцедуры
Функция ПолучитьТекстЗапросаСпискаТаблиц()
ТекстЗапроса =
"Sel ect table_name
|from information_schema.tables
|where table_schema='public'";
Возврат ТекстЗапроса;
КонецФункции
Функция ПолучитьТаблицыБазы(База,Source)
Сервер = "localhost";
Порт = "5432";
//База = "BuhSever";
Пользователь = "postgres";
Пароль = "*****";
Connection = Новый COMОбъект("ADODB.CONNECTION");
Connection.Provider = "MSDASQL.1";
Connection.ConnectionString = "Driver={PostgreSQL Unicode};data source="+Source+";Server="+Сервер+";Port=" +
Порт+";Database="+База+";Uid="+Пользователь+";Pwd="+Пароль+";STMT="+"utf8";
Попытка
Состояние("Подключение к базе PostgreSQL...");
Connection.open();
Сообщить("База PostgreSQL подключена");
Исключение
Сообщить("Не могу подключиться к базе PostgreSQL ");
КонецПопытки;
НаборЗаписей = Новый ComObject("ADODB.RecordSet");
Команда = Новый COMОбъект("ADODB.Command");
Попытка
Команда.ActiveConnection = Connection;
Команда.CommandText = ПолучитьТекстЗапросаСпискаТаблиц();
НаборЗаписей = Команда.Execute();
Сообщить("Данные получены.");
Исключение
Сообщить("Нет данных.");
Возврат Новый ТаблицаЗначений;
КонецПопытки;
ТЗ = Новый ТаблицаЗначений;
//Добавление колонок во временную таблицу
Для НомерСтолбца = 0 По НаборЗаписей.Fields.Count - 1 Цикл
ИмяСтолбца = НаборЗаписей.Fields.Item(НомерСтолбца).Name;
ТЗ.Колонки.Добавить(ИмяСтолбца);
КонецЦикла;
Пока НЕ НаборЗаписей.EOF Цикл
// Заполнение временной таблицы таблицы
НоваяСтрока = ТЗ.Добавить();
Для НомерСтолбца = 0 По НаборЗаписей.Fields.Count-1 Цикл
НоваяСтрока.Установить(НомерСтолбца, СокрЛП(НаборЗаписей.Fields(НомерСтолбца).Value));
КонецЦикла;
НаборЗаписей.MoveNext();
КонецЦикла;
Возврат ТЗ;
КонецФункции
Функция СкопироватьТаблицуИзБазыВБазу(table_name)
ОбработкаПрерыванияПользователя();
Команда = Новый COMОбъект("ADODB.Command");
Попытка
Команда.ActiveConnection = ConnectionT;
Команда.CommandText = "Copy "+table_name+" to 'D:/tables/"+table_name+".csv'";
Команда.Execute();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Команда = Новый COMОбъект("ADODB.Command");
Попытка
Команда.ActiveConnection = ConnectionK;
Команда.CommandText = "delete from "+table_name;
Команда.Execute();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Команда = Новый COMОбъект("ADODB.Command");
Попытка
Команда.ActiveConnection = ConnectionK;
Команда.CommandText = "Copy "+table_name+" from 'D:/tables/"+table_name+".txt'";
Команда.Execute();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Состояние(table_name);
КонецФункции
Процедура КнопкаВыполнитьНажатие(Кнопка)
ПолучитьСоединениеСУбитойБазой();
ПолучитьСоединениеСКопиейБазы();
ТЗБитойБазы = ПолучитьТаблицыБазы("BuhSever","PostgreBuhTrash");
ТЗКопииБазы = ПолучитьТаблицыБазы("RestoreBuhSever","PostgreBuhRes");
Для Каждого СтрТЗБ из ТЗБитойБазы цикл
Для Каждого СтрТЗК из ТЗКопииБазы цикл
Если СтрТЗБ.table_name = СтрТЗК.table_name тогда
СкопироватьТаблицуИзБазыВБазу(СтрТЗБ.table_name);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Сообщить("ОК");
КонецПроцедуры
Показать
НО! Мне в итоге это не помогло, видимо оставшиеся таблицы тоже были порушены. База в итоге перестала открываться, просто повисает и всё. ТИИ не делает, тоже повисает. Реидексацию средствами PopstgreSQL не делает, ждал 2 часа.
Появилась обратная идея, т.е. выгрузить все таблицы из рабочей копии и загрузить в упавшую базу, то те, которых в ней не достаёт.
Но тут я столкнулся с тем, что не нашел рабочий способ как из папки с кучей файлов с "файлами-таблицами" создать таблицы в базе где их нет.
Выгрузку недостающих таблиц в файлы написал....
На загрузку нагуглил утилиту, которая якобы по указанному ей файлу создает таблицу в базе со структурой из указанного файла, но мне так и не удалось заставить её работать.
Написал скрипт *.bat, который перебирает все файлы в паке с таблицами и подсовывает утилитке, она всё отрабатывает, даже иногда задумывается на больших файлах, но таблицы не появляются в итоге в базе.
Утилита называется pgfutter
@Echo off
FOR %%a IN (d:\tables\*.csv) DO (
echo %%~nxa
pgfutter.exe --host "localhost" --port "5432" --db "BuhSever" --schema "public" --table %%~na --user "postgres" --pw "ПАРОЛЬ" csv %%~nxa)
В общем может кому-то это всё пригодится.
Всем спасибо и удачи)
P.S. Бухи начали восстанавливать базу по первичке(
Может стоит попробовать как-то разобраться с ошибкой по индексам и попробовать что-то сделать из этой копии ( ну при условии что она восстановиться)
Ругается на то, что восстанавливается INDEX, а такой таблицы в базе нет:
pg_restore: creating INDEX "public.byshowog"
pg_restore: [archiver (db)] Error from TOC entry 87716; 1259 913655 INDEX byshowog postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.v8usersog" does not exist
Command was: CRE ATE INDEX byshowog ON public.v8usersog USING btree (show);