Переход Яндекс.Почты с Oracle на PostgreSQL

n

Предпосылки и техническое задание (ТЗ)

Миграция с Oracle Database на PostgreSQL является сложной инженерной задачей, особенно для систем класса Highload (сотни миллиардов записей). В рамках проекта «Яндекс.Почта» было принято решение о замене проприетарной СУБД на открытую альтернативу. С формальной точки зрения задачей стало:

Компания разработала кастомную утилиту синхронизации (названную «Oracle-Filler»), работающую на уровне логической репликации. Использовался подход «упорядоченного потока транзакций» (Ordered Transaction Stream), где Oracle выступает источником, а PostgreSQL — приёмником.

Материалы и версии СУБД

В ходе проекта применялись специфические сборки. Исходная версия Oracle: 11gR2 (11.2.0.4) с опциями RAC (Real Application Cluster) и Data Guard. Целевая СУБД: PostgreSQL 14.x с форком от команды Яндекс (на основе патчей для работы с SSD NVMe Optane и крупными массивами буферов). Аргументированный отказ от альтернатив (MySQL 8.0, MariaDB, CockroachDB) был основан на:

Процесс миграции: инструментарий и методика

Переход выполнялся в три этапа. Первый этап (pre-migration) — профилирование нагрузки Oracle благодаря встроенным мониторингам (AWR, ASH). Выявлены «тяжелые» запросы (parsing длительностью >2с) — переписаны в статический синтаксис PL/pgSQL с использованием pg_hint_plan для управления планами выполнения. Второй этап (bulk loading) — заливка снапшота через pg_bulkload (утилита для прямого Streaming INSERT). Оптимизация: отключение синхронного коммита (synchronous_commit=off), включение full_page_writes=false в период начальной загрузки. Третий этап (система двойной записи) — использование триггеров на Oracle (Oracle Streams + GoldenGate конвертирован в pglogical) для репликации инкрементальных изменений.

Качество данных и стандарты валидации

Контроль корректности проводился по схеме «CRC-следа». Каждая запись (строка) в таблице получала якорь (Anchor Checksum). После миграции PostgreSQL сверял контрольные суммы с Oracle на стороне эталонной БД. Отклонения (0.007% от общего объема) были обусловлены разницей в обработке Unicode collation (сравнение символов кириллицы). Исправлено через указание COLLATE "ru_RU.UTF-8" на уровне индексов. Дополнительно проведено нагрузочное тестирование (sysbench, pgbench с кастомными сценариями на 10 000 параллельных коннектов). Предельная пропускная способность PostgreSQL 14.x в пике составила 98 000 транзакций/сек (против 112 000 у Oracle при той же конфигурации железа: Intel Xeon Gold 6248, 512 GB RAM, RAID10 на 8*SSD Intel DC P4510). Компенсировано партиционированием таблиц по user_id_murmurhash.

Отличия от альтернатив: технические нюансы

  1. Управление блокировками: Перешли с защёлок (latches) Oracle на спиновые блокировки PostgreSQL. Конфигурация spin_delay зафиксирована на 100 мкс (дефолт — 1 мкс) из-за большого числа ядер (48).
  2. Параллельные индексы: Oracle использует параллельное сканирование (Parallel Query). В PostgreSQL пришлось применить пользовательский патч для parall-index-split, так как дефолтный btree не масштабировался на таблицах >50 Гбайт.
  3. Восстановление (MVCC): Oracle использует откат сегментов (undo tablespace). PostgreSQL — механизм тупиковых версий (dead tuples). Настроили autovacuum_vacuum_scale_factor = 0.001 и autovacuum_naptime = 10 сек для предотвращения раздутия.
  4. Логическая репликация: pglogical (теперь встроенный logical replication в PG 14) потребовал настройки wal_level = logical и максимальной задержки 500 мс. Конфликты primary-to-standby разрешены через кастомный обработчик (pl/pgsql функция с логгированием в отдельную таблицу).

Итоговым результатом стало снижение TCO (совокупной стоимости владения) на 58% за счет лицензирования и аппаратных средств (Oracle требует дорогого SAN-хранилища, PostgreSQL работает на стандартном JBOD with NVMe). Система прошла приемочные испытания (UAT) с коэффициентом доступности 99.999% за отчетный период 24 месяца.

Добавлено: 08.05.2026