PostgreSQL медленная фиксация производительности

9

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

Я провел очень простой тест, используя следующую таблицу:

CREATE TABLE test (
    id serial primary key,
    foo varchar(16),
);

После включения регистрации всех операторов я выполнил следующий запрос 10000 раз:

BEGIN;
INSERT INTO test (a) VALUES ('bar');
COMMIT;

BEGIN и INSERT требуют <1 мс для завершения, но для выполнения команды COMMIT требуется в среднем 22 мс.

Запуск такого же теста на моем собственном ПК, который работает намного медленнее, дает то же самое среднее значение для операторов BEGIN и INSERT, но среднее значение COMMIT составляет около 0,4 мс (более чем в 20 раз быстрее).

После некоторого чтения я попробовал pg_test_fsyncинструмент, чтобы попытаться определить проблему. На сервере я получаю эти результаты:

$ ./pg_test_fsync -o 1024
1024 operations 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                      14.875 ops/sec
        fdatasync                          11.920 ops/sec
        fsync                              30.524 ops/sec
        fsync_writethrough                            n/a
        open_sync                          30.425 ops/sec

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                      19.956 ops/sec
        fdatasync                          23.299 ops/sec
        fsync                              21.955 ops/sec
        fsync_writethrough                            n/a
        open_sync                           3.619 ops/sec

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
        16kB open_sync write                5.923 ops/sec
         8kB open_sync writes               3.120 ops/sec
         4kB open_sync writes              10.246 ops/sec
         2kB open_sync writes               1.787 ops/sec
         1kB open_sync writes               0.830 ops/sec

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                34.371 ops/sec
        write, close, fsync                36.527 ops/sec

Non-Sync'ed 8kB writes:
        write                           248302.619 ops/sec

На моем собственном ПК я получаю:

$ ./pg_test_fsync -o 1024
1024 operations 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                      69.862 ops/sec
        fdatasync                          68.871 ops/sec
        fsync                              34.593 ops/sec
        fsync_writethrough                            n/a
        open_sync                          26.595 ops/sec

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                      26.872 ops/sec
        fdatasync                          59.056 ops/sec
        fsync                              34.031 ops/sec
        fsync_writethrough                            n/a
        open_sync                          17.284 ops/sec

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
        16kB open_sync write                7.412 ops/sec
         8kB open_sync writes               3.942 ops/sec
         4kB open_sync writes               8.700 ops/sec
         2kB open_sync writes               4.161 ops/sec
         1kB open_sync writes               1.492 ops/sec

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                35.086 ops/sec
        write, close, fsync                34.043 ops/sec

Non-Sync'ed 8kB writes:
        write                           240544.985 ops/sec

Конфигурация сервера:

CPU: Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
RAM: 32GB
Disk: 2x 2TB SATA disk in Software RAID 1

Для сравнения используется i5 с 16 ГБ ОЗУ и обычными дисками SATA (без рейда).

Больше информации:

  • ОС: Ubuntu server 12.10
  • Ядро: Linux ... 3.5.0-22-generic # 34-Ubuntu SMP Вт 8 января 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • Программный RAID 1
  • Файловая система ext4
  • Другие параметры монтирования не указаны.
  • Postgres версия 9.1
  • Linux mdadm raid

Вывод dump2efs:

dumpe2fs 1.42.5 (29-Jul-2012)
Filesystem volume name:   <none>
Last mounted on:          /
Filesystem UUID:          16e30b20-0531-4bcc-877a-818e1f5d5fb2
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    (none)
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              182329344
Block count:              729289039
Reserved block count:     36464451
Free blocks:              609235080
Free inodes:              182228152
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      850
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   256
RAID stride:              1
Flex block group size:    16
Filesystem created:       Sat Jan 19 12:42:19 2013
Last mount time:          Wed Jan 23 16:23:11 2013
Last write time:          Sat Jan 19 12:46:13 2013
Mount count:              8
Maximum mount count:      30
Last checked:             Sat Jan 19 12:42:19 2013
Check interval:           15552000 (6 months)
Next check after:         Thu Jul 18 13:42:19 2013
Lifetime writes:          257 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           128
Journal inode:            8
First orphan inode:       17304375
Default directory hash:   half_md4
Directory Hash Seed:      a71fa518-7696-4a28-bd89-b21c10d4265b
Journal backup:           inode blocks
Journal features:         journal_incompat_revoke
Journal size:             128M
Journal length:           32768
Journal sequence:         0x000df5a4
Journal start:            31733

Mdadm - подробный вывод:

/dev/md2:
        Version : 1.2
  Creation Time : Sat Jan 19 12:42:05 2013
     Raid Level : raid1
     Array Size : 2917156159 (2782.02 GiB 2987.17 GB)
  Used Dev Size : 2917156159 (2782.02 GiB 2987.17 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Fri Mar 22 11:16:45 2013
          State : clean 
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : rescue:2
           UUID : d87b98e7:d584a4ed:5dac7907:ae5639b0
         Events : 38

    Number   Major   Minor   RaidDevice State
       0       8        3        0      active sync   /dev/sda3
       1       8       19        1      active sync   /dev/sdb3

Обновление 2013-03-25 : Я провел длинный смарт-тест на обоих дисках, который не выявил никаких проблем. Оба диска от Seagate, модель: ST3000DM001-9YN166.

Обновление 2013-03-27 : я запустил pg_test_fsync последней версии (9.2.3) на полностью бездействующей машине:

$ ./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                      39.650 ops/sec
        fdatasync                          34.283 ops/sec
        fsync                              19.309 ops/sec
        fsync_writethrough                            n/a
        open_sync                          55.271 ops/sec

Это немного лучше, чем раньше, но все же плачевно. Разделы на обоих дисках выровнены:

$ sudo parted /dev/sdb unit s print
Model: ATA ST3000DM001-9YN1 (scsi)
Disk /dev/sdb: 5860533168s
Sector size (logical/physical): 512B/4096B
Partition Table: gpt

Number  Start      End          Size         File system  Name  Flags
 4      2048s      4095s        2048s                           bios_grub
 1      4096s      25169919s    25165824s                       raid
 2      25169920s  26218495s    1048576s                        raid
 3      26218496s  5860533134s  5834314639s                     raid

Смонтировать -v вывод:

$ mount -v | grep ^/dev/
/dev/md2 on / type ext4 (rw,noatime)
/dev/md1 on /boot type ext3 (rw)

Устройство md2 используется для тестов. Собираемся уничтожить раздел подкачки и запустить pg_test_fsync на отдельных дисках.

Если я запускаю pg_test_fsync на обоих дисках по отдельности, я получаю примерно одинаковую производительность, раздел монтируется с noatime:

$ pg_test_fsync/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                      75.111 ops/sec
        fdatasync                          71.925 ops/sec
        fsync                              37.352 ops/sec
        fsync_writethrough                            n/a
        open_sync                          33.746 ops/sec

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                      38.204 ops/sec
        fdatasync                          49.907 ops/sec
        fsync                              32.126 ops/sec
        fsync_writethrough                            n/a
        open_sync                          13.642 ops/sec

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          25.325 ops/sec
         2 *  8kB open_sync writes         12.539 ops/sec
         4 *  4kB open_sync writes          6.207 ops/sec
         8 *  2kB open_sync writes          3.098 ops/sec
        16 *  1kB open_sync writes          1.208 ops/sec

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                27.275 ops/sec
        write, close, fsync                20.561 ops/sec

Non-Sync'ed 8kB writes:
        write                           562902.020 ops/sec

После запуска теста пару раз, как на массиве, так и на одном диске, цифры, кажется, сильно различаются. В худшем случае производительность составляет около 50% от того, что я выложил здесь (где-то около 30 операций в секунду для первого теста.) Это нормально? Машина полностью простаивает, все время.

Также, согласно выводу dmesg, контроллер находится в режиме AHCI.

выпячивающийся
источник
Можете ли вы предоставить некоторые подробности об этом программном RAID? Какое программное обеспечение? Линукс mdadmили dmraid? Что-то специфичное для производителя? Что-то другое? Ваша версия PostgreSQL и версия операционной системы также могут помочь.
Крейг Рингер

Ответы:

6

Сервер имеет невероятно, невероятно, удивительно медленную fsyncпроизводительность. Что-то не так с вашей программной настройкой RAID 1. Ужасная fsyncпроизводительность почти наверняка является причиной ваших проблем с производительностью.

Рабочий стол просто очень медленный fsync.

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

Для сравнения вот что я получаю на своем ноутбуке (i7, 8 ГБ ОЗУ, SSD среднего уровня 128 ГБ, pg_test_fsync из 9.2):

Compare file sync methods using one 8kB write:

        open_datasync                    4445.744 ops/sec
        fdatasync                        4225.793 ops/sec
        fsync                            2742.679 ops/sec
        fsync_writethrough                            n/a
        open_sync                        2907.265 ops/sec

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

Крейг Рингер
источник
1
Да, но что вызывает плохую производительность fsync?
Блуббер
Я попытался запустить pg_test_fsync на своем собственном SSD, и я получил сопоставимые показатели производительности. Я знаю, что могу отключить синхронизацию, но остается вопрос, что является причиной этой проблемы?
Blubber
@Blubber Какое программное обеспечение RAID вы используете? Какая файловая система? Какой хост ОС и версия? Какие параметры монтирования файловой системы? Все это важная информация, если вы ищете основную причину; пожалуйста, обновите ваш вопрос. Вы также должны выполнить SMART-проверки работоспособности на жестких дисках ( smartctl -d ata -a /dev/sdx|lessи smartctl -d ata -t long /dev/sdxзатем получить знак sleep 90mили что- smartctlто еще, после чего другой -d ata -aполучит результаты).
Крейг Рингер,
@Blubber Даже если вы исправите проблемы с RAID, ваша производительность все равно будет плохой, но не настолько плохой. Обычные старые диски 7200 об / мин (или, что еще хуже, 5400 об / мин) являются плохим выбором для производительности базы данных, особенно без надлежащего аппаратного RAID-контроллера с кэш-памятью с резервным питанием от батареи, которая позволяет группировать контроллер и выполнять запись в буфер.
Крейг Рингер
Я обновил вопрос с более подробной информацией о файловой системе и конфигурации raid. Я понимаю, что эта машина никогда не даст очень хороших результатов в своей текущей конфигурации. Но текущая производительность действительно плохая.
Blubber
1

Это pg_test_fsyncвывод на моем сервере с очень похожей конфигурацией - программный RAID1 Linux на 2 дисках потребительского уровня ( WD10EZEX-00RKKA0):

# ./pg_test_fsync -s 3
Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                     115.375 ops/sec
        fdatasync                         109.369 ops/sec
        fsync                              27.081 ops/sec
        fsync_writethrough                            n/a
        open_sync                         112.042 ops/sec
...

Вы проверили это на полностью простаивающем сервере?


Возможно, у вас есть невыровненные разделы. Проверьте:

parted /dev/sda unit s print

Это вывод моего сервера:

Model: ATA WDC WD10EZEX-00R (scsi)
Disk /dev/sda: 1953525168s
Sector size (logical/physical): 512B/4096B
Partition Table: msdos

Number  Start       End          Size         Type     File system     Flags
 1      2048s       67110911s    67108864s    primary  ext4            boot, raid
 2      67110912s   603981823s   536870912s   primary                  raid
 3      603981824s  608176127s   4194304s     primary  linux-swap(v1)
 4      608176128s  1953523711s  1345347584s  primary                  raid

Убедитесь, что каждое число в Startстолбце делится на 2048 (что означает 1 МБ). Для хорошего 4096B выравнивания, делимого на 4, будет достаточно, но утилиты, осведомленные о выравнивании, начинают разделы на границах 1MiB.


Также, возможно, вы используете нестандартные параметры монтирования, например data=journal, которые сильно влияют на производительность. Покажите своим: mount -v | grep ^/dev/. Это мое:

/dev/md0 on / type ext4 (rw,barrier,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0)
/dev/md2 on /home type ext4 (rw,barrier,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0)
/dev/md1 on /var type ext4 (rw,barrier,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0)

Возможно, один из ваших дисков сломан. Создайте по одному разделу на каждом диске без RAID (может быть, вы зарезервировали несколько разделов подкачки на обоих дисках - используйте их - в любом случае RAID не используется). Создайте там файловые системы и запустите их pg_test_fsyncна каждом диске - если у вас есть проблемы, то хорошему придется подождать, когда оба будут зеркально отражены.


Убедитесь, что ваш BIOS настроен на использование режима AHCI вместо режима IDE. Сервер выиграет от Native Command Queuing , которая недоступна в режиме IDE.


Игнорировать сравнение с SSD. Смешно сравнивать.

Tometzky
источник
Я запустил bonnie ++, который показывает хорошую производительность (такую, какую вы ожидаете от обычных дисков sata). Также разделы выровнены. Когда я запустил pg_test_fsync в первый раз, это было на виртуальной машине. Затем я запустил его на реальном оборудовании после завершения всех остальных процессов (включая виртуальные машины). Производительность была чуть лучше, около 40 операций в секунду, что все еще плачевно. Я собираюсь провести еще несколько тестов на отдельных разделах, если у меня будет время сегодня. Спасибо за все предложения.
Blubber
Я исправил свой исходный вопрос, добавив дополнительную информацию о параметрах монтирования и выравнивании разделов.
Blubber
1

Я знаю, что могу быть слишком поздно, чтобы ответить на это. Я видел аналогичные проблемы с производительностью PostgreSQL и MySQL при использовании O_DIRECT. Я провел микро-тестирование системы, используя iozone с синхронизацией (опция - + r) и с O_DIRECT и без него (опция -I). Ниже приведены две команды, которые я использовал:

iozone -s 2g -r 512k -+r -I -f /mnt/local/iozone_test_file -i 0

а также

iozone -s 2g -r 512k -+r    -f /mnt/local/iozone_test_file -i 0

Первый - O_SYNC + O_DIRECT, а второй - только O_SYNC. С первым я получал примерно 30 МБ / с, а со вторым я получал около 220 МБ / с (SSD-накопитель). Я обнаружил, что опция has_journal в швах ext4 вызывает проблему. Не знаю, почему на самом деле ...

Filesystem features:      has_journal 

Как только я отказался от этой опции, все стало работать нормально, и тесты достигли и поддержали 220 МБ / с. Чтобы убрать опцию, вы можете использовать что-то вроде:

tune2fs -O ^has_journal /dev/sdX

Вы можете пройти тест и посмотреть, решит ли он ваши проблемы с производительностью.

scribul
источник
1
Отключение журнала в ext3 / 4 - это не то, что нужно делать без тщательного рассмотрения и очень хорошего понимания воздействия.
ThatGraemeGuy
2
Я не согласен. СУБД ведет свою собственную регистрацию и восстановление, чтобы обеспечить долговечность и атомарность транзакций. Журнал FS совершенно бесполезен в этом отношении. Пока fsync работает должным образом, эффекты зафиксированных транзакций всегда можно восстановить.
Каэтано Зауэр