Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Добрый день. Меня зовут Волков Сергей, я работаю системным архитектором в компании "РЕД СОФТ". При эксплуатации СУБД Ред База Данных или Firebird возникает необходимость выполнить операцию резервного копирования и восстановления. На БД размером сотни гигабайт бекап и рестор занимает часы, а на БД размером несколько терабайт занимает сутки и более. Как ускорить процесс я расскажу под катом.
Введение
Строго говоря, для резервного копирования БД есть две утилиты: gbak (штатная утилита резервного копирования Firebird) и nbackup (предоставляет возможности, отсутствующие у gbak). Gbak работает на логическом уровне - подключается к БД, создает snapshot транзакцию и забирает все метаданные и данные, поэтому может делать только полный бекап. Скорость работы этой утилиты ограничена производительностью процессора. Nbackup работает на файловом уровне, может делать полную резервную копию или инкрементальную резервную копию с заданного уровня или заданной точки. Скорость работы nbackup ограничивается производительностью дисковой подсистемы.
Можно всегда пользоваться только nbackup, но иногда приходится обращаться к gbak. Вот наиболее частые причины, вынуждающие это делать:
изменение размера страницы БД;
обновление версии СУБД, в которой используется новая версия ODS (On Disk Structure);
заканчивается 32-х битный счетчик транзакций, максимальное значение которого равно 2^32-1, т.е. 2 147 483 648 (начиная с версии 3.0 счетчик стал 48-битным);
восстановление БД из-за повреждений, выхода из строя;
уменьшение размера БД;
При восстановлении БД из резервной копии от 1/2 до 2/3 времени занимает активация индексов. Она выполняется в один поток. Значит есть возможность уменьшить время восстановления БД, активируя индексы параллельно.
Прикладное решение plume
Поиски решения данной проблемы на профильных ресурсах не дали универсального ответа. Значит будем делать свой велосипед. На сам велосипед можно посмотреть и даже покататься тут – https://github.com/neozx/plume.
Plume – это утилита, запускаемая из командной строки. Ключами передается строка подключения к БД, логин, пароль и количество потоков для активации индексов.
При запуске plume подключается к БД и получает список индексов, которые необходимо активировать. Затем создает заданное количество потоков activate_index. Каждый поток создает свое подключение к БД, далее берет индекс из списка и активирует его запросом "ALTER INDEX index_name ACTIVE;". По достижению конца списка поток завершается. Так же с помощью утилиты можно обновлять статистику индексов, если указать ключ "-s". Если требуется активировать только конкретные индексы или индексы в определенном порядке, в таком случае ключом "-q" можно передать SQL-запрос, который будет использоваться для получения списка индексов. Ключом "-P" можно задать количество потоков ParallelWorkers, о них будет написано ниже.
Тестировать будем на БД размером 337ГиБ, в ней 6420 таблиц, 10213 индексов. БД используется для документооборота, построенного на Ред Платформе.
Аппаратное обеспечение:
24-х ядерный процессор (AMD Ryzen Threadripper 3960X)
256 ГиБ ОЗУ (SAMSUNG M391 DDR4 ECC DIMM PC4-21300)
NVME SSD 1ТБ (Intel DC P4510)
Тестирование показало следующие результаты:
01:02:30 - время резервного копирования.
03:44:03 - время восстановления из резервной копии.
Как распределяется время внутри процесса восстановления:
00:00:02 - восстановление метаданных.
01:32:26 - вставка данных.
00:13:51 - настройка привилегий.
01:57:43 - активация индексов.
При этом 57% времени занимает активация индексов, которые активируются в одном потоке.
Восстановим БД с ключом "-i" (отключает активацию индексов), а затем посмотрим сколько времени будут активироваться индексы в несколько потоков.
Потоки | Время работы (чч:мм:сс) |
1 | 02:27:27 |
2 | 01:16:04 |
3 | 00:51:15 |
4 | 00:38:51 |
6 | 00:26:26 |
8 | 00:20:33 |
12 | 00:14:12 |
16 | 00:11:05 |
20 | 00:09:18 |
24 | 00:08:45 |
При использовании 24-х потоков время активации индексов сократилось в 16 раз(!). Со 147 минут до 9 минут. При этом время восстановления из резервной копии сократилось до 115 минут (первоначальное время восстановления - 224 минут). Разница почти в 2 раза.
Последовательность резервного копирования и восстановления сокращается почти в 2 раза: с 3ч44мин до 1ч45мин.
Системное решение ParallelWorkers
В СУБД Ред База Данных версии 3.0.9 есть возможность параллельного бекапа, восстановления и sweep (сборки мусора). Максимальное число потоков на сервере задается параметром MaxParallelWorkers в файле firebird.conf, максимальное значение 64. Количество потоков для операции задается параметром ParallelWorkers в том же файле. Так же его можно задать параметром -parallel утилит gfix и gbak.
ParallelWorkers используются при:
резервном копировании данных;
активации индекса;
сборке мусора.
При бекапе создается один основной поток и N-1 рабочих. Каждый поток создает собственное подключение к БД. Когда читается таблица с данными, её записи разделяются между потоками. Каждый поток читает записи со страниц данных, находящихся в выделенной ему POINTER PAGE. Обработав их, берёт следующую необработанную POINTER PAGE.
При восстановлении параллельная обработка реализована только при построении индексов. Внутри ядра создаются N потоков. Параллельные потоки одновременно читают таблицу (так же, как при бекапе) и сортируют её записи. Затем один основной поток строит дерево сортировки (B+tree) и создаёт индекс.
В таблице приведено время резервного копирования при разном значении ParallelWorkers.
ParallelWorkers | Время резервного копирования (чч:мм:сс) |
1 | 01:01:16 |
2 | 00:39:03 |
3 | 00:30:14 |
4 | 00:26:48 |
6 | 00:24:52 |
8 | 00:22:54 |
12 | 00:21:29 |
16 | 00:23:00 |
20 | 00:23:27 |
24 | 00:24:26 |
Для данной БД с текущей аппаратной конфигурацией минимальное время при заданном значении ParallelWorkers=12 составляет 21 минуту.
Время резервного копирования сокращается с 61 минуты до 21 минуты, ускорение работы в 3 раза!
Сравним время активации индексов при использовании ParallelWorkers и при использовании plume.
Потоки | ParallelWorkers (чч:мм:сс) | plume (чч:мм:сс) |
1 | 02:25:42 | 02:27:27 |
2 | 01:45:24 | 01:16:04 |
3 | 01:30:52 | 00:51:15 |
4 | 01:31:03 | 00:38:51 |
6 | 01:36:03 | 00:26:26 |
8 | 01:42:44 | 00:20:33 |
12 | 01:46:50 | 00:14:12 |
16 | 01:51:28 | 00:11:05 |
20 | 01:54:47 | 00:09:18 |
24 | 01:58:39 | 00:08:45 |
ParallelWorkers показывает лучший результат при 3-4-х потоках, далее при увеличении количества потоков идет деградация производительности.
Нужно учитывать важный момент в разнице работы между этими двумя механизмами. ParallelWorkers распараллеливает активацию индекса, при этом данные читаются в несколько потоков. Тогда как plume активирует индексы в разных подключениях. Из этого следует, что ParallelWorkers ускорит активацию одного индекса, что может помочь при наличии большого и "тяжелого" индекса. А plume ускорит активацию большого количества индексов.
Итак, что будет если использовать ParallelWorkers и plume? В таблице ниже приведены результаты при активации индексов в несколько потоков plume и 1-4 потоках ParallelWorkers.
Потоки plume | ParallelWorkers=1 | ParallelWorkers=2 | ParallelWorkers=3 | ParallelWorkers=4 |
1 | 02:27:05 | 01:31:26 | 01:10:10 | 01:00:56 |
2 | 01:16:00 | 00:46:42 | 00:36:05 | 00:31:40 |
3 | 00:51:28 | 00:31:32 | 00:24:34 | 00:21:19 |
4 | 00:39:01 | 00:24:13 | 00:18:52 | 00:16:22 |
6 | 00:26:37 | 00:16:26 | 00:13:04 | 00:11:26 |
8 | 00:20:43 | 00:12:57 | 00:10:19 | 00:09:53 |
12 | 00:14:20 | 00:09:14 | 00:09:18 | 00:09:28 |
16 | 00:11:17 | 00:08:52 | 00:09:25 | |
20 | 00:09:26 | 00:09:09 | 00:09:38 | |
24 | 00:08:46 | 00:09:19 |
Для данной БД при активации индексов ParallelWorkers оказалась менее полезна. Дело в том, что в БД довольно много индексов (10213). Время активации самого тяжелого составило 258 секунд. При ParallelWorkers=3 время активации индекса уменьшилось до 134 секунд. А время активации всех индексов составляет 526 секунд.
Однако в случае если в БД есть очень "тяжелые" индексы, активация которых занимает минуты или даже часы, ParallelWorkers придется как нельзя кстати.
В открытую версию Firebird доработка с параллельными операциями, согласно плану, должна появится в 5-ой версии. А в Ред Базе Данных 3 есть уже сейчас!
Итог
Используя утилиту plume удалось сократить время восстановления из резервной копии в 2 раза, за счет ускорения активации индексов в 16 раз.
Используя СУБД Ред База Данных 3.0.9 с новыми доработками получилось уменьшить время резервного копирования в 3 раза, а время восстановления из резервной копии в 2 раза.