У нас возникли проблемы с конфигурацией 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 (без рейда).
Больше информации:
Вывод 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.
Сервер невероятно, несказанно, удивительно медленный fsync
производительность. Что-то очень не так с вашей программной настройкой RAID 1. Ужасный fsync
производительность почти наверняка является причиной ваших проблем с производительностью.
На рабочем столе просто очень медленно fsync
.
Вы можете обойти проблемы с производительностью за счет потери некоторых данных после сбоя, установив synchronous_commit = off
и установив 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
По общему признанию, этот SSD, вероятно, не защищен от потери мощности, но это не похоже на то, что достойный отказоустойчивый SSD стоит очень дорого, когда мы говорим о стоимости сервера.
Я знаю, что могу слишком поздно ответить на этот вопрос. Я наблюдал аналогичные проблемы с производительностью 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
Вы можете протестировать это и посмотреть, решит ли он ваши проблемы с производительностью.
Это 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. Сервер выиграет от Собственная очередь команд, который недоступен в режиме IDE.
Игнорируйте сравнение с SSD. Смешно сравнивать.