Как спать спокойно, когда база данных весит терабайты
Представьте ситуацию: три часа ночи, основной сервер базы данных «упал», а последний бэкап делался сутки назад. Даже если он развернется без ошибок, вы потеряете данные за целый рабочий день. Для бизнеса это катастрофа, для инженера — седые волосы. Именно здесь на сцену выходит WAL-G.
Что это за зверь
Если вы работаете с PostgreSQL, то наверняка слышали про WAL-E. Это был отличный инструмент от команды Heroku, который научил нас правильно делать бэкапы в облака. Но время идет, объемы данных растут, и Python (на котором написан WAL-E) перестал справляться с нагрузкой при сжатии и передаче огромных потоков данных.
WAL-G — это преемник WAL-E, переписанный на Go. Разработчики взяли проверенную идею и выжали из нее максимум производительности. По сути, это инструмент для непрерывного архивирования и быстрого восстановления баз данных. Он умеет делать полные бэкапы (base backups) и постоянно подхватывать WAL-логи (Write Ahead Log), отправляя их в облачное хранилище вроде S3.
Интересно, что проект давно вышел за рамки только «постгреса». Сейчас он поддерживает MySQL, MariaDB, MongoDB, Redis и даже SQL Server.
Почему стоит на него посмотреть
Главная фишка WAL-G — скорость. Благодаря параллелизму в Go, он умеет сжимать и загружать данные в несколько потоков. В моей практике переход с кастомных скриптов на WAL-G сокращал время создания бэкапа в разы.
Вот несколько вещей, которые делают его по-настоящему полезным:
- Потоковое сжатие. Данные сжимаются «на лету» перед отправкой. Вы экономите на трафике и месте в облаке, при этом процессор не захлебывается.
- Поддержка кучи хранилищ. S3 (AWS, Minio, Yandex Cloud), Google Cloud Storage, Azure, OpenStack Swift или просто локальная папка. Выбор за вами.
- Дельта-бэкапы. Вместо того чтобы каждый раз копировать всю базу, WAL-G может записывать только изменившиеся блоки. Для баз в несколько терабайт это спасение.
- Управление временем жизни (Retention). Можно настроить автоматическую очистку старых бэкапов, чтобы не платить за лишние терабайты в S3.
Как это работает внутри
Архитектура проекта довольно прозрачна. Есть основной бинарник, который запускается как CLI-утилита. Когда PostgreSQL генерирует WAL-файл, он вызывает команду wal-push. WAL-G забирает файл, сжимает его (используя lz4, zstd или snappy) и закидывает в хранилище.
При восстановлении все работает в обратном порядке. Вы вызываете wal-fetch, и инструмент вытягивает нужные сегменты логов, чтобы «накатить» их на базовый бэкап до определенного момента времени (Point-in-Time Recovery, PITR).
Практический пример
Настройка обычно не занимает много времени. Сначала нужно прокинуть переменные окружения с доступами к вашему S3-хранилищу.
export WALG_S3_PREFIX=s3://my-db-backups/postgres
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
Чтобы сделать полный бэкап, достаточно одной команды:
wal-g backup-push /var/lib/postgresql/13/main
А в конфиге postgresql.conf прописывается команда для архивации логов:
archive_mode = on
archive_command = 'wal-g wal-push %p'
Теперь каждый раз, когда сегмент лога заполняется, он автоматически улетает в облако. Если сервер сгорит целиком, вы сможете восстановиться на любую секунду до аварии.
Кому это нужно
Если у вас маленькая база на 10 ГБ, которую не жалко потерять, можно обойтись обычным pg_dump по крону. Но если вы строите серьезную инфраструктуру, где:
- База растет быстрее, чем ваши нервы.
- Нужно восстанавливаться на конкретный момент времени.
- Вы используете облака и хотите дешевое, надежное хранилище для бэкапов.
Тогда WAL-G — это стандарт индустрии. Он надежен, как швейцарские часы, и поддерживается крупными компаниями (изначально проект активно развивался в Яндексе).
Конечно, документация местами может показаться суховатой, а количество флагов в конфигурации — избыточным. Но это тот случай, когда один раз настроил и забыл, пока не придет время «учений» по восстановлению данных. А проводить такие учения я советую регулярно, потому что бэкап считается существующим только тогда, когда вы проверили, что из него можно восстановиться.
