Первым делом смотрим виновника в мониторе ресурсов:
Видим что им является один из процессов rphost с id 8484. (Remote Process HOST)
Далее, смотрим все сеансы этого рабочего процесса, где-то в последних столбцах таблицы ищем потребление диска:
Видим 6 сеансов на этом процессе:
Ага, вот и наш ненасытный сеанс, открытый фоновым заданием под пользователем Adm в 9:57. В колонке "Запись (Текущая)" значение достигло 138 гб! (пред. скрин). Кстати, с этого же времени висит ещё одно. Может они связаны.
Далее идем в консоль заданий и ищем что его породило:
Смотрим код первого:
К сожалению по заданному пути никакого скрипта не было.
И оно, даже не смотря на блок попытки, просто зависало с ошибкой:
Ок, не наш случай. Добавим проверку на существование файла и идём дальше. Код второго регламентного:
Здесь уже интересней. При достаточно большом размере выбираемых данных до второй точки останова выполнение никогда не дойдет.
Когда в запросе выбирается реквизит типа хранилище значений с бинарными данными (поле ФайлДанных) - тогда в результирующую выборку попадает весь размер всех файлов одновременно!
В нашем случае это вызывает ошибку нехватки места на диске:
При выполнении метода Выполнить() данные запроса могут сбрасываться на диск, и вот почему:
http://its.1c.ru/db/v8std#content:-2145782922:1
1. Не следует разрабатывать решения исходя из неограниченного объема оперативной памяти. Для многопользовательских систем любое неэффективное использование памяти может катастрофически сказаться на работоспособности.
Следует избегать формирования больших структур данных в памяти. Если объём данных, с которыми работает бизнес-логика, сам по себе ничем не ограничен, его нужно ограничивать искусственно, обрабатывая данные порциями и сохраняя результаты в базу или файлы.
2. При потенциально неограниченных выборках данных из ИБ следует получать данные из базы порциями фиксированного размера.
Например, неправильно:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
// Выгрузка всего справочника в таблицу значений
Номенклатура = Запрос.Выполнить().Выгрузить();
Для каждого ПозицияНоменклатуры Из Номенклатура Цикл
// Обработка элемента справочника
// ...
КонецЦикла;
поскольку весь результат запроса сразу помещается в память, в таблицу значений.
Также неправильно:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
РезультатЗапроса = Запрос.Выполнить();
// Обход результата запроса
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Обработка элемента выборки
// ...
КонецЦикла;
поскольку и в этом случае при выполнении запроса его результат будет сначала считан в память целиком (*).
* Примечание. Если размер результата запроса превосходит размер имеющейся памяти, то данные будут записаны на диск, а затем считаны оттуда в процессе вызовов Выборка.Следующий().
Правильно ограничивать результат запроса искусственно:
ВсеОбработано = Ложь;
Пока Истина Цикл
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1000
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| <условие выборки необработанных записей>";
РезультатЗапроса = Запрос.Выполнить();
ВсеОбработано = РезультатЗапроса.Пустой();
Если ВсеОбработано Тогда
Прервать;
КонецЕсли;
// Обход порции результата запроса
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Обработка элемента выборки
// ...
КонецЦикла;
КонецЦикла;
Также правильно:
Выборка = Справочники.Номенклатура.Выбрать(..., Отбор);
Пока Выборка.Следующий() Цикл
// Обработка элемента выборки
// ...
КонецЦикла;
поскольку в этом случае платформа 1С:Предприятие выполняет курсорный запрос.
Кроме того, число элементов выборки автоматически ограничивает платформа 1С:Предприятие в запросах динамических списков.
Таким образом, переписав код на получение значения хранилища через ключ записи, избавляемся от ошибки нехватки памяти:
Вывод: никогда не делайте неограниченную выборку полей типа ХранилищеЗначения, иначе забьёте память и диск!
upd: insurgut +
upd 24.06.22 : ещё одна причина потребления места в папке tmp
Анализ консоли кластера выявил равномерный рост Записи текущих данных
Завершение сеансов регзаданий в топе потребления ресурсов не помогало, рост продолжался, зависших регзаданий не было
Удалили все незанятые процессами файлы, что делать нельзя (отвалились макеты компонент, потребовался мягкий перезапуск)
После удаления увидели закономерность в создании файлов с одинаковым размером 2525 кб
Вручную начал сохранять по одному общие макеты на диск, был найден совпадающий по размерам
Виновником оказалась недавно включенная внешняя компонента КомпонентаПечатиШтрихкодовWindows64
При падении шло повторное её подключение без очистки, что и вызывало неконтролируемое дублирование файлов