Перейти к содержанию

ADR-0003 · Хранилище журнала: расширить имеющееся#

Статус:    принят · 2026-09-18
Метод:     D-01 v2.0 · рыночный снимок 2026-09-16 · шаблон ADR v1.2
Участники: сопровождение (3 человека)

Учебная запись: часть прогона E-03, система вымышлена. Форма и рассуждение настоящие.

Контекст#

Вход — 00-context.md. Журнал остаётся во владении модуля учёт с единственным писателем (ADR-0002); здесь решается, где он лежит.

Семь вопросов раздела 1#

Вопрос Ответ
Какие 3–5 запросов дают основную нагрузку Вставка операции — 470 тыс./сут. Путь посылки — точечно по идентификатору, 1 200 обращений в поддержку в сутки [замер]. Срез по пункту за период — при разборе расхождений. Ночная выгрузка — полный суточный срез
Соотношение чтения и записи у этого хранилища 9 вставок/с против ≈ 0,02 чтения/с. Пишущий профиль — см. ниже
Объём сейчас, через год, и задан он или выбирается 100 ГБ/год, 300 ГБ за регламентные три года. Срок задан регламентом; граница горячего и холодного выбирается нами — и выбрана не тем критерием, см. ниже
Что обязано меняться атомарно Приёмка: обновить посылку и записать операцию, 225 тыс. раз в сутки [схема]
Какая свежесть допустима Строгая: сверка читает то, что записано. Отставания журнал не терпит — он и есть источник порядка
Кто эксплуатирует и есть ли управляемая версия Трое сопровождающих, платформенной команды нет. Размещение — свой ЦОД плюс холодный резерв, управляемых сервисов нет вовсе [орг]
Ограничения по лицензии, поставщику, юрисдикции Журнал содержит идентификаторы, но не ПДн (ADR-0002). Регламент требует неизменяемого хранения три года [режим]

Обе «осторожности» раздела 1 сработали#

Первая — соотношение чтений к записям у хранилища, а не у системы. У системы 470 тыс. операций в сутки, и все они выглядят как работа с журналом. У самого журнала картина другая: вставок 9/с, чтений около 0,02/с, то есть на каждое чтение приходится примерно 450 записей. Но чтения тяжёлые — диапазонные срезы по пункту и периоду, — и настраивать журнал как читающее хранилище значит строить индексы под то, что происходит раз в минуту.

Вторая — объём как параметр. Три года заданы регламентом, а граница горячего и холодного выбрана нами на предыдущем этапе — 90 суток, по периоду инвентаризации. Проверка запросами показала, что критерий не тот: самое частое чтение — путь посылки за последний год при обращении в поддержку, и при окне в 90 суток две трети таких обращений уходят в архив.

D-07 предупреждает об этом прямо: у формы «разделить по времени» режим отказа записан как «граница горячего подобрана на глаз и уезжает». Она уехала на следующем же этапе.

Окно Сырьё С индексами Доля обращений в поддержку, попадающих в горячее
90 суток (из ADR-0002) 8,5 ГБ ≈ 25 ГБ ≈ 33 % [расчёт]
400 суток 37 ГБ ≈ 110 ГБ ≈ 96 % [расчёт]

Граница переносится на 400 суток, и это частичная отмена параметра из ADR-0002 — см. «Связанные ADR». Для PostgreSQL 110 ГБ горячей таблицы не создают ни одной развилки, так что цена переноса нулевая; цена неверного окна — две трети обращений в поддержку ходят в архив, который объявлен неизменяемым и лежит холодно.

Дисквалификаторы#

Проверялись три альтернативы: колоночное хранилище под журнал, объектное хранилище с блокировкой записи под архив, отдельный экземпляр PostgreSQL под учёт.

Условие Кого отсекло
Нет управляемой версии там, где мы размещаемся, а эксплуатировать самим некому Колоночное хранилище · объектное хранилище. Свой ЦОД, трое сопровождающих, ни один не автор, выкат раз в две недели вручную [орг]
Команда не умеет эксплуатировать и не планирует учиться в горизонте проекта То же. Горизонт задан одной задачей — сократить обнаружение расхождений с 90 суток до суток; освоение второго хранилища в него не помещается
Не даёт транзакционной границы, которая требуется Отдельный экземпляр PostgreSQL под учёт: приёмка перестаёт быть атомарной 225 тыс. раз в сутки. Тот же дисквалификатор, что отменил физическое разделение в ADR-0002

Рассмотренные варианты#

Дисквалификаторы сделали всю работу: не осталось ни одного варианта, кроме нулевого. Матрица не заполняется.

Что отсечено Чем
Колоночное хранилище (ClickHouse и аналоги) Некому эксплуатировать; управляемой версии в нашем размещении нет
Объектное хранилище с блокировкой записи под архив То же. Это единственный вариант, дававший настоящую неизменяемость, и его потеря записана в последствия
Отдельный экземпляр PostgreSQL под модуль учёт Разрывает атомарную приёмку
Нулевой вариант — расширить имеющийся PostgreSQL Не отсечён

Пустой раздел без этой строки выглядел бы небрежностью, хотя означает обратное: сравнивать было не с чем.

Решение#

Журнал остаётся в имеющемся PostgreSQL. Три уточнения формы хранения:

  1. Партиционирование по времени, месячными секциями. Отсечение архивных секций и ночная выгрузка идут по границе секции, а не запросом с условием по дате.
  2. Горячее окно — 400 суток, вместо 90 из ADR-0002. Критерий — доля обращений, обслуживаемых без обращения к архиву; целевая доля выбрана 95 %, фактическая по расчёту 96 %.
  3. Индексы под два чтения: точечный по идентификатору посылки и составной по пункту и времени. Третьего чтения нет — ночная выгрузка идёт полным проходом по суточной секции и индекса не требует.

Неизменяемость архива обеспечивается правами доступа, а не хранилищем. Учётная запись модуля учёт не имеет UPDATE и DELETE на архивных секциях. Это слабее, чем блокировка записи в объектном хранилище: права выдаёт администратор базы, и он же может их вернуть.

Обоснование#

Ни одна ось не сравнивалась, потому что сравнивать было не с чем, и это честный исход, а не пропуск работы. Три дисквалификатора из шести, и два из них — организационные: ровно то, что предсказывает мастер-шаблон, и ровно то, что случилось на прогоне E-01.

Рыночный слой в этом решении не понадобился ни строкой. Таблица типовых решений D-01 содержит десять продуктов с лицензиями и ограничениями; ни один не дошёл до сравнения, потому что все отсеклись раньше — не свойствами продукта, а тем, кто его будет эксплуатировать. Дата съёмки рыночного слоя в этом ADR указана и не использована.

Форма хранения решена запросами, а не вкусом. Два индекса — ровно под два чтения из семи вопросов; третье чтение индекса не требует, и это записано, чтобы его не добавили «на всякий случай».

Последствия#

Отрицательные:

  • Настоящей неизменяемости архива не будет. Регламент требует трёхлетнего неизменяемого хранения; права доступа дают это лишь в той мере, в какой доверяют администратору базы. Единственный вариант, дававший аппаратную гарантию, отсечён отсутствием эксплуатации. Это расхождение с регламентом, и оно записано, а не закрыто формулировкой.
  • Архив живёт в той же базе, значит с ней и ляжет. Отказоустойчивость не улучшилась ни на шаг — как и в ADR-0002.
  • Горячая таблица в 110 ГБ и растущая. Через год — 140 ГБ, через три — 190 ГБ при том же окне. Предел не близок, но за ним никто не следит: предметных метрик нет, а инфраструктурные покажут размер диска, а не размер секции.
  • Перенос границы горячего — вторая правка параметра за два этапа. Первая была выбором, вторая — исправлением критерия. Это признак того, что параметр выбирался не в том разделе, см. замечание.

Положительные: операционный контур остаётся один; резервное копирование и восстановление — те же, что были; атомарность приёмки сохранена без единой оговорки.

Замечание к методу: параметр выбран раньше, чем вопрос о нём задан#

Граница горячего и холодного выбрана на этапе 3 — там, где решалась форма разделения данных. Вопрос, от которого она зависит («какие запросы дают основную нагрузку»), задаётся на этапе 4, в D-01. Между постановкой параметра и вопросом о нём — целый документ.

D-07 знает об этой опасности и называет её в колонке «чем оборачивается при ошибке». Знание не помогло: предупреждение прочитано, параметр всё равно выбран по единственному числу, которое было под рукой, — периоду инвентаризации.

Что из этого следует, решать при ревизии. Возможных ответа два, и они разные по цене: либо форма «разделить по времени» в D-07 обязана отсылать за границей к D-01, либо D-01 обязан спрашивать про уже выбранные границы. Это первый случай в трёх прогонах, когда два документа разошлись не по содержанию, а по порядку.

Условия пересмотра#

  • Доля обращений, обслуживаемых горячим окном, упала ниже 95 % — окно пересчитывается.
  • Появилась возможность эксплуатировать объектное хранилище с блокировкой записи — тогда расхождение с регламентом закрывается, и это отдельное решение.
  • Горячая секция перестала помещаться в память под кэш страниц — появляется первая настоящая развилка по хранилищу.
  • Профиль чтения изменился: появился третий частый запрос, которому не хватает двух индексов.
  • Регламент хранения изменился с трёх лет на другой срок.

Самая дорогая будущая граница#

Граница между журналом и остальной базой. Сегодня журнал — таблица среди других, и его отделяет только владение. Если когда-нибудь понадобится вынести его физически — ради неизменяемости, ради отказоустойчивости или ради другого типа хранилища, — придётся разрывать атомарную приёмку, а это 225 тыс. операций в сутки на главном пути. Цена этой границы не меняется от того, откладываем мы её или нет, и она уже названа дважды: в ADR-0002 и здесь.

Связанные ADR#

Зависит от: ADR-0001 — владение модулей; ADR-0002 — единственный писатель, разделение по времени. Частично отменяет ADR-0002 в одном параметре: граница горячего и холодного переносится с 90 на 400 суток. Остальные решения ADR-0002 в силе. Зависимые: поведение терминала без связи (этап 5), цели и измеритель (этап 6).