Ускоряем Резервное Копирование. Лекция Яндекса

Несколько предстоящих лекций будут основаны на первом субботнике Ю.

по базам данных, который состоялся Весной .

Первым на Я.

Субботнике выступил разработчик Андрей Бородин.

Он рассказал о WAL-G — простом и эффективном инструменте резервного копирования PostgreSQL в облако, а также об алгоритмах и технологиях, которые позволяют WAL-G быстрее создавать резервные копии.

Основная особенность WAL-G — дельта-резервное копирование.

Из лекции вы узнаете об их реализации и о том, как развивается поддержка этой технологии в PostgreSQL. - Привет! Я разработчик Яндекса из Екатеринбурга.

На пути к технологиям быстрого резервного копирования.

Резервное копирование делаем уже довольно давно, были сообщения Владимир Бородин И Евгения Дюкова о том, как мы исследуем и разрабатываем способы безопасного, надежного, удобного и эффективного хранения данных.

Данная серия посвящена последним разработкам в этой области.

Поговорим о резервных копиях в PostgreSQL в принципе.

Стандартная утилита передачи данных - pg_dump — определяется как консольная утилита, создающая файл с логическим представлением ваших данных.

Тот факт, что это логическая копия, весьма удобен.

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

Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Первое, что вам нужно знать о pg_dump, это то, что это инструмент разработчика.

Это не инструмент эксплуатации базы данных.

pg_dump не предназначен для работы с высоконагруженной базой данных.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Допустим, у вас дела серьезные и вы хотите использовать технологию Point-in-Time Recovery, которая использует API PostgreSQL для работы с онлайн-резервными копиями.

Вы вызываете функцию pg_start_backup и создаете файловую копию базы данных.

Фактически, pg_start_backup заставляет базу данных выполнить CHECKPOINT; и включать запись полной страницы в журнал упреждающей записи.

Копия базы данных, которую вы создаете при вызове API, не является согласованной копией данных.

Вам также необходим журнал упреждающей записи, чтобы иметь возможность восстановить базу данных на время вызова pg_stop_backup, то есть на время завершения резервного копирования.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса



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

В комплекте с коробкой идет утилита pg_basebackup, которая реализует всю эту технологию в каноническом виде и позволяет делать резервную копию с минимально необходимым функционалом.

Если у вас ситуация еще серьезнее, чем раньше, то вы используете какое-то программное обеспечение для управления резервными копиями, и обычно это Barman. У него есть несколько преимуществ.

Главное преимущество в том, что это очень распространённая утилита, у неё огромное сообщество и огромное количество вопросов по Stack Overflow.

Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Вам просто нужно настроить один сервер резервного копирования и выполнить резервное копирование всего вашего PostgreSQL на нем.

Это очень удобно — главное, чтобы вам хватило одного резервного сервера.

Если у вас много резервных серверов, вам необходимо следить за тем, заполнен ли какой-либо из них.

Если сервер резервного копирования выйдет из строя, вам необходимо понять, какая из ваших баз данных сейчас находится в опасности.

Вам нужно в принципе понимать, куда копировать новый кластер базы данных при его создании.

Существует гораздо более простая утилита резервного копирования под названием WAL-E.

Ускоряем резервное копирование.
</p><p>
 лекция яндекса

WAL-E выполняет четыре основные команды.

Команда WAL-PUSH отправляет один файл WAL в облако, а команда WAL-FETCH извлекает один файл WAL, когда необходимо восстановить выполнение команды восстановления.

Также есть BACKUP-PUSH (реализует удаление резервного API) и BACKUP-FETCH (забирает все данные из облака).

Данные хранятся в облаке, поэтому следить за чем-либо не нужно, это уже проблема облачного сервиса, как обеспечить доступность ваших данных тогда, когда они вам понадобятся.

Это, наверное, главное преимущество WAL-E.

Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Функционала там довольно много.

Есть список резервных копий, есть политика хранения, то есть мы хотим хранить резервные копии за последние семь дней, например, или последние пять резервных копий, что-то в этом роде.

А WAL-E умеет делать резервные копии в огромном количестве облачных сервисов: S3, Azure, Google, может называть локальную файловую систему облаком.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Он имеет несколько свойств.

Во-первых, он написан на Python и сильно зависит от конвейера Unix, отчасти из-за этого у него есть зависимости и он не очень производительен.

Это нормально, потому что WAL-E ориентирован на простоту использования и настройки, поэтому вы не можете ошибиться, составляя план резервного копирования.

И это очень хорошая идея.

В WAL-E написано очень много возможностей, и авторам было не очень понятно, куда их развивать дальше.

Пришла идея, что нужен новый инструмент.

Ускоряем резервное копирование.
</p><p>
 лекция яндекса



Ссылка со слайда
Его главная особенность в том, что он переписан на Go, у него практически нет внешних зависимостей, если только вы не используете внешнее шифрование, и он значительно более производительен.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса



Ссылка со слайда
WAL-G изначально был создан двумя авторами из Citus Data, и главное преимущество, изображенное на этой гистограмме, — скорость отправки «валов».

Мы видим, что WAL-E может быть быстрым, всякое может случиться, может быть большая полоса около нуля.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса



Ссылка со слайда
WAL-G имеет достаточно стабильную пропускную способность.

В тестах Citus Data он показал, что стабильно отправляет «общие ресурсы» со скоростью около 800 МБ/с.

Кроме того, в WAL-G, например, я написал функцию, реализующую резервное копирование с реплики.

Вам не нужно нагружать мастер БД нагрузкой чтения, вы можете создать резервную копию реплики.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса



Ссылка со слайда
Но есть одна маленькая проблема.

В тот момент, когда вы начинаете создавать резервную копию, вы должны как-то назвать резервную копию.

В названии указан срок, который будет изменен при необходимости продвижения реплики.

Если в цепочке реплик произойдет отказоустойчивость до того, как реплика, с которой вы делаете резервную копию, вы продвинете одну из реплик, временная шкала будет изменена.

WAL-G понимает, что данная ситуация противоречива, поскольку, имея заголовок на старой временной шкале, заголовок обещает вам, что вы сможете продолжить развитие истории базы данных в любом существующем направлении.

Но это не так.

Вы уже путешествовали по одному из направлений; вы не можете перейти на другую временную шкалу с помощью задней каретки.

Поэтому WAL-G понимает эту ситуацию и не загружает фишинговый JSON-файл в облако.

Вы создаете физическую копию.

Но прежде чем эту копию можно будет использовать, требуется вмешательство администратора.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Мы реализовали дельта-копии в WAL-G, я тоже участвовал в этой разработке.

Это позволяет удалить меньше данных при следующей базовой резервной копии; вы не делаете копию тех страниц данных, которые не изменились с момента предыдущего резервного копирования.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

При настройке WAL-G вы указываете количество шагов, на которое дельта-резервная копия максимально удалена от базовой, и указываете политику дельта-копирования.

Либо вы делаете копию последней существующей дельты, либо делаете дельту из исходной полной резервной копии.

Это необходимо для случая, когда в вашей базе данных постоянно меняется один и тот же компонент базы данных, постоянно меняются одни и те же данные.

Зачем вообще нужны дельта-копии базы данных? По идее у вас есть WAL, вы все равно можете накатиться в любую точку.

На загруженном сервере воспроизведение WAL в течение пяти физических секунд прошлого может занять четыре физических секунды настоящего.

Если вас попросят развернуть WAL за четыре дня, это означает, что человеку, запрашивающему это, возможно, придется подождать еще три дня.

Не всегда приемлемая ситуация.

Вам нужны резервные копии базы на каждый день, но тем не менее вы не можете себе позволить хранить там 7 или 14 полных копий вашей базы, даже с учетом того, что их будет архивировать WAL-G, это все равно будут довольно большие объемы.

И в этом случае помогают дельта-копии.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

В ходе разработки дельта-копий обсуждалось несколько возможных форматов файлов данных.

В первую очередь был предложен формат, где мы просто обнуляем неизменяемую страницу.

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



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Следующая технология, которая рассматривалась, заключалась в сохранении сначала номера блока, а затем измененного блока.

Но здесь мы сталкиваемся с особенностью хранения в TAR-файлах: нам нужно сначала указать размер TAR-файлов, в которых мы храним нашу дельта-копию, а затем начинать ее запись.

Мы хотели реализовать технологию с минимумом потребляемой оперативной памяти, поэтому пришлось использовать третий формат, в котором мы сначала полностью читаем каждый файл данных, ищем измененные страницы данных, сначала сохраняем номера измененных блоков в TAR-файле, и только потом сами измененные блоки.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Эта функция еще не реализована.

Я смотрю на это или ищу кого-нибудь, кто хочет сделать запрос на включение в WAL-G. При восстановлении из разностной копии база данных подвергается каждой реинкарнации на каждом этапе разностной резервной копии.

Иногда в середине жизни некоторые файлы удаляются.

В то же время нам не пришлось бы беспокоиться об их состоянии, если бы они все равно были удалены, а затем воссозданы из дельта-копии.

Это не кажется очень сложной функцией, поэтому, если вы хотите написать что-нибудь на Go, обратите внимание на эту функцию.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

График использования сети, процессора и диска.

Для WAL-E, как мы видим, резервное копирование еще не закончилось, оно началось в 1 час ночи по московскому времени, и не закончилось на последнем отчете, который мы видим.

Графика WAL-G закончилась, работает быстрее и гораздо равномернее по потреблению ресурсов.

Самое интересное — график потребления ресурсов при дельта-копировании.

Мы видим, что все ресурсы стали практически нулевыми.

Загрузка ЦП почти стандартная нагрузка на базу данных; некоторые запросы выполняются ночью.

Мы видим большой зубец для чтения.

Я тоже этим занимаюсь, тоже хотел бы пул-реквест или летом сделаю сам.

Дело в том, что нам все равно придется читать наши данные, чтобы найти, что в них изменилось.

Этого чтения можно было избежать.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

В WAL-G удаление происходит, когда мы указываем количество резервных копий или дату, с которой нам нужно хранить все WAL и все базовые резервные копии.

И WAL-G уже решает вопрос, какие WAL и базовые резервные копии необходимы.

У нас пока нет функции, которая бы удаляла все.

У WAL-E он есть, что тоже является причиной запроса на включение.

Мы еще не реализовали интересную команду DELETE EVERYTHING.

Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Есть список резервных копий.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Мы устанавливаем переменную среды, необходимую для работы WAL-G, и вызываем консольную утилиту WAL-G. Отобразятся резервные копии, которые нам нужно просмотреть.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

В WAL-G реализовано довольно много технологий распараллеливания резервного копирования и различных операций в целом.

Например, эта технология используется для отправки «валов» в архив.

Как только PostgreSQL вызывает archive_command для загрузки одного файла, WAL-G проверяет, есть ли поблизости другие готовые файлы.

В целом это не очень документированная функция, она очень стабильна в последних версиях PostgreSQL, ее используют многие технологии.

Смотрим, есть ли в статусе архива готовые WAL-файлы, и также отправляем их вместе с тем, который база данных попросила отправить в архив.

И когда PostgreSQL просит их отправить, мы их уже отправили, у нас всё готово.

Это существенно ускоряет отправку WAL по загруженным базам данных и позволяет сделать ее не однопоточной.

Обычно PostgreSQL подготавливает один файл, затем ждет его отправки и готовит следующий.

Нам удается избежать этой последовательной работы.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

С помощью WAL-FETCH при восстановлении кластера мы также пытаемся загрузить следующие N файлов, которые будут необходимы, и пытаемся сбалансировать паузы между запусками предварительной выборки новых файлов WAL, чтобы максимально использовать все ресурсы.

что имеем: либо упираемся в сеть, либо в редких случаях сталкиваемся с диском.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Все это настраивается переменными среды.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Существует также параллелизм в изготовлении копии.

Пока эта функция отсутствует в различных релизах - А.

Б.

вышел в релизе 0.1.10 в июне 2018 года — поскольку параллелизм чтения с диска позволяет гарантированно попасть либо в сеть, либо на диск.

Это не очень хорошо, когда база данных загружена.

В WAL-E была функция, позволяющая регулировать скорость.

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

Наша самая важная особенность связана не только с технологиями.

Два года назад Женя Дюков реализовал технология дельта-резервного копирования для Бармана его еще не убили, сообщество все еще обсуждает его.

Почти год назад Женя исправил глюк WAL-E, и мы отправили его на полгода( ссылка на гитхаб — ок.

ред.).

Довольно часто решения с открытым исходным кодом сталкиваются с проблемой того, что их не очень хорошо поддерживают.

Ускоряем резервное копирование.
</p><p>
 лекция яндекса

С WAL-G все довольно просто: мы пользуемся им, а я его обслуживаю.

Если нам или вам что-то понадобится, просто дайте нам знать, что у вас есть проблема.

Мы постараемся решить эту проблему.

Стандартный запрос сообщества прост — «дайте нам всего побольше».

Больше криптовалюты, больше платформ.

Может быть, не только PostgreSQL, но и MySQL, или что-то еще? Я вижу немного другое.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Во-первых, теперь при отправке «вала» мы могли понять, какие блоки базы данных изменились, просканировать эти WAL-файлы и сохранить информацию о том, что изменилось.

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

Мы попытались использовать технологию Page-Track. Он реализует отслеживание изменений страниц на уровне ядра базы данных.

Резервная копия удаляется очень быстро.

Основная проблема PTRACK в том, что он очень агрессивен.

Он содержит множество изменений в ядре PostgreSQL в очень важных местах, поэтому вряд ли он будет принят в ближайшее время.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Также его дельты немного отличаются от тех дельт, которые есть у нас сейчас.

При удалении дельты на основе LSN мы удаляем все изменения в дельта-файле, произошедшие с предыдущего запуска до текущего времени.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

В случае PTRACK мы получаем изменения в файле дельты, начиная с предыдущего сбора дельты.

У нас нет точной разницы во времени до начала резервного копирования и до того, как изменения начнут удаляться.

Это не главная проблема PTRACK, в целом он работает хорошо, но с этим по-прежнему сложно смириться.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

PTRACK не позволяет выполнять дельта-разделение в режиме LATEST_FULL, поскольку он хранит карту измененных блоков после предыдущего разделения этой карты.

У Oracle интересная технология, есть 8 предыдущих карт, которые они сохраняют на всякий случай.

Возможно, мы могли бы сделать что-то подобное, но мы пока не работаем в этом направлении.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса



Ссылка со слайда
В сентябре прошлого года я попытался предложить сообществу технологию, основанную на том, что мы добавляем в ядро только те хуки, которые нам нужны, и реализуем отслеживание измененных страниц в расширении, чтобы патч отслеживания страниц не был слишком агрессивным.

Обсудив эту технологию, мы пришли к выводу, что нам нужно несколько прототипов, и мы добавим хуки, когда будут прототипы.

Возможно, мы посмотрим, как они работают. В настоящее время я работаю над прототипами этих расширений, которые могли бы использовать перехватчики в ядре для отслеживания изменений в базе данных.

В сообществе бытует мнение, что у каждого постгресиста должен быть свой инструмент резервного копирования.

Это плохо.

Каждый занимается своим делом, которое выполняет важнейшую задачу.

Должна быть одна вещь, в которой все будет в коробке, в идеальном мире все будет идеально.

Что бы вы хотели видеть в поле basebackup? Вероятно, нам бы хотелось увидеть архивирование в облаке.

И дельта-копии.



Ускоряем резервное копирование.
</p><p>
 лекция яндекса

Ещё хотелось бы сжатие, параллелизм, шифрование, троттлинг, листинг бэкапов, верификацию, валидацию бэкапов.

Много всего.

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

Теги: #Администрирование баз данных #postgresql #Промышленное программирование #резервное копирование #i.subbotnik

Вместе с данным постом часто просматривают: