При проведении процедуры тестирования и исправления (ТиИ) базы данных пользователи и администраторы часто сталкиваются с системными сообщениями вида: «Проверка таблицы InfoRg6853: удалено 3 записей» или «Проверка таблицы AccumRg7377: удалено 1 записей». Сама платформа 1С сообщает лишь внутренние физические имена таблиц СУБД, что сильно затрудняет понимание масштаба проблемы. Выясним причину появления таких сообщений, разберем по шагам, как расшифровать эти имена, оценим критичность потерь и подробно рассмотрим методы поиска удаленных записей с помощью резервной копии.
Платформа 1С:Предприятие работает как надстройка над реляционными базами данных (будь то файловая база 1Cv8.1CD или клиент-серверные MS SQL, PostgreSQL). Для оптимизации работы и абстрагирования от конкретной СУБД платформа автоматически транслирует объекты конфигурации в физические таблицы с уникальными идентификаторами. Например:
InfoRg обозначает таблицу регистра сведений (Information Register).AccumRg указывает на таблицу движений регистра накопления (Accumulation Register).AccumRgT указывает на таблицу итогов соответствующего регистра накопления.Числовой индекс в конце названия генерируется платформой динамически. Важно понимать, что при выгрузке информационной базы в файл .dt и её последующей загрузке в новую базу эти идентификаторы могут измениться. Поэтому искать жесткое соответствие в интернете бессмысленно — структуру нужно получать динамически для конкретной базы данных.
Для того чтобы сопоставить имена таблиц СУБД с реальными объектами метаданных, воспользуемся встроенной функцией платформы ПолучитьСтруктуруХраненияБазыДанных(). Этот метод доступен как в управляемом, так и в обычном приложении.
Рассмотрим подробнее, как написать простую обработку, которая выведет нам соответствие физических имен таблиц понятным объектам метаданных. Создадим внешнюю обработку и вставим в модуль следующую процедуру:
Процедура ОпределитьИменаТаблиц() Экспорт
// Получаем полную структуру хранения базы данных
ТаблицаСтруктуры = ПолучитьСтруктуруХраненияБазыДанных();
// Создадим отбор по интересующим нас именам таблиц СУБД
МассивИскомыхТаблиц = Новый Массив;
МассивИскомыхТаблиц.Добавить("InfoRg6853");
МассивИскомыхТаблиц.Добавить("AccumRg7377");
МассивИскомыхТаблиц.Добавить("AccumRgT7397");
МассивИскомыхТаблиц.Добавить("AccumRg7994");
Для Каждого СтрокаСтруктуры Из ТаблицаСтруктуры Цикл
ИндексИскомой = МассивИскомыхТаблиц.Найти(СтрокаСтруктуры.ИмяТаблицыХранения);
Если ИндексИскомой <> Неопределено Тогда
Сообщить("Таблица в БД: " + СтрокаСтруктуры.ИмяТаблицыХранения
+ " -> Объект конфигурации: " + СтрокаСтруктуры.ИмяТаблицы);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Запустив этот код, мы мгновенно получим расшифровку. В рассматриваемом примере из УТ 10.3 выяснилось следующее:
InfoRg6853 соответствует регистру сведений РегистрСведений.ОбъектыДоступаДокументов.AccumRg7377 и AccumRg7994 соответствуют регистрам накопления, хранящим фактические движения хозяйственных операций.AccumRgT7397 — это служебная таблица итогов регистра накопления AccumRg7377.Многие специалисты на форумах советуют «не париться» и просто продолжить работу после удаления записей. Разберем, почему такой подход может быть крайне опасным для бизнеса.
Регистр сведений «Объекты доступа документов» (InfoRg6853): Этот регистр отвечает за ограничение прав доступа на уровне записей (механизм RLS). Удаление строк из этой таблицы означает, что у некоторых пользователей мог пропасть доступ к документам, которые они должны видеть по работе, либо наоборот — открылся несанкционированный доступ к конфиденциальной информации. Оставлять это без внимания нельзя.
Регистры накопления (AccumRg7377 и AccumRg7994): Это таблицы движений. Физическое удаление записей отсюда означает потерю первичной информации о продажах, остатках товаров, взаиморасчетах или взаимозачетах. Совет «просто перепровести документы» в рабочей базе УТ 10.3 несет в себе колоссальные риски: перепроведение документов прошлых закрытых периодов гарантированно приведет к изменению себестоимости, искажению партионного учета и поплывшим финансовым результатам прошлых месяцев.
Таблица итогов (AccumRgT7397): Единственная таблица, удаление записей из которой действительно безопасно. Наличие символа «Т» в названии указывает на то, что это кэшированные итоги. Сами итоги легко восстанавливаются платформой по детальным записям движений. Для этого достаточно выполнить стандартный пересчет итогов через ТиИ.
Поскольку перед выполнением ТиИ у нас была сделана резервная копия (это обязательное золотое правило любого администратора), мы можем детально сопоставить исходное состояние данных и текущее исправленное. Рассмотрим четыре надежных метода сравнения.
Этот способ является самым простым и не требует навыков программирования. Он отлично подходит для небольших и средних регистров.
ОбъектыДоступаДокументов)..mxl (назовем его backup_data.mxl).repaired_data.mxl.Если в регистре содержатся сотни тысяч или миллионы строк, метод с выгрузкой в табличный документ MXL вызовет зависание системы. В таком случае оптимально использовать программное сравнение. Напишем внешнюю обработку, запускаемую в исправленной базе, которая по COM-соединению подключится к копии и найдет расхождения.
Проанализируем пример кода для сравнения регистра сведений:
Процедура ВыполнитьСравнениеРегистров() Экспорт
// Путь к файловой резервной копии базы данных
ПутьККопии = "File=""C:\Backup_Base"";Usr=""Администратор"";";
// Инициализируем COM-соединение
Попытка
COMConnector = Новый COMОбъект("V83.COMConnector");
БазаКопия = COMConnector.Connect(ПутьККопии);
Исключение
Сообщить("Ошибка подключения к резервной копии: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Шаг 1: Запрашиваем уникальные ключи записей из резервной копии базы
ЗапросКопия = БазаКопия.NewObject("Запрос");
ЗапросКопия.Текст =
"ВЫБРАТЬ
| ОбъектыДоступа.Документ КАК Документ,
| ОбъектыДоступа.ОбъектДоступа КАК ОбъектДоступа,
| ОбъектыДоступа.ОбластьДанных КАК ОбластьДанных
|ИЗ
| РегистрСведений.ОбъектыДоступаДокументов КАК ОбъектыДоступа";
РезультатКопии = ЗапросКопия.Perform().Unload();
КоличествоЗаписейКопии = РезультатКопии.Count();
// Шаг 2: Переносим выгруженную таблицу в структуру текущей базы
ТЗКопии = Новый ТаблицаЗначений;
ТЗКопии.Колонки.Добавить("Документ");
ТЗКопии.Колонки.Добавить("ОбъектДоступа");
ТЗКопии.Колонки.Добавить("ОбластьДанных");
Для Индекс = 0 По КоличествоЗаписейКопии - 1 Цикл
СтрокаCOM = РезультатКопии.Get(Индекс);
НоваяСтрока = ТЗКопии.Добавить();
// Преобразуем уникальные идентификаторы ссылок для корректного поиска
НоваяСтрока.Документ = ПолучитьСсылкуПоУИД(СтрокаCOM.Документ);
НоваяСтрока.ОбъектДоступа = ПолучитьСсылкуПоУИД(СтрокаCOM.ОбъектДоступа);
НоваяСтрока.ОбластьДанных = СтрокаCOM.ОбластьДанных;
КонецЦикла;
// Шаг 3: Используем запрос с левым соединением для поиска пропавших строк
ЗапросТекущий = Новый Запрос;
ЗапросТекущий.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
// Помещаем данные из копии во временную таблицу
ЗапросТекущий.Текст =
"ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Копия ИЗ &ТЗКопии КАК ТЗКопии";
ЗапросТекущий.УстановитьПараметр("ТЗКопии", ТЗКопии);
ЗапросТекущий.Выполнить();
// Находим строки, которых нет в текущей базе
ЗапросТекущий.Текст =
"ВЫБРАТЬ
| ВТ_Копия.Документ КАК Документ,
| ВТ_Копия.ОбъектДоступа КАК ОбъектДоступа,
| ВТ_Копия.ОбластьДанных КАК ОбластьДанных
|ИЗ
| ВТ_Копия КАК ВТ_Копия
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ОбъектыДоступаДокументов КАК ТекущийРегистр
| ПО ВТ_Копия.Документ = ТекущийРегистр.Документ
| И ВТ_Копия.ОбъектДоступа = ТекущийРегистр.ОбъектДоступа
|ГДЕ
| ТекущийРегистр.Документ ЕСТЬ NULL";
РезультатСравнения = ЗапросТекущий.Выполнить().Выгрузить();
Для Каждого СтрокаПропажи Из РезультатСравнения Цикл
Сообщить(СтрокаШаблон("Пропала запись: Документ %1, Объект доступа %2",
СтрокаПропажи.Документ, СтрокаПропажи.ОбъектДоступа));
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСсылкуПоУИД(COMСсылка)
// Вспомогательная функция для получения ссылки по строковому представлению UUID
УИДСтрока = СокрЛП(COMСсылка.UUID());
УИД = Новый УникальныйИдентификатор(УИДСтрока);
Возврат Документы.ЗаказПокупателя.ПолучитьСсылку(УИД); // Пример для конкретного типа метаданных
КонецФункции
Этот метод ориентирован на продвинутых пользователей и системных администраторов файловых баз данных. Поскольку база файловая, все таблицы физически упакованы в бинарный файл 1Cv8.1CD.
Tool_1CD._InfoRg6853).Если вы не хотите самостоятельно писать программный код или разбираться с консольными утилитами, можно применить готовые инструменты, разработанные сообществом 1С. На специализированных ресурсах опубликовано множество универсальных обработок для сравнения данных двух баз.
Обычно они работают по следующему алгоритму:
Таким образом, проведение тестирования и исправления требует серьезного и вдумчивого анализа каждого системного сообщения. Вооружившись встроенными функциями платформы и методами сравнения данных, мы всегда сможем точно определить, какая информация была удалена, и своевременно восстановить критически важные учетные данные.