Wydajność powolnego zatwierdzania PostgreSQL

9

Mamy pewne problemy z konfiguracją PostgreSQL. Po kilku testach porównawczych dowiedziałem się, że bardzo proste zapytania zajmują stosunkowo dużo czasu, po dokładniejszej kontroli wydaje się, że rzeczywiste polecenie COMMIT jest naprawdę wolne.

Przeprowadziłem bardzo prosty test, korzystając z poniższej tabeli:

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

Po włączeniu logowania do wszystkich instrukcji uruchomiłem następujące zapytanie 10000 razy:

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

BEGIN i INSERT zajmują <1ms, ale COMMIT zajmuje średnio 22ms.

Uruchomienie tego samego testu porównawczego na moim komputerze, który jest znacznie wolniejszy, daje tę samą średnią dla instrukcji BEGIN i INSERT, ale średni COMMIT wynosi około 0,4 ms (ponad 20 razy szybciej).

Po krótkiej lekturze wypróbowałem pg_test_fsyncnarzędzie, aby spróbować zlokalizować problem. Na serwerze otrzymuję te wyniki:

$ ./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

Na własnym komputerze otrzymuję:

$ ./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

Konfiguracja serwera:

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

Maszyna używana do porównania to i5 z 16 GB pamięci RAM i zwykłymi dyskami SATA (bez raidu).

Więcej informacji:

  • System operacyjny: serwer Ubuntu 12.10
  • Jądro: Linux ... 3.5.0-22-generic # 34-Ubuntu SMP Wt 8 stycznia 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • Oprogramowanie RAID 1
  • System plików to ext4
  • Nie określono innych opcji montowania.
  • Wersja Postgres 9.1
  • RAID Linux-a

Wyjście 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 - szczegółowe dane wyjściowe:

/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

Aktualizacja 2013-03-25 : Przeprowadziłem długi inteligentny test na obu dyskach, który nie wykazał żadnych problemów. Oba dyski pochodzą z Seagate, model: ST3000DM001-9YN166.

Aktualizacja 27.03.2013 : Uruchomiłem pg_test_fsync najnowszej wersji (9.2.3) na całkowicie bezczynnym komputerze:

$ ./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

Jest nieco lepszy niż wcześniej, ale nadal godne ubolewania. Partycje na obu dyskach są wyrównane:

$ 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

Zamontuj wyjście -v:

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

Do testów wykorzystywane jest urządzenie md2. Zniszczę partycję wymiany i uruchom pg_test_fsync na poszczególnych dyskach.

Jeśli uruchomię pg_test_fsync na obu dyskach osobno, uzyskam mniej więcej taką samą wydajność, partycja zostanie zamontowana z 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

Po kilkukrotnym uruchomieniu testu, zarówno na macierzy, jak i na pojedynczym dysku, liczby wydają się znacznie różnić. W najgorszym przypadku wydajność wynosi około 50% tego, co tu zamieściłem (około 30 operacji / s na pierwszy test). Czy to normalne? Maszyna jest całkowicie bezczynna przez cały czas.

Ponadto, zgodnie z wyjściem dmesg, kontroler jest w trybie AHCI.

Beczeć
źródło
Czy możesz podać jakieś szczegóły dotyczące tego oprogramowania RAID? Jakie oprogramowanie? Linux mdadmczy dmraid? Coś specyficznego dla dostawcy? Coś innego? Twoja wersja PostgreSQL i wersja systemu operacyjnego hosta również by pomogły.
Craig Ringer

Odpowiedzi:

6

Serwer ma niewiarygodnie, niewymownie, niezwykle powolną fsyncwydajność. Coś jest bardzo źle z konfiguracją oprogramowania RAID 1. Straszna fsyncwydajność jest prawie na pewno przyczyną problemów z wydajnością.

Pulpit po prostu działa bardzo wolno fsync.

Możesz obejść problemy z wydajnością kosztem utraty niektórych danych po awarii, ustawiając synchronous_commit = offi ustawiając commit_delay. Ty naprawdę trzeba uporządkować wydajność dysku na serwerze, chociaż, to szczęka droppingly powolny.

Dla porównania, oto co otrzymuję na moim laptopie (i7, 8 GB RAM, dysk SSD 128G klasy średniej, pg_test_fsync od 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

Trzeba przyznać, że ten dysk SSD prawdopodobnie nie jest odporny na utratę zasilania, ale nie jest tak, jakby porządny dysk SSD odporny na awarię kosztował dużo, gdy mówimy o kosztach serwera.

Craig Ringer
źródło
1
Tak, ale co powoduje złą wydajność fsync?
Blubber
Próbowałem uruchomić pg_test_fsync na własnym dysku SSD i otrzymałem porównywalne wyniki wydajności. Wiem, że mogłem wyłączyć zatwierdzanie synchronizacji, ale pozostaje pytanie, jaka jest przyczyna tego problemu?
Blubber
@Blubber Jakiego oprogramowania RAID używasz? Jaki system plików Jaki system operacyjny i wersja? Jakie opcje montowania systemu plików? Są to wszystkie kluczowe informacje, jeśli szukasz przyczyny źródłowej; zaktualizuj swoje pytanie. Powinieneś także wykonać SMART kontrole kondycji na dyskach twardych ( smartctl -d ata -a /dev/sdx|lessa smartctl -d ata -t long /dev/sdxnastępnie jedno sleep 90mlub cokolwiek smartctlinnego, -d ata -aco oznacza kolejne, aby uzyskać wyniki).
Craig Ringer
@Blubber Nawet jeśli rozwiążesz problemy z macierzą RAID, Twoja wydajność będzie nadal słaba, ale nie aż tak słaba. Zwykłe stare dyski 7200RPM (lub, co gorsza, 5400RPM) są złym wyborem dla wydajności bazy danych, szczególnie bez odpowiedniego sprzętowego kontrolera RAID z podtrzymywaną bateryjnie pamięcią podręczną, która umożliwia grupowanie kontrolerów i zapisywanie buforów.
Craig Ringer
Zaktualizowałem pytanie o więcej szczegółów na temat systemu plików i konfiguracji raidu. Rozumiem, że ta maszyna nigdy nie zapewni bardzo dobrej wydajności w obecnej konfiguracji. Ale obecne wyniki są naprawdę złe.
Blubber
1

To jest pg_test_fsyncwyjście na moim serwerze, z bardzo podobną konfiguracją - oprogramowanie Linux RAID1 na 2 dyskach klasy konsumenckiej ( 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
...

Testowałeś to na całkowicie bezczynnym serwerze, prawda?


Być może masz nieprzystosowane partycje. Czek:

parted /dev/sda unit s print

To jest wynik mojego serwera:

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

Sprawdź, czy każdą liczbę w Startkolumnie można podzielić przez 2048 (co oznacza 1 MB). Dla dobrego 4096B wystarczy wyrównywanie podzielne przez 4, ale narzędzia świadome wyrównywania rozpoczynają partycje na granicach 1MiB.


Być może używasz niestandardowych opcji montażu, takich jak data=journal, które mają duży wpływ na wydajność. Pokaż swoje: mount -v | grep ^/dev/. To jest moje:

/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)

Być może jeden z twoich dysków jest uszkodzony. Utwórz jedną partycję na każdym dysku bez RAID (być może zarezerwowałeś niektóre partycje wymiany na obu dyskach - użyj ich - i tak nie ma zastosowania dla RAID podczas wymiany). Utwórz tam systemy plików i uruchom je pg_test_fsyncna każdym dysku - jeśli masz problemy, dobry będzie musiał na nie poczekać, gdy oba zostaną dublowane.


Sprawdź, czy system BIOS jest skonfigurowany do używania trybu AHCI zamiast trybu IDE. Serwer skorzystałby z Native Command Queuing , które nie jest dostępne w trybie IDE.


Zignoruj ​​porównanie z dyskiem SSD. To niedorzeczne porównywanie.

Tometzky
źródło
Uruchomiłem bonnie ++, który pokazuje dobrą wydajność (tak dobrą, jak można się spodziewać po zwykłych dyskach sata). Ponadto partycje są wyrównane. Kiedy uruchomiłem pg_test_fsync po raz pierwszy na maszynie wirtualnej. Następnie uruchomiłem go na rzeczywistym sprzęcie, po wyłączeniu każdego innego procesu (w tym maszyn wirtualnych). Wydajność była nieco lepsza, około 40 operacji na sekundę, co nadal jest godne ubolewania. Przeprowadzę jeszcze kilka testów, na osobnych partycjach, jeśli mam dzisiaj czas. Dziękuję za wszystkie sugestie.
Blubber
Poprawiłem swoje oryginalne pytanie o dodatkowe informacje na temat opcji montowania i wyrównania partycji.
Blubber
1

Wiem, że mogę być za późno, aby odpowiedzieć na to pytanie. Podczas używania O_DIRECT widziałem podobne problemy z wydajnością w PostgreSQL i MySQL. Przeprowadziłem mikro-test porównawczy systemu, używając iozone z synchronizacją zapisów (opcja - + r) oraz zi bez O_DIRECT (opcja -I). Poniżej znajdują się dwa polecenia, których użyłem:

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

i

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

Pierwszy to O_SYNC + O_DIRECT, a drugi to tylko O_SYNC. Przy pierwszym uzyskiwałem około 30 MB / s, a przy drugim - około 220 MB / s (dysk SSD). Odkryłem, że przyczyną problemu jest opcja has_journal w szwach ext4. Naprawdę nie wiem dlaczego ...

Filesystem features:      has_journal 

Kiedy wyjąłem tę opcję, wszystko zaczęło działać dobrze, zarówno testy osiągały, jak i utrzymywały 220 MB / s. Aby skorzystać z tej opcji, możesz użyć czegoś takiego:

tune2fs -O ^has_journal /dev/sdX

Możesz przetestować i sprawdzić, czy rozwiąże to problemy z wydajnością.

scribul
źródło
1
Wyłączenie dziennika na ext3 / 4 nie jest czymś, co należy zrobić bez starannego rozważenia i bardzo dobrego zrozumienia wpływu.
ThatGraemeGuy
2
Nie zgadzam się. DBMS wykonuje własne rejestrowanie i odzyskiwanie, aby zapewnić trwałość i atomowość transakcji. Dziennik FS jest pod tym względem całkowicie bezużyteczny. Dopóki fsync działa poprawnie, zawsze można przywrócić efekty popełnionych transakcji.
Caetano Sauer