Недавно в компании, где работал друг, весь день кричали продавцы.
Мой друг разработчик и не очень хорошо знает БД.Он сказал, что с их приложением на самом деле проблем нет, но обработка очень медленная каждый день, когда наступает пиковый период, всевозможные перегрузки, и куча запросы не могут быть выполнены. У них нет выделенного администратора баз данных, и они хотят обратиться ко мне за помощью.
Закончив работу, я открыл их базу данных, взглянул на нее и был ошеломлен: в базе данных настроены все параметры по умолчанию. Затем я дал им случайную модификацию и сказал им перезапустить базу данных. На второй день он сообщил: «Брат, ты потрясающий. То, что ты сделал вчера, заставило нашу базу данных внезапно стать быстрее».
Я сказал: я ничего не делал, я просто скорректировал параметры по умолчанию в соответствии со значением опыта, что очень поспешно! Все ваши параметры имеют значения по умолчанию из коробки. Явно не для производства.
Параметры, которые PostgreSQL должен настроить
max_connections
Максимально допустимое количество клиентских подключений. Размер этого параметра имеет некоторую связь с work_mem. Чем выше конфигурация, тем больше памяти можно использовать в системе. Обычно можно настроить сотни подключений.Если необходимо использовать тысячи подключений, рекомендуется настроить пул подключений, чтобы уменьшить накладные расходы.
shared_buffers
PostgreSQL использует собственный буфер, а также использует ядро операционной системы Linux для буферизации кэша ОС. Это означает, что данные хранятся в памяти дважды, сначала в буфере PostgreSQL, а затем в буфере ядра ОС. В отличие от других баз данных, PostgreSQL не обеспечивает прямой ввод-вывод, поэтому это также известно как двойная буферизация. Буферы PostgreSQL называютсяshared_buffer
, рекомендуется установить его на 1/4 физической памяти. Фактическая конфигурация зависит от конфигурации оборудования и рабочей нагрузки.Если у вас большой объем памяти и вы хотите буферизовать некоторые данные в памяти, вы можете продолжать увеличивать размер.shared_buffer
.
Effective_cache_size
Этот параметр в основном используется для оптимизатора Postgre Query. Одним из предположений, что является допустимым размером дискового кэша, доступного для одного запроса, является предполагаемое значение, которое не занимает системную память. Поскольку оптимизатор должен быть оценен стоимость, более высокое значение, скорее всего, будет использовать индексное сканирование, а более низкие значения могут использовать последовательные сканирования. Общее значение Это значение установлено на 1/2 памяти - это нормальная консервативная настройка, а 3/4, установленные на память - это относительно рекомендуемое значение. Просмотр статистики операционной системы через бесплатную команду, вы можете лучше оценить это значение.
[pg@e22 ~]$ free -g
total used free shared buff/cache available
Mem: 62 2 5 16 55 40
Swap: 7 0 7
work_mem
Этот параметр в основном используется для объема памяти, используемого внутренними операциями сортировки и хеш-таблицами перед записью во временные файлы, увеличиваяwork_mem
Параметр позволит PostgreSQL выполнять большую сортировку в памяти. этот параметр иmax_connections
Есть некоторые отношения, скажем, вы установили его на 30 МБ, 40 пользователей, одновременно выполняющих сортировку запросов, скоро будут использовать 1,2 ГБ реальной памяти. При этом для сложных запросов может выполняться несколько операций сортировки и хеширования, например, в сортировке слиянием задействовано 8 таблиц, что требует в 8 раз большеwork_mem
.
Как показано в примере ниже, среда использует 4 МБwork_mem
, который используется при выполнении операций сортировкиSort Method
даexternal merge Disk
.
kms=> explain (analyze,buffers) select * from KMS_BUSINESS_HALL_TOTAL order by buss_query_info;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------
Gather Merge (cost=262167.99..567195.15 rows=2614336 width=52) (actual time=2782.203..5184.442 rows=3137204 loops=1)
Workers Planned: 2
Workers Launched: 2
Buffers: shared hit=68 read=25939, temp read=28863 written=28947
-> Sort (cost=261167.97..264435.89 rows=1307168 width=52) (actual time=2760.566..3453.783 rows=1045735 loops=3)
Sort Key: buss_query_info
Sort Method: external merge Disk: 50568kB
Worker 0: Sort Method: external merge Disk: 50840kB
Worker 1: Sort Method: external merge Disk: 49944kB
Buffers: shared hit=68 read=25939, temp read=28863 written=28947
-> Parallel Seq Scan on kms_business_hall_total (cost=0.00..39010.68 rows=1307168 width=52) (actual time=0.547..259.524 rows=1045735 loops=3)
Buffers: shared read=25939
Planning Time: 0.540 ms
Execution Time: 5461.516 ms
(14 rows)
Когда мы изменим параметры на 512 МБ, мы увидимSort Method
сталquicksort Memory
, который становится сортировкой по памяти.
kms=> set work_mem to "512MB";
SET
kms=> explain (analyze,buffers) select * from KMS_BUSINESS_HALL_TOTAL order by buss_query_info;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=395831.79..403674.80 rows=3137204 width=52) (actual time=7870.826..8204.794 rows=3137204 loops=1)
Sort Key: buss_query_info
Sort Method: quicksort Memory: 359833kB
Buffers: shared hit=25939
-> Seq Scan on kms_business_hall_total (cost=0.00..57311.04 rows=3137204 width=52) (actual time=0.019..373.067 rows=3137204 loops=1)
Buffers: shared hit=25939
Planning Time: 0.081 ms
Execution Time: 8419.994 ms
(8 rows)
maintenance_work_mem
Указывает максимальный объем памяти, используемый операциями обслуживания, такими как (очистка, создание индекса и изменение таблицы, добавление внешнего ключа) Значение по умолчанию — 64 МБ. Так как в нормально работающей БД большого количества одновременных операций такого рода не будет, можно задать большее значение для повышения скорости очистки и создания внешних ключей для индексов.
postgres=# set maintenance_work_mem to "64MB";
SET
Time: 1.971 ms
postgres=# create index idx1_test on test(id);
CREATE INDEX
Time: 7483.621 ms (00:07.484)
postgres=# set maintenance_work_mem to "2GB";
SET
Time: 0.543 ms
postgres=# drop index idx1_test;
DROP INDEX
Time: 133.984 ms
postgres=# create index idx1_test on test(id);
CREATE INDEX
Time: 5661.018 ms (00:05.661)
Вы можете видеть, что при использовании 64 МБ по умолчанию для создания индекса скорость составляет 7,4 секунды, а после установки 2 ГБ скорость создания составляет 5,6 секунды.
wal_sync_method
То, как PostgreSQL принудительно фиксирует данные в журнале WAL после каждой транзакции. можно использоватьpg_test_fsync
команда для тестирования на вашей ОС,fdatasync
является методом по умолчанию в Linux. Как показано ниже, моя среда протестированаfdatasync
Еще скорость. Неподдерживаемые методы, такие как fsync_writethrough, показывают n/a напрямую.
postgres=# show wal_sync_method ;
wal_sync_method
-----------------
fdatasync
(1 row)
[pg@e22 ~]$ pg_test_fsync -s 3
3 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.
Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync is Linux's default)
open_datasync 4782.871 ops/sec 209 usecs/op
fdatasync 4935.556 ops/sec 203 usecs/op
fsync 3781.254 ops/sec 264 usecs/op
fsync_writethrough n/a
open_sync 3850.219 ops/sec 260 usecs/op
Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync is Linux's default)
open_datasync 2469.646 ops/sec 405 usecs/op
fdatasync 4412.266 ops/sec 227 usecs/op
fsync 3432.794 ops/sec 291 usecs/op
fsync_writethrough n/a
open_sync 1929.221 ops/sec 518 usecs/op
Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB in different write
open_sync sizes.)
1 * 16kB open_sync write 3159.780 ops/sec 316 usecs/op
2 * 8kB open_sync writes 1944.723 ops/sec 514 usecs/op
4 * 4kB open_sync writes 993.173 ops/sec 1007 usecs/op
8 * 2kB open_sync writes 493.396 ops/sec 2027 usecs/op
16 * 1kB open_sync writes 249.762 ops/sec 4004 usecs/op
Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written on a different
descriptor.)
write, fsync, close 3719.973 ops/sec 269 usecs/op
write, close, fsync 3651.820 ops/sec 274 usecs/op
Non-sync'ed 8kB writes:
write 400577.329 ops/sec 2 usecs/op
wal_buffers
Размер буфера журнала транзакций, в который PostgreSQL записывает записи WAL перед сбросом буфера на диск. В PostgreSQL версии 12 значение по умолчанию равно -1, которое равно 1/32 от shared_buffers. Это значение можно установить вручную, если автоматический выбор слишком велик или слишком мал. Обычно считается установленным на 16 МБ.
synchronous_commit
Клиент выполняет фиксацию и ждет, пока WAL будет записан на диск, прежде чем вернуть клиенту статус успешного выполнения. Можно установить на on, remote_apply, remote_write, local, off и другие значения. По умолчанию включено. Если установлено значение off, sync_commit будет закрыт, и клиент вернется сразу после отправки, не дожидаясь сброса записи на диск. Если в этот момент произойдет сбой экземпляра PostgreSQL, последние несколько асинхронных коммитов будут потеряны.
default_statistics_target
PostgreSQL использует статистику для создания планов выполнения. Статистику можно собирать с помощью команды «Анализ» вручную или с помощью автоматического анализа, запускаемого процессом автоочистки.default_statistics_target
Параметр указывает уровень детализации, с которым эти статистические данные собираются и регистрируются. Значение по умолчанию 100 подходит для большинства рабочих нагрузок, для очень простых запросов может быть полезно меньшее значение, а для сложных запросов (особенно к большим таблицам) большее значение может быть более приемлемым. Чтобы не быть одним размером для всех, ALTER TABLE .. ALTER COLUMN .. SET STATISTICS можно использовать для переопределения уровня детализации по умолчанию для сбора статистики для определенных столбцов таблицы.
checkpoint_timeout, max_wal_size, min_wal_size, checkpoint_completion_target
Прежде чем разобраться с этими двумя параметрами, давайте сначала рассмотрим несколько операций, запускающих контрольные точки.
- Выполнить команду контрольной точки напрямую
- Выполнять команды, требующие контрольных точек (например, pg_start_backup, Создать базу данных, pg_ctl stop/start и т. д.)
- Настроенное количество времени (checkpoint_timeout) было достигнуто с момента последней контрольной точки.
- Количество WAL, созданных с момента последней контрольной точки (max_wal_size)
При значении по умолчанию контрольная точка будет иметь значение checkpoint_timeout=5min. То есть срабатывает каждые 5 минут. а такжеmax_wal_sizeПараметр представляет собой максимальный объем журнала с упреждающей записью (WAL), который увеличивается между автоматическими контрольными точками. По умолчанию 1 ГБ, если он превышает 1 ГБ, произойдет контрольная точка. Это мягкий предел. В особом случае, например, при кратковременной высокой нагрузке на систему, журнал может достигать 1 ГБ за несколько секунд, эта скорость значительно превышает значение checkpoint_timeout, и размер каталога pg_wal резко увеличивается. На данный момент мы можем видеть похожие предупреждения из журнала.
LOG: checkpoints are occurring too frequently (9 seconds apart)
HINT: Consider increasing the configuration parameter "max_wal_size".
LOG: checkpoints are occurring too frequently (2 seconds apart)
HINT: Consider increasing the configuration parameter "max_wal_size".
Так что настройте max_wal_size разумно, чтобы избежать частых контрольных точек. Обычно рекомендуется устанавливать значение более 16 ГБ, но конкретная настройка должна соответствовать рабочей нагрузке.
Параметр min_wal_size указывает, что пока использование диска WAL остается ниже этого значения, при выполнении контрольной точки старые файлы WAL всегда возвращаются для использования в будущем, а не удаляются напрямую.
Запись контрольных точек не завершается сразу, и PostgreSQL распределяет все операции контрольной точки в течение определенного периода времени. Этот период времени определяется параметромcheckpoint_completion_target
Контроль, это дробь, по умолчанию 0,5. То есть операция записи на диск завершается при коэффициенте 0,5 между двумя контрольными точками. При маленьком значении процесс контрольной точки будет быстрее записывать на диск, а при большом — медленнее. Обычно рекомендуется установить значение 0,9, чтобы растянуть написание контрольных точек. Но недостатком является то, что когда происходит сбой, это влияет на время восстановления.
Используйте инструмент PGTune для настройки параметров
Для компаний, таких как друзья, без специалистов по администрированию баз данных, я обычно рекомендую им использовать PGTune для настройки параметров, этот инструмент представляет собой онлайн-программу,Связь. Настройка проста, вам просто нужно знать версию вашей базы данных, тип ОС, объем памяти, объем ЦП, тип диска, количество подключений и тип приложения. Вы можете легко получить некоторые рекомендуемые значения параметров.
Используйте postgresqltuner для оптимизации параметров
Конечно, мы также можем использовать инструмент postgresqltuner для оптимизации параметров.Автор сказал, что он был вдохновлен mysqltuner, который был написан сценарием perl.
Это программное обеспечение также очень простое в использовании, просто загрузите его, распакуйте и запустите скрипт.
postgresqltuner.pl --host=dbhost --database=testdb --user=username --password=qwerty
Результат выполнения следующий:
Эта программа более профессиональна, чем PGTune, она также выводит некоторые конфигурации операционной системы, в то же время оценивая адекватность параметров памяти исходя из текущей загрузки базы данных, аналогично Advisor.
Суммировать
Наконец, давайте сделаем концовку.Конфигурация системы по умолчанию подходит только для самостоятельной игры, не подходит для использования «из коробки». По-прежнему необходимо настроить соответствующие параметры в соответствии с профессиональным опытом администратора баз данных.Если нет профессиональной детской обуви администратора баз данных, вы также можете использовать скрипт PGTune или postgresqltuner для выполнения некоторых оптимизаций.После завершения этих оптимизаций производительность системы будет значительно улучшен.
Справочная документация
Tuning Your PostgreSQL Server
Tuning PostgreSQL Database Parameters to Optimize Performance