Вопрос или проблема
Мы используем pg_dump каждую ночь, чтобы сделать снимок нашей базы данных. Долгое время мы делали это с помощью простой команды
pg_dump -Fc database_name
На это уходит около часа, и создается файл размером более 30 Гбайт.
Как мы можем ускорить процесс?
Наша самая большая таблица содержит необработанные данные изображений в виде столбца bytea
.
Когда мы делали простой COPY из psql на этой таблице в stdout
, это было довольно быстро (1 или 2 минуты), но pg_dump
был очень медленным. Это заняло около 60 минут.
Итак, исследуя это, я наткнулся на это обсуждение. Похоже, что сжатие pg_dump
довольно медленно, если данные уже сжаты, как это бывает с данными изображений в формате bytea
. И лучше сжимать вне pg_dump
(-Z0).
Кроме того, мы обнаружили, что можем использовать нашу многопоточную CPU (-j 10
и pigz -p 10
, чтобы использовать 10 ядер. Вы можете выбрать другое количество ядер).
Итак, теперь мы делаем это так:
$ pg_dump -Z0 -j 10 -Fd database_name -f dumpdir
$ tar -cf - dumpdir | pigz -p 10 > dumpdir.tar.gz
$ rm -r dumpdir
Время сократилось с ~70 минут до ~5 минут. Довольно удивительно.
Вы можете восстановить его так:
$ mkdir -p dumpdir
$ pigz -dc dumpdir.tar.gz | tar -C dumpdir --strip-components 1 -xf -
$ pg_restore -j 10 -Fd -O -d database_name dumpdir
Ответ или решение
Оптимизация времени выполнения pg_dump
для PostgreSQL 13: Достигните 5 минут вместо 70
Использование pg_dump
для создания ночных снимков вашей базы данных является стандартной, но часто весьма ресурсоемкой задачей, особенно когда речь идет о больших объемах данных, как в вашем случае — файл размером более 30 ГБ. Давайте рассмотрим, как можно значительно ускорить этот процесс, сократив его время выполнения с 70 до 5 минут, следуя предложенному вами решению.
Проблема и временные затраты
Исходный вызов:
pg_dump -Fc database_name
занимал около часа. Основная причина этого — наличие большого объема данных в формате bytea
, которые содержат сжатые изображения. Это делает процесс медленным, поскольку встроенная компрессия pg_dump
неэффективна для уже сжатых данных.
Решение: Оптимизация через распределение нагрузки
-
Отключение компрессии в
pg_dump
: Использование флага-Z0
отключает компрессию на сторонеpg_dump
, что существенно сокращает время, затрачиваемое на эту операцию. -
Увеличение параллелизма: Флаг
-j
позволяет распределять работу по нескольким потокам. Если у вас мультикорный процессор, вы можете параллелить этот процесс и использовать ресурсы вашего оборудования более эффективно. В вашем примере используются 10 потоков, что существенно снижает время выполнения операции:pg_dump -Z0 -j 10 -Fd database_name -f dumpdir
-
Ускоренная компрессия с
pigz
: Используйтеpigz
, расширенную версиюgzip
, поддерживающую многопоточность, для компрессии созданного дампа. Это позволит более эффективно использовать доступные ресурсы процессора:tar -cf - dumpdir | pigz -p 10 > dumpdir.tar.gz
-
Очистка временных файлов:
rm -r dumpdir
Восстановление дампа
Для восстановления данных из оптимизированного дампа следуйте следующей процедуре:
-
Создайте директорию для разархивирования:
mkdir -p dumpdir
-
Разархивируйте и извлеките файлы:
pigz -dc dumpdir.tar.gz | tar -C dumpdir --strip-components 1 -xf -
-
Восстановите базу данных с параллелизмом:
pg_restore -j 10 -Fd -O -d database_name dumpdir
Заключение
Ваша проделанная работа по оптимизации не только решает проблему времени выполнения, но и демонстрирует эффективное использование ресурсов современных процессоров. Это значительно сокращает время создания дампа без потери качества резервного копирования и восстановления данных. Урок из этого примера: разумное распределение нагрузки и использование правильных инструментов может привести к впечатляющим улучшениям производительности, что особенно важно при регулярной обработке больших объемов данных.