При активной работе с мобильным приложением 1С на складских терминалах сбора данных (ТСД) под управлением Android разработчики часто сталкиваются с проблемой стремительного роста размера базы данных. Даже после программного удаления старых документов, неиспользуемых справочников и очистки регистров физический размер файла базы на устройстве может оставаться прежним. Это связано с архитектурными особенностями СУБД SQLite, которую использует мобильная платформа. В этой статье мы подробно разберем, почему так происходит, как правильно очищать данные программно и каким образом добиться физического уменьшения объема файла.
Разберем ситуацию: мы программно удалили тысячи записей, но файл 1Сdv.1cd (или внутренние файлы базы) не уменьшился ни на мегабайт. Проанализируем причину. Мобильная платформа 1С хранит данные в формате SQLite. В этой системе при удалении строк из таблиц место в файле не возвращается операционной системе немедленно. Вместо этого удаленные блоки данных помечаются как «свободные» и помещаются в так называемый freelist. При последующих операциях записи система сначала будет пытаться занять место из этого списка, и только если свободного места не хватит, файл начнет расти дальше.
Для того чтобы физически «сжать» файл и вернуть неиспользуемое место системе, необходимо выполнить операцию VACUUM. В контексте 1С эта процедура называется «Сжатие таблиц» и является частью процесса «Тестирования и исправления» (ТиИ).
Прежде чем приступать к сжатию, необходимо корректно удалить объекты. Простого удаления ссылок недостаточно — нужно обеспечить полное удаление объектов и связанных с ними записей в регистрах. Рассмотрим пример процедуры, которая перебирает метаданные и очищает базу:
Процедура ОчисткаБД() Экспорт
// Очистка документов
Для Каждого Об Из Метаданные.Документы Цикл
Выборка = Документы[Об.Имя].Выбрать();
Пока Выборка.Следующий() Цикл
Док = Выборка.Ссылка.ПолучитьОбъект();
Если Док = Неопределено Тогда
Продолжить;
КонецЕсли;
// Если документ проведен, сначала отменяем проведение
Если Док.Проведен Тогда
Док.Записать(РежимЗаписиДокумента.ОтменаПроведения);
КонецЕсли;
// Удаляем объект из базы
Док.Удалить();
КонецЦикла;
КонецЦикла;
// Очистка независимых регистров сведений
Для Каждого Рег Из Метаданные.РегистрыСведений Цикл
Если Рег.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый Тогда
Набор = РегистрыСведений[Рег.Имя].СоздатьНаборЗаписей();
// Запись пустого набора очищает данные в таблице
Набор.Записать(Истина);
КонецЕсли;
КонецЦикла;
// Очистка справочников
Для Каждого Об Из Метаданные.Справочники Цикл
Выборка = Справочники[Об.Имя].Выбрать();
Пока Выборка.Следующий() Цикл
Спр = Выборка.Ссылка.ПолучитьОбъект();
Если Спр = Неопределено Тогда
Продолжить;
КонецЕсли;
Спр.Удалить();
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Важный момент: При очистке регистров сведений крайне важно использовать метод Записать(Истина) для пустого набора записей. Это гарантирует полную очистку таблицы регистра на уровне базы данных. В случае с документами важно сначала отменять проведение (ОтменаПроведения), чтобы корректно очистились движения в регистрах накопления и других связанных таблицах.
После того как данные удалены программно, место в базе помечено как свободное, но файл всё еще занимает много памяти. Чтобы выполнить сжатие, необходимо запустить встроенную утилиту платформы. Выясним, как это сделать на мобильном устройстве.
В последних релизах мобильной платформы 1С функционал ТиИ стал доступен непосредственно на мобильном клиенте или в автономном приложении. Рассмотрим алгоритм действий:
Если у вас собранное приложение (APK), доступ к этому меню может быть скрыт. В таком случае можно попробовать зайти через список «Мои приложения» в мобильной платформе, если приложение было установлено как конфигурация для отладки. Если же приложение полностью автономно, разработчику стоит предусмотреть кнопку в интерфейсе, вызывающую системные настройки платформы, если это позволяет текущая версия сборщика.
Если у вас десятки или сотни ТСД, а пользователи обладают низкой квалификацией, ручной запуск ТиИ на каждом устройстве невозможен. Рассмотрим альтернативные стратегии автоматизации:
Метод «Полного сброса»:
В мобильном приложении реализуется механизм проверки флага «Необходима очистка». При получении такого флага с сервера приложение программно очищает все данные (как в коде выше), а затем завершает работу с параметром перезапуска: ЗавершитьРаботуСистемы(Истина). При следующем запуске приложение может выполнить первичную синхронизацию, загрузив только актуальные остатки. Однако это не решит проблему размера файла без ТиИ.
Метод переустановки базы:
Самый эффективный программный способ — это удаление файла базы данных и его повторное создание. Это можно реализовать через скрипт в ОС Android (если есть доступ к папке данных) или через полную переустановку приложения средствами MDM-систем (Mobile Device Management). При новой установке база создается с нуля и имеет минимально возможный размер.
Чтобы база не росла слишком быстро, проанализируем следующие рекомендации:
ЗаписьЖурналаРегистрации.Очистить(), чтобы удалять старые события.ХранилищеЗначения внутри базы данных. Это приводит к взрывному росту .1cd файла. Рекомендуется сохранять файлы в файловую систему Android через КопироватьФайл(), а в базе хранить только текстовый путь к файлу.Подведем итог: очистка данных в коде 1С — это только половина дела. Для физического освобождения места на диске ТСД обязательно требуется выполнение сжатия таблиц через меню администрирования. Сочетание регулярной программной очистки и периодического обслуживания базы позволит поддерживать стабильную работу мобильного приложения без необходимости очистки памяти всего устройства.