Прямой ответ
Срок хранения — период, по истечении которого данные должны быть удалены или обезличены. Он задаётся политикой по типу данных, а реализуется автоматикой: удаление вручную не выполняется никогда и не проверяется.
Принцип ограничения хранения прямо сформулирован в GDPR: персональные данные хранятся в форме, позволяющей идентификацию, не дольше, чем это необходимо для целей обработки. Отсутствие срока — нарушение, даже если данные никому не мешают.
Классификация по типам данных — основа политики:
| Тип данных | Типичный срок | Основание |
|---|---|---|
| Логи доступа | 30–90 дней | Безопасность и расследование |
| Метрики высокой детализации | 7–15 дней | Стоимость хранения |
| Транзакционные записи | 5 лет | Бухгалтерские требования |
| Персональные данные | До цели обработки | GDPR, 152-ФЗ |
| Черновики и корзины | 30 дней | Отсутствие ценности |
Для больших таблиц удаление через DELETE неэффективно: операция пишет WAL, удерживает блокировки и оставляет мёртвые строки, требующие очистки. Партиционирование по времени решает задачу отбрасыванием раздела:
CREATE TABLE metrics (
ts timestamptz NOT NULL,
name text NOT NULL,
value double precision
) PARTITION BY RANGE (ts);
CREATE TABLE metrics_2026_10 PARTITION OF metrics
FOR VALUES FROM ('2026-10-01') TO ('2026-11-01');
-- удаление за месяц — мгновенная операция
DROP TABLE metrics_2026_10;
Отбрасывание раздела не порождает мёртвых строк и выполняется за миллисекунды; о настройке — в статье про партиционирование.
Для таблиц без партиционирования удаление выполняется пакетами, чтобы не создавать длительную транзакцию:
DELETE FROM sessions
WHERE id IN (
SELECT id FROM sessions
WHERE created_at < now() - interval '30 days'
LIMIT 5000
);
Что мешает внедрить сроки хранения
На практике политику хранения блокируют не технические сложности, а четыре типичных препятствия.
Отсутствие владельца данных. Если никто не отвечает за конкретный набор данных, срок не назначается, а данные продолжают накапливаться. Реестр данных должен содержать имя ответственного, а не только название таблицы.
Страх удалить нужное. Опасение, что удалённое когда-нибудь понадобится, приводит к бессрочному хранению. Проверка обращения к старым данным за последние годы обычно показывает, что к данным старше года обращений не было.
Зависимости между наборами. Удаление основного набора оставляет связанные строки в других таблицах. Без описания связей задача удаления выполняется частично, а формально считается выполненной.
Отсутствие проверки. Задача удаления существует в планировщике, но её результат никто не проверяет. Через год выясняется, что задача падала с ошибкой, а данные продолжали накапливаться; о метриках — в статье про SLO и error budget.
Преодоление этих препятствий — организационная задача. Техническая реализация удаления проста, а определение того, что и когда удалять, требует решения владельца данных.
Практика: внедрение политики хранения
1. Составьте реестр данных. Таблица, тип данных, срок, основание, ответственный. Без реестра политика существует только на словах.
2. Задайте срок при создании схемы. Колонка created_at и указание срока в комментарии к таблице делают правило видимым для разработчиков.
3. Партиционируйте таблицы с предсказуемым ростом. Метрики, логи, события — кандидаты на удаление отбрасыванием раздела, а не построчным DELETE.
4. Удаляйте пакетами. Удаление миллиона строк в одной транзакции удерживает блокировки и разрывается по таймауту; о разрастании после удалений — в статье про VACUUM.
5. Автоматизируйте через планировщик. Задача по расписанию с идемпотентным условием выполняется независимо от того, помнит ли кто-то о ней.
6. Проверяйте выполнение. Метрика объёма данных по типам показывает, что удаление действительно происходит; о требованиях к персональным данным — в статье про 152-ФЗ и GDPR.
7. Обезличивайте вместо хранения в открытом виде. Агрегаты сохраняют аналитическую ценность без персональных данных и без срока удаления.
8. Проверяйте связанные данные. Удаление заказа без удаления связанных строк в истории операций оставляет персональные данные в системе. Реестр данных должен описывать связи, а задача удаления — обходить их в правильном порядке.
9. Учитывайте поисковые индексы и кеш. Копии данных в поисковом индексе или кеше не удаляются запросом к базе. Для них нужен собственный срок жизни либо явная инвалидация.
10. Логируйте факт удаления. Запись о том, когда и какой объём данных удалён, подтверждает выполнение политики при проверке; о журнале — в статье про audit log.
Рекомендации:
- Не храните данные «на всякий случай». Стоимость хранения и риск утечки растут, а ценность старых данных обычно нулевая.
- Разделяйте горячие и холодные данные. Перенос старых записей в объектное хранилище снижает нагрузку на базу; о хранении объектов — в статье про жизненный цикл объектов.
- Учитывайте резервные копии. Удаление из рабочей базы не удаляет данные из копий, поэтому срок хранения применяется и к ним.
- Фиксируйте исключения. Если данные хранятся дольше по требованию регулятора, основание фиксируется в реестре.
- Тестируйте удаление. Проверка, что задача удаляет ожидаемый объём и не затрагивает свежие данные, обязательна.
Практический сценарий: таблица логов на 400 миллионов строк и запрос удалить данные старше 90 дней
Контекст: таблица логов доступа росла без ограничения и достигла 400 миллионов строк. Юридический отдел запросил удаление данных старше 90 дней.
- Диагностика. Прямой
DELETEпо 350 миллионам строк оценивался в сутки работы с удержанием блокировок. Таблица не была партиционирована, а размер индексов превышал размер полезных данных. - Причина. Срок хранения не задавался при проектировании, а удаление выполнялось вручную и нерегулярно.
- Действия. (а) Создали новую таблицу с партиционированием по месяцам; (б) перенесли данные за последние 90 дней батчами по 50 тысяч строк, чтобы не блокировать запись; (в) переключили приложение на новую таблицу; (г) старую переименовали, выждали сутки и удалили — мгновенная операция вместо суточного
DELETE; (д) добавили задачу по расписанию, отбрасывающую разделы старше 90 дней; (е) внесли срок в реестр данных и добавили метрику объёма по типам. - Результат. Удаление стало мгновенной операцией, объём таблицы стабилизировался, а выполнение политики проверяется метрикой, а не памятью сотрудников.
Вывод: срок хранения проектируется вместе со схемой. Для больших таблиц построчное удаление неприменимо — партиционирование по времени превращает его в отбрасывание раздела, а автоматизация гарантирует, что политика выполняется регулярно.
FAQ
Как определить срок хранения? Исходя из цели обработки и требований регулятора. Срок должен быть обоснован, а не выбран произвольно.
Что делать с резервными копиями? Срок хранения распространяется и на них. Практически это означает ротацию копий с периодом, не превышающим срок хранения.
Почему нельзя удалять всё одной командой DELETE? Операция удерживает блокировки, пишет большой объём WAL и оставляет мёртвые строки. Пакетное удаление или отбрасывание раздела безопаснее.
Как проверить, что удаление выполняется? Метрикой объёма данных по типам с порогом. Рост выше ожидаемого уровня означает, что задача не работает.
Источники: GDPR ст. 5 (ограничение хранения), PostgreSQL docs (партиционирование, DELETE) — ссылки в шапке.