В процессе эксплуатации систем на базе 1С:Комплексная автоматизация 2 или 1С:ERP пользователи могут столкнуться с аномальным разрастанием регистров накопления. Типичная ситуация: из-за ошибок в алгоритмах закрытия месяца или некорректного сторнирования документов в регистре (например, КУДИР) создаются десятки миллионов дублирующихся записей по одному и тому же регистратору. Попытки стандартного удаления таких данных через отмену проведения документа или программную очистку набора записей часто заканчиваются неудачей с ошибкой numeric field overflow или разрывом соединения с сервером. Разберем детально, как решить эту проблему, сохранив работоспособность базы данных.
Рассмотрим природу ошибки numeric field overflow. В СУБД (особенно часто это проявляется на PostgreSQL) для полей типа «число» задана определенная разрядность. В структуре таблиц 1С для регистров накопления существует служебное поле _LineNo (номер строки). Платформа накладывает ограничение на точность этого поля. Если количество строк по одному регистратору превышает 10 миллионов (10^7), СУБД блокирует любые операции с этим набором данных, так как внутренний счетчик строк выходит за пределы допустимого диапазона.
Кроме того, при попытке прочитать 34 миллиона записей в оперативную память через стандартный РегистрНакопленияНаборЗаписей, сервер 1С формирует огромный POST-запрос к СУБД, который может прерываться по таймауту или из-за нехватки ресурсов (ошибка /e1cib/logForm).
Если объем данных велик, но еще не достиг критического порога блокировки СУБД, первым делом стоит попробовать стандартный метод 1С с использованием свойства ОбменДанными.Загрузка. Это позволит пропустить часть проверок и ускорить процесс.
Проанализируем пример кода для очистки регистра по конкретному документу:
Процедура ОчиститьЗаписиРегистра(ДокументСсылка)
// Создаем набор записей регистра КУДИР
Набор = РегистрыНакопления.КнигаУчетаДоходовИРасходов.СоздатьНаборЗаписей();
// Устанавливаем фильтр по нашему проблемному документу
Набор.Отбор.Регистратор.Установить(ДокументСсылка);
// Включаем режим загрузки, чтобы обойти стандартные обработчики событий
Набор.ОбменДанными.Загрузка = Истина;
// Записываем пустой набор (это удалит все записи по регистратору)
Попытка
Набор.Записать();
Сообщить("Записи успешно удалены");
Исключение
Сообщить("Ошибка при удалении: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Важный нюанс: Если записей более 10 миллионов, метод Набор.Записать() все равно может выдать ошибку переполнения, так как платформа пытается вычислить итоги или проверить структуру таблицы перед транзакцией.
При удалении 34 миллионов записей система 1С будет пытаться пересчитать таблицы итогов для каждого удаляемого движения. Это создает колоссальную нагрузку на дисковую подсистему и процессор. Чтобы минимизировать влияние на СУБД, перед очисткой необходимо временно отключить использование итогов для целевого регистра.
РегистрыНакопления.КнигаУчетаДоходовИРасходов.УстановитьИспользованиеИтогов(Ложь);РегистрыНакопления.КнигаУчетаДоходовИРасходов.УстановитьИспользованиеИтогов(Истина); и запускаем полный пересчет итогов.Если платформа 1С отказывается работать с набором данных из-за ошибки numeric field overflow, нам придется обратиться напрямую к средствам СУБД. Рассмотрим этот процесс на примере PostgreSQL.
Проанализируем последовательность действий:
ПолучитьСтруктуруХраненияБазыДанных(). Имя таблицы будет выглядеть примерно как _AccumReg12345._RecorderRRef.
-- Будьте крайне осторожны! Сначала выполните SELECT для проверки
DELETE FROM _AccumReg12345
WHERE _RecorderRRef = '\x80e1005056915b2211eb668661706692';
Важно: После прямого удаления записей через SQL база данных 1С «не узнает» об изменениях в итогах. После завершения операции в SQL обязательно нужно зайти в 1С и выполнить «Тестирование и исправление» с галочкой «Пересчет итогов», иначе отчеты будут показывать неверные данные.
Если прямая работа с SQL затруднена, а документ содержит 90% всех записей регистра, можно рассмотреть метод «переливки» данных. Разберем этот алгоритм:
TRUNCATE TABLE _AccumReg12345;. Это мгновенно очистит всю таблицу регистра.Этот метод гарантированно решает проблему переполнения, так как полностью пересоздает структуру данных в таблице.
Выясним, почему такая ситуация стала возможной. В конфигурациях КА 2 и ERP подобные проблемы в регистре КУДИР часто возникают при использовании механизма сторнирования в закрытии месяца. Если регламентная операция завершается с ошибкой или прерывается, система может не удалить временные записи и при следующем запуске создать их повторно.
Рекомендуем применить следующие меры:
_AccumReg... — повод для проверки.Совместное применение программных методов 1С и инструментов СУБД позволяет эффективно очистить базу от «мусорных» миллионов записей и вернуть системе быстродействие.