SQL-версия обрезки базы 1С: TRUNCATE, шринк за 89 минут и ошибка 3140
Иван Недомолков · Жарияланды: · Жаңартылды:
Это техническое приложение к истории про 97,5 % - той, где база розничной сети похудела с 4 197 до 105 ГБ, а виновником оказался служебный кэш механизма разграничения доступа на 3,85 ТБ. В самой истории написано “сделали TRUNCATE, сжали файл, перестроили индексы”. Здесь - что за этими тремя глаголами стоит: какими запросами строилась карта объёмов, чем доказывалась “мёртвость” данных, почему TRUNCATE, а не DELETE, как выглядели тайминги ночного окна и на каких граблях мы там прыгали.
Отдельное объяснение, почему этот текст живёт только у нас. Профильные площадки для 1С-специалистов не публикуют материалы с операциями записи в СУБД мимо платформы - и это их право: массовому читателю такие приёмы приносят больше вреда, чем пользы. Мы с позицией согласны, поэтому в статьях на Инфостарте осталась только диагностическая часть, выполнимая штатными средствами. Полная версия - здесь, с дисклеймером на весь размер экрана.
Дисклеймер. Ниже - операции уровня СУБД на базе 1С. Официальная позиция вендора платформы такие вмешательства не поддерживает: любая проблема, возникшая после прямой записи в СУБД, - ваша и только ваша. Мы применяем их на объёмах, где штатные механизмы физически не укладываются в окно простоя, и только внутри контура: доказательство “мёртвости” данных из нескольких независимых источников, полные репетиции на копии прода, пред-чеки перед каждым необратимым шагом, побитовые сверки “до/после”, точки отката и приёмка на стороне заказчика. Не повторяйте на продуктиве без этого контура и без письменного согласия владельца системы. Имена таблиц в примерах условные, скрипты приведены как схема подхода, а не как готовый набор для копирования: у вашей базы будут другие таблицы, другие объёмы и другой диагноз.
Шаг 0. Карта объёмов: что вообще занимает место
Всё начинается не с удаления, а с таблицы “что сколько весит”. В базе 1С имена SQL-таблиц не говорят человеку ничего - _InfoRg31415 не подсказывает, регистр это сведений про ключи доступа или про курсы валют. Поэтому карта строится в два приёма: объёмы берутся из SQL, расшифровка имён - из платформы.
Объёмы:
-- Выполнять в базе 1С: USE [YourDb] или выбор базы в SSMS.
-- Оба представления видят только текущую базу, столбца database_id у них нет.
SELECT
t.name AS sql_table,
SUM(ps.reserved_page_count) * 8 / 1024 AS reserved_mb,
SUM(ps.used_page_count) * 8 / 1024 AS used_mb,
SUM(CASE WHEN ps.index_id IN (0, 1)
THEN ps.row_count ELSE 0 END) AS rows_cnt
FROM sys.dm_db_partition_stats AS ps
JOIN sys.tables AS t ON t.object_id = ps.object_id
GROUP BY t.name
ORDER BY reserved_mb DESC;
Расшифровка - на стороне 1С, штатным методом:
// Соответствие "SQL-таблица -> объект метаданных".
// Выгружаем в CSV и джойним с результатом запроса выше.
// Объект берём из колонки Метаданные: ИмяТаблицы у итогов
// и настроек итогов регистров пустое. У таблиц самой платформы
// (_SystemSettings и подобных) пусто и там, их узнают по Назначению.
Структура = ПолучитьСтруктуруХраненияБазыДанных(, Истина);
Для Каждого Строка Из Структура Цикл
Сообщить(Строка.ИмяТаблицыХранения + ";"
+ Строка.Метаданные + ";"
+ Строка.Назначение);
КонецЦикла;
Назначение здесь важнее, чем кажется: один объект метаданных живёт в СУБД как несколько физических таблиц. У регистра остатков ТоварыНаСкладах в УТ 11.5 их четыре: “Основная”, “Итоги”, “РегистрацияИзменений” и “НастройкиХраненияИтоговРегистраНакопления”. У оборотного ВыручкаИСебестоимостьПродаж таблиц 28: “Обороты” вместо итогов и два десятка служебных таблиц агрегатов. Регистр, который в конфигураторе выглядит скромно, в базе может занимать несколько строк карты - и весь его вес будет в таблице итогов или в таблице регистрации изменений для плана обмена, о которой никто не вспоминал с момента настройки обмена.
Если писать это самому не хочется, у нас есть обработка “Карта объёмов базы 1С”: она сопоставляет таблицы с объектами сразу по всей конфигурации, штатными методами платформы, без обращения к СУБД. Размеры она при этом только оценивает по метаданным, и такая оценка годится для списка кандидатов, а вес подтверждает запрос выше: на базе 3,4 ТБ ни одна из пяти самых тяжёлых таблиц не попала в первую пятёрку оценки. Дальше по тексту предполагается, что карта у вас на руках и в её топе стоит что-то, что вы не ожидали там увидеть. В нашем проекте это выглядело так: 3,34 ТБ истории версий шаблонов ограничений доступа и две очереди пересчёта ключей доступа на 1,18 и 1,19 млрд строк.
Обязательная оговорка про общий инстанс. Если на сервере живут десятки баз (а это норма), сначала убедитесь, в какой базе выполняется запрос. sys.dm_db_partition_stats и sys.tables из запроса выше видят только текущую базу, столбца database_id у них нет, и фильтровать там нечего: базу задаёт USE [YourDb] или выбор в SSMS. Представления уровня сервера устроены иначе. sys.dm_db_index_usage_stats из следующего шага хранит статистику всех баз сразу, и без условия database_id = DB_ID() к вашим таблицам примешаются чужие строки. Мы этот урок оплатили неделей анализа регистра, который в итоге оказался из соседней базы.
Шаг 1. Три независимых доказательства “мёртвости”
Самый опасный момент проекта - не TRUNCATE. Опасный момент - решение, что таблицу можно очистить. Ошибка здесь не откатывается извинениями, поэтому правило простое: одного признака недостаточно, нужны три независимых.
Доказательство первое: статистика использования индексов
SELECT
OBJECT_NAME(s.object_id) AS sql_table,
SUM(s.user_seeks + s.user_scans + s.user_lookups) AS reads,
SUM(s.user_updates) AS writes,
MAX(s.last_user_scan) AS last_scan,
MAX(s.last_user_update) AS last_update
FROM sys.dm_db_index_usage_stats AS s
WHERE s.database_id = DB_ID()
AND OBJECT_NAME(s.object_id) IN (N'_InfoRg31415', N'_InfoRg31416')
GROUP BY OBJECT_NAME(s.object_id);
И сразу - вопрос, который отличает доказательство от самообмана: с какого момента эти счётчики считают?
SELECT sqlserver_start_time FROM sys.dm_os_sys_info;
Счётчики обнуляются при перезапуске экземпляра. “Ноль чтений” на инстансе, поднятом три часа назад, не значит ничего - это статистика за три часа, а не за шесть лет. Нам повезло с аптаймом; когда не везёт, счётчики надо снимать в динамике неделями, складывая срезы в отдельную таблицу.
Доказательство второе: логика самого механизма
Статистика показывает, что таблицу не читают. Она не показывает, почему - и не гарантирует, что не прочитают завтра. В нашем случае объяснение нашлось на стороне конфигурации: регламентные задания пересчёта ключей доступа были выключены в 2020 году. Механизм продолжал ставить задания в очередь, но никто их не забирал. Записи копились, чтения не происходили - картина сошлась.
Тут же выяснилось и то, что переворачивает наивный план: формальный признак “RLS отключён” оказался ложью. 208 ролей реально использовали ограничения доступа по условию. Механизм был жив, просто его кэширующая часть превратилась в свалку. Поэтому чистке кэша предшествовал перевод базы с универсального ограничения доступа на классическое - иначе после очистки права начали бы вычисляться на лету и кассы легли бы окончательно. Про эту развилку - отдельная статья: универсальный RLS против классического.
Доказательство третье: сами данные
Последняя проверка - заглянуть внутрь. Даты в служебных таблицах, ссылки на существующие объекты, доля “живых” записей:
-- Пример: сколько записей ссылается на действующих пользователей
SELECT COUNT_BIG(*) FROM dbo._InfoRg31415 AS q
WHERE EXISTS (SELECT 1 FROM dbo._Reference1234 AS u
WHERE u._IDRRef = q._Fld31417RRef
AND u._Marked = 0x00);
Из миллиардов строк живых ключей доступа набралось 660. Именно этот запрос закрыл вопрос окончательно: удаляем не “вероятно ненужное”, а измеренное.
Дополнительный слой контроля, который стоит копейки: перед ночным окном таблицы-кандидаты переименовываются и живут под новым именем неделю (sp_rename на схеме без внешних ключей - операция мгновенная). Если через неделю никто не пришёл с ошибкой - гипотеза “мёртвости” подтверждена самым честным из возможных способов: продуктивом. У нас роль такого теста сыграли недели наблюдения после перехода на классический RLS.
Шаг 2. Почему TRUNCATE, а не DELETE
К ночи Х подготовка выглядела так: 2,37 млрд строк, которые доказанно никто не читает и не пишет, и окно длиной в одну ночь.
DELETE на этом объёме невозможен арифметически. Он построчный и полностью журналируемый: каждая удалённая строка - запись в журнале транзакций, обслуживание всех индексов таблицы, удержание блокировок. Журнал распухнет до размеров, сопоставимых с самой таблицей (терабайты), а индексы после массового удаления останутся фрагментированным решетом, которое всё равно придётся перестраивать. Порционный DELETE лечит распухание журнала, но растягивает работу на дни - окна такой длины у розницы нет.
TRUNCATE TABLE работает иначе: он не удаляет строки, а деаллоцирует экстенты целиком, журналируя только освобождение страниц. Отсюда и результат: 4 108 → 108 ГБ занятого места за секунды.
-- Пред-чек: убеждаемся, что смотрим на ту таблицу и на тот объём
SELECT COUNT_BIG(*) AS rows_before FROM dbo._InfoRg31415;
TRUNCATE TABLE dbo._InfoRg31415;
-- Пост-чек: пусто и место освобождено
SELECT COUNT_BIG(*) AS rows_after FROM dbo._InfoRg31415;
Что нужно знать про TRUNCATE до того, как его набирать:
- Он требует эксклюзивной блокировки схемы. В базе не должно быть ни одного сеанса, ни одного регламентного задания, ни одного обмена. “Почти никого” не считается: любой доживший до операции писатель либо заблокирует её, либо допишет данные в таблицу, которую вы через секунду опустошите.
- Ограничение по внешним ключам к базам 1С не применяется. Платформа не создаёт в СУБД внешних ключей - ссылочную целостность она обеспечивает своим кодом. Это удобно и одновременно означает, что СУБД вас не остановит, если таблица окажется живой. Единственный предохранитель - шаг 1.
- Структура таблицы сохраняется. Платформа после очистки видит пустой регистр, а не сломанный: для служебных регистров, которые механизм умеет наполнять заново, это штатное состояние.
- Он не про учётные данные.
TRUNCATEтаблицы документов или регистров бизнес-учёта - это не оптимизация, это авария. Служебный кэш допустимо очищать целиком именно потому, что он кэш.
Если очистить нужно часть большой таблицы, TRUNCATE не подходит, а DELETE всё так же плох. Там работает другой паттерн - перенос выживших строк в новую таблицу с подменой имён; мы разбирали его отдельно: table swap вместо DELETE.
Шаг 3. Журнал транзакций и модель восстановления
Перед массовыми операциями база переводилась в простую модель восстановления, после - обратно в полную:
ALTER DATABASE [YourDb] SET RECOVERY SIMPLE;
-- ... TRUNCATE, SHRINK, REBUILD ...
ALTER DATABASE [YourDb] SET RECOVERY FULL;
Это тот шаг, который любят пропускать в чек-листах из интернета, а он ломает больше всего судеб. Переключение в SIMPLE рвёт цепочку журналов: все ваши журнальные бэкапы после этого момента бесполезны для восстановления на точку времени, пока не снят новый полный бэкап. Поэтому порядок жёсткий: свежий полный бэкап до окна → работы → возврат в FULL → новый полный бэкап сразу же, не “утром”.
Второе следствие - про мониторинг. Пока база в SIMPLE, журнал усекается на чекпойнтах, и привычный алерт “журнал растёт” молчит. Не расслабляйтесь: перестроение индексов в следующем шаге всё равно нагенерирует журнала, а если у вас настроен SORT_IN_TEMPDB, то и журнала tempdb - на отдельно взятой ночи это превращается в ошибку 9002 и остановленное окно.
Шаг 4. Шринк: 3 ТБ за 89 минут одним проходом
После TRUNCATE файл базы всё ещё весил своё: внутри просто образовалось 3 ТБ пустоты. Вернуть место диску умеет только сжатие файла.
-- Целевой размер в мегабайтах, с запасом под ближайший рост
DBCC SHRINKFILE (N'YourDb_Data', 300000);
Здесь мы в итоге пошли против самого популярного совета - “сжимайте порциями, чтобы не держать долгую операцию”. Первую ночь шли по этому плану, порциями по 500 ГБ, и порции застревали на хвосте файла. На вторую ночь запустили одно сжатие сразу до целевого размера: одним проходом получилось 2 999,6 → 300 ГБ за 89 минут. Наша версия, почему проигрывали порции: каждая заново натыкалась на страницы, которые сервер ещё не успел разобрать после удаления. Подробно обе ночи разобраны в статье файл базы 1С не уменьшился после удаления данных.
Не утверждаем, что так будет на любом железе: утверждаем, что это надо мерить на своей базе на репетиции, а не принимать на веру из чек-листов в интернете, включая этот.
Что ещё стоит знать:
DBCC SHRINKFILEоднопоточен и двигает страницы с конца файла в начало. Отсюда две черты: время растёт нелинейно с объёмом переносимого, а индексы после операции оказываются перемешаны в клочья.WITH TRUNCATEONLYотдаёт только “хвост” файла за последним занятым экстентом, ничего не перемещая. Это мгновенно и безопасно - но помогает, только если свободное место удачно легло в конец. ПослеTRUNCATEкрупных таблиц так почти никогда не бывает.- Плановые бэкапы на время окна гасятся руками. Это не перестраховка: параллельно стартовавший бэкап уронил у нас сжатие с ошибкой 3140, а после прерванной попытки у базы остался “залипший” внутренний признак незавершённого сжатия - следующие операции вели себя странно, и вылечилось это только переводом базы
OFFLINE/ONLINE. Выключили задания - проверьте, что они действительно выключены, а не “выключены в интерфейсе”. - Запас места после сжатия - предмет разговора с заказчиком, а не ваш личный выбор. Мы оставили базе ~14 ГБ свободного пространства при естественном приросте ~0,6 ГБ в сутки, потому что место на дисках было нужно немедленно. Это осознанное решение, проговорённое вслух. Молча оставить продуктиву три недели запаса и уйти - верный способ получить аварийный звонок.
Шаг 5. Перестроение индексов и статистика
Перестроение после шринка - не “желательная гигиена”, а тот же пункт того же ночного плана с заранее замеренным таймингом. Список кандидатов генерируется запросом, который сразу выдаёт готовые команды:
SELECT
'ALTER INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(t.name)
+ ' REBUILD WITH (MAXDOP = 8, SORT_IN_TEMPDB = ON, ONLINE = OFF);' AS cmd,
ps.avg_fragmentation_in_percent AS frag,
ps.page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ps
JOIN sys.indexes AS i ON i.object_id = ps.object_id AND i.index_id = ps.index_id
JOIN sys.tables AS t ON t.object_id = ps.object_id
WHERE ps.avg_fragmentation_in_percent > 30
AND ps.page_count > 1000
AND i.index_id > 0
ORDER BY ps.page_count DESC;
Двести фрагментированных индексов перестроились за 44 минуты, 0 ошибок. Про параметры:
ONLINE = OFF- внутри окна простоя это быстрее и дешевле; онлайн-перестроение нужно, когда пользователи работают (и доступно не во всех редакциях SQL Server).SORT_IN_TEMPDB = ONускоряет сортировку, но переносит нагрузку в tempdb. Если tempdb маленькая или её журнал ограничен - вы познакомитесь с ошибкой 9002 в самый неудобный момент. Считайте место заранее.MAXDOPзадавайте явно. Мы в этом же проекте лечили заводскую настройкуMAXDOP = 0на 48-ядерном сервере, из-за которой в вечерний пик две трети запросов стояли в очереди за потоками, - тем более странно оставлять “ноль” в момент перестроения.
Дальше - статистика. REBUILD обновляет её для перестроенных индексов сам, но по остальным таблицам после массовых изменений она врёт, поэтому в план входит отдельный проход:
-- Недокументированная, но повсеместно используемая процедура;
-- в проде разумнее генерировать список команд явным запросом
EXEC sp_MSforeachtable 'UPDATE STATISTICS ? WITH FULLSCAN';
И финал ночи: возврат в FULL, полный бэкап (18,3 ГБ вместо прежних 556 - снялся за минуты), новая базовая линия для цепочки журналов.
Тайминги ночного окна
| Шаг | Время | Результат |
|---|---|---|
| Полный бэкап перед стартом | ~2 ч | 556 ГБ - последний раз в таком размере |
TRUNCATE мёртвого кэша (2,37 млрд строк) | секунды | занято 4 108 → 108 ГБ |
DBCC SHRINKFILE одним проходом | 89 мин | файл 2 999,6 → 300 ГБ |
| Перестроение 200 индексов | 44 мин | фрагментация обнулена, 0 ошибок |
Статистика, возврат в FULL, финальный бэкап | минуты | бэкап 18,3 ГБ |
Общий результат проекта: файл базы 4 197 → 105 ГБ, список чеков под кассиром 25 секунд → мгновенно (505 410 логических чтений → 4), бэкап 556 → 18,3 ГБ. Утром кассы открылись штатно, регресса нет.
Что делает всё это допустимым: контур проверок
Скрипты выше - самая простая часть работы. Дорогая часть - то, что вокруг них, и именно она отличает инженерную операцию от русской рулетки:
- Репетиции на копии прода с таймингами каждого шага. Не одна. Ночное окно должно быть исполнением известного плана, а не экспериментом; “точка невозврата” назначается по часам заранее, а не определяется на месте в три часа ночи.
- Пред-чеки перед каждым необратимым шагом. Счётчик строк, размер, отсутствие сеансов - автоматически, с остановкой всего процесса при расхождении. Не предупреждение в лог, а стоп.
- Матрица эквивалентности прав. Любое изменение механизма доступа сверяется таблицей “роль × сценарий × видимость” до и после. У нас в ней было 329 проверок, расхождений - 0. Самая скучная таблица проекта и единственная, которая стоит между вами и инцидентом безопасности.
- Сверка отчётов контрольной суммой, а не глазами. Выгрузка нормализуется и сравнивается по SHA-256 - как именно, разобрано отдельно.
- Точки отката на каждом уровне: свежий полный бэкап до окна,
_old-таблицы (там, где применяется swap) до конца окна, согласованное время отката. - Приёмка на стороне заказчика. Под ограниченными правами, по реальным сценариям. Приёмка глазами исполнителя - оксюморон: исполнитель смотрит туда, где ожидает увидеть успех.
Когда так делать нельзя
Честный раздел, без которого статья была бы вредной. Не применяйте описанное, если:
- Вы не доказали “мёртвость” данных тремя независимыми способами. Один признак - это гипотеза, а не основание для необратимой операции.
- Речь об учётных данных. Документы, движения регистров, справочники - только штатными средствами платформы, с её ссылочной целостностью и её же сверками.
- Нет копии прода для репетиций. Значит, вы планируете эксперимент на продуктиве.
- Нет возможности заморозить контур. Сеансы, регламентные задания, обмены, интеграции - всё должно быть выключено и проверено.
- Штатные механизмы укладываются в окно. На базе в 200 ГБ типовая свертка и типовые чистки отработают нормально - и это несравнимо более дешёвый и безопасный путь. Прямые операции в СУБД оправданы там, где платформа физически не успевает, и нигде больше.
- Нет письменного согласия владельца системы на работы такого класса с пониманием последствий для поддержки вендора.
Если хотя бы один пункт не выполняется - начните с карты объёмов и штатных методов: свертка, обрезка, тома или шринк - что выбрать.
Частые вопросы про шринк и уменьшение базы 1С
Вопросы, которые нам задают в комментариях и на аудитах чаще всего. Ответы короткие, но с цифрами.
Почему после удаления данных база 1С не уменьшилась?
Потому что удаление строк и уменьшение файла - две разные операции. DELETE (и штатная свертка, и чистка регистров средствами 1С) освобождает место внутри файла базы данных, но сам файл остаётся прежнего размера: СУБД держит его как есть, чтобы не платить за перераспределение при следующем росте. Место возвращает операционной системе только DBCC SHRINKFILE. Проверить, сколько внутри файла “воздуха”, можно так:
SELECT
name AS logical_name,
size * 8 / 1024 AS file_mb,
FILEPROPERTY(name, 'SpaceUsed') * 8 / 1024 AS used_mb,
(size - FILEPROPERTY(name, 'SpaceUsed')) * 8 / 1024 AS free_mb
FROM sys.database_files;
Если free_mb близок к нулю - шринк не даст ничего, сколько его ни запускай, и проблема не в файле, а в данных: нужна карта объёмов и диагноз. Дальше это уже свертка или обрезка базы, а не сжатие файла: место надо сначала освободить внутри, и только потом возвращать диску. Если free_mb большой, порядок подготовки ночи сжатия и запросы для наблюдения за ней собраны в разборе почему файл базы не уменьшился после удаления данных.
Сколько времени занимает шринк большой базы?
Нелинейно и зависит не от размера файла, а от объёма страниц, которые придётся переместить, и от дисковой подсистемы. Наш замер: 2 999,6 → 300 ГБ за 89 минут одним проходом на приличном хранилище. Ориентир для планирования - порядка часа на терабайт перемещаемых данных, но это именно ориентир: единственный честный способ узнать своё время - прогнать шринк на копии прода и засечь. Планировать ночное окно по чужим цифрам нельзя.
Опасен ли шринк? Почему его так ругают
Ругают заслуженно, но не за то, за что обычно думают. Сам по себе DBCC SHRINKFILE данные не портит. Его реальные издержки:
- Фрагментация индексов. Шринк перемещает страницы с конца файла, перемешивая их порядок. После него индексы фрагментированы почти полностью - то есть шринк без последующего
REBUILDменяет одну проблему на другую. - Долгая однопоточная операция. На терабайтах это часы, в течение которых база занята.
- Бессмысленность в регулярном режиме. Если базу шринкуют каждую неделю, а она каждую неделю снова растёт, вы просто оплачиваете фрагментацию и нагрузку на диск в обмен на ничто. Шринк - разовая операция после массового удаления, а не элемент регламентного обслуживания баз 1С, где место занимают бэкапы, индексы и статистика.
Отсюда правило: шринк допустим, когда внутри файла реально образовались освобождённые сотни гигабайт, и всегда идёт в паре с перестроением индексов в том же окне.
Можно ли выполнять TRUNCATE в базе 1С?
Технически - да: платформа не создаёт в СУБД внешних ключей, и команда отработает. Практически это допустимо в очень узком случае: таблица служебная (кэш, очередь, лог), её “мёртвость” доказана, контур заморожен, есть свежий бэкап и точка отката. Для таблиц учётных данных - документов, движений регистров, справочников - TRUNCATE неприменим: платформа не узнает об изменении, ссылочная целостность порвётся, а “внезапно” это всплывёт в отчётах через недели. И общая рамка: любая прямая запись в СУБД выводит происходящее за пределы поддержки вендора платформы.
Чем шринк отличается от свертки базы?
Свертка уменьшает учётные данные - переносит остатки на дату и убирает старую историю документов. Шринк не удаляет ни одной строки, он лишь возвращает диску уже свободное место. Это разные инструменты под разные диагнозы, и путать их дорого: свертка требует полной сверки остатков, шринк - только окна и последующего перестроения индексов. Развёрнутое сравнение всех четырёх методов (свертка, обрезка служебного, тома внешнего хранения, шринк) - в статье “Свертка, обрезка, тома или шринк: как выбрать”.
Как уменьшить журнал транзакций, а не файл данных?
Журнал сжимается тем же DBCC SHRINKFILE, но только после того, как его активная часть усечена: в полной модели восстановления - журнальным бэкапом, в простой - чекпойнтом. Если журнал не усекается, у него есть причина, и её показывает поле log_reuse_wait_desc:
SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE database_id = DB_ID();
LOG_BACKUP - журнал ждёт очередного журнального бэкапа, и если он при этом растёт, бэкапов нет или они идут слишком редко; ACTIVE_TRANSACTION - висит длинная транзакция; REPLICATION - не вычитаны изменения репликацией. Пока причина не устранена, сжимать журнал бесполезно: он вырастет снова к утру. Подробный разбор - в статье “Журнал транзакций 1С разросся”.
Нужно ли останавливать пользователей?
Для карты объёмов и диагностики - нет, эти запросы читающие и безопасны на работающей базе. Для TRUNCATE, шринка и перестроения индексов - да, контур замораживается полностью: сеансы, регламентные задания, обмены, интеграции и плановые бэкапы. Именно параллельно стартовавший бэкап уронил у нас сжатие с ошибкой 3140.
Итог
Технически вся ночь Х сводится к четырём командам: TRUNCATE, SHRINKFILE, ALTER INDEX REBUILD, BACKUP. Написать их - минута. Заслужить право их выполнить - два месяца диагностики, репетиций и сверок, в которых и состоит работа.
Поэтому если из этой статьи забирать одну мысль, пусть это будет не синтаксис TRUNCATE, а порядок действий: сначала карта объёмов, потом три доказательства, потом репетиция с таймингами, и только потом - команда, которая необратима. В обратном порядке те же самые четыре команды работают ровно так же быстро, только результат называется по-другому.
Краткая версия проекта с таблицей результатов - в кейсе “Обрезка базы 4,2 ТБ → 105 ГБ”, человеческая версия с сюжетом и отброшенными гипотезами - в статье-расследовании. А если ваша база доросла до объёмов, где типовое уже не укладывается в ночь, - мы делаем свертку и обрезку больших баз 1С как услугу: от карты объёмов до протокола сверки, с бесплатным экспресс-аудитом на входе.