PostgreSQL Slow Commit-Leistung

9

Wir haben einige Probleme mit einer PostgreSQL-Konfiguration. Nach einigen Benchmarks stellte ich fest, dass sehr einfache Abfragen relativ lange dauern. Bei näherer Betrachtung scheint es, dass der eigentliche COMMIT-Befehl sehr langsam ist.

Ich habe einen sehr einfachen Test anhand der folgenden Tabelle durchgeführt:

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

Nachdem ich die Anmeldung aller Anweisungen aktiviert hatte, führte ich die folgende Abfrage 10000 Mal aus:

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

Der BEGIN und der INSERT benötigen <1 ms, aber der COMMIT dauert durchschnittlich 22 ms.

Das Ausführen des gleichen Benchmarks auf meinem eigenen PC, der viel langsamer ist, ergibt den gleichen Durchschnitt für die Anweisungen BEGIN und INSERT, aber der durchschnittliche COMMIT liegt bei etwa 0,4 ms (mehr als 20-mal schneller).

Nach einigem Lesen habe ich versucht, mit dem pg_test_fsyncTool das Problem zu beheben. Auf dem Server erhalte ich folgende Ergebnisse:

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

Auf meinem eigenen PC bekomme ich:

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

Die Serverkonfiguration:

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

Die zum Vergleich verwendete Maschine ist eine i5 mit 16 GB RAM und einfachen SATA-Festplatten (kein RAID).

Mehr Info:

  • Betriebssystem: Ubuntu Server 12.10
  • Kernel: Linux ... 3.5.0-22-generic # 34-Ubuntu SMP Di Jan 8 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • Software-RAID 1
  • Dateisystem ist ext4
  • Keine anderen Mount-Optionen angegeben.
  • Postgres Version 9.1
  • Linux mdadm raid

Ausgabe von 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 - Detailausgabe:

/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

Update 25.03.2013 : Ich habe auf beiden Festplatten einen langen Smart-Test durchgeführt, bei dem keine Probleme festgestellt wurden. Beide Festplatten stammen von Seagate, Modell: ST3000DM001-9YN166.

Update 27.03.2013 : Ich habe pg_test_fsync der neuesten Version (9.2.3) auf einem vollständig inaktiven Computer ausgeführt:

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

Es ist etwas besser als zuvor, aber immer noch bedauerlich. Partitionen auf beiden Festplatten sind ausgerichtet:

$ 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

Mount -v Ausgang:

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

Das md2-Gerät wird für die Tests verwendet. Zerstören Sie die Swap-Partition und führen Sie pg_test_fsync auf einzelnen Festplatten aus.

Wenn ich pg_test_fsync auf beiden Festplatten einzeln ausführe, erhalte ich ungefähr die gleiche Leistung, die Partition wurde mit noatime gemountet:

$ 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

Nachdem der Test einige Male sowohl auf dem Array als auch auf der einzelnen Festplatte ausgeführt wurde, scheinen die Zahlen stark zu variieren. Im schlimmsten Fall liegt die Leistung bei etwa 50% der hier veröffentlichten Leistung (etwa 30 Operationen / s für den ersten Test). Ist das normal? Die Maschine ist ständig im Leerlauf.

Entsprechend der dmesg-Ausgabe befindet sich der Controller im AHCI-Modus.

Speck
quelle
Können Sie einige Details zu diesem Software-RAID angeben? Welche Software? Linux mdadmoder dmraid? Etwas herstellerspezifisch? Etwas anderes? Ihre PostgreSQL-Version und Host-Betriebssystemversion würden ebenfalls helfen.
Craig Ringer

Antworten:

6

Der Server hat eine unglaublich, unbeschreiblich, erstaunlich langsame fsyncLeistung. Mit Ihrem Software-RAID 1-Setup stimmt etwas sehr schlecht. Die schreckliche fsyncLeistung ist mit ziemlicher Sicherheit die Ursache für Ihre Leistungsprobleme.

Der Desktop hat nur sehr langsam fsync.

Sie können die Leistungsprobleme auf Kosten des Datenverlusts nach einem Absturz umgehen, indem Sie a festlegen synchronous_commit = offund festlegen commit_delay. Sie müssen wirklich die Festplattenleistung auf dem Server regeln, das ist umwerfend langsam.

Zum Vergleich: Folgendes bekomme ich auf meinem Laptop (i7, 8 GB RAM, 128G-SSD mit mittlerer Reichweite, pg_test_fsync ab 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

Zugegeben, diese SSD ist wahrscheinlich nicht stromausfallfest, aber es ist nicht so, dass eine anständige stromausfallsichere SSD viel kostet, wenn es um Serverkosten geht.

Craig Ringer
quelle
1
Ja, aber was verursacht die schlechte fsync-Leistung?
Blubber
Ich habe versucht, pg_test_fsync auf meiner eigenen SSD auszuführen, und erhalte vergleichbare Leistungsdaten. Ich weiß, dass ich Synchronisierungs-Commits deaktivieren könnte, aber die Frage bleibt, was ist die Ursache für dieses Problem?
Blubber
@Blubber Welches Software-RAID verwenden Sie? Welches Dateisystem? Welches Host-Betriebssystem und welche Version? Welche Optionen zum Einhängen von Dateisystemen? Dies sind alles wichtige Informationen, wenn Sie nach der Grundursache suchen. Bitte aktualisieren Sie Ihre Frage. Sie sollten auch auf den Festplatten SMART Gesundheitskontrollen tun ( smartctl -d ata -a /dev/sdx|lessund smartctl -d ata -t long /dev/sdxgefolgt von einem sleep 90moder was auch immer smartctlsagt Ihnen , gefolgt von einem anderen -d ata -adie Ergebnisse zu erhalten).
Craig Ringer
@Blubber Selbst wenn Sie die RAID-Probleme beheben, ist Ihre Leistung immer noch schlecht, nur nicht ganz so schlecht. Einfache alte Festplatten mit 7200 U / min (oder, schlimmer noch, 5400 U / min) sind eine schlechte Wahl für die Datenbankleistung, insbesondere ohne einen geeigneten Hardware-RAID-Controller mit batteriegepuffertem Cache, mit dem der Controller Schreibvorgänge gruppieren und puffern kann.
Craig Ringer
Ich habe die Frage mit weiteren Details zum Dateisystem und zur RAID-Konfiguration aktualisiert. Ich verstehe, dass diese Maschine in ihrer aktuellen Konfiguration niemals eine sehr gute Leistung erbringen wird. Aber die aktuelle Leistung ist wirklich schlecht.
Blubber
1

Dies wird pg_test_fsyncauf meinem Server mit sehr ähnlicher Konfiguration ausgegeben - Linux-Software RAID1 auf 2 Consumer-Festplatten ( 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
...

Sie haben dies auf einem vollständig inaktiven Server getestet, oder?


Möglicherweise haben Sie nicht ausgerichtete Partitionen. Prüfen:

parted /dev/sda unit s print

Dies ist die Ausgabe meines Servers:

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

Überprüfen Sie, ob jede Zahl in der StartSpalte durch 2048 teilbar ist (was 1 MB bedeutet). Für eine gute 4096B-Ausrichtung würde eine durch 4 teilbare Ausrichtung ausreichen, aber ausrichtungsbewusste Dienstprogramme starten Partitionen an 1 MB-Grenzen.


Möglicherweise verwenden Sie auch nicht standardmäßige Mount-Optionen data=journal, die einen großen Einfluss auf die Leistung haben. Zeigen Sie Ihre : mount -v | grep ^/dev/. Das ist meins:

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

Möglicherweise ist eine Ihrer Festplatten defekt. Erstellen Sie eine Partition auf jeder Festplatte ohne RAID (möglicherweise haben Sie einige Swap-Partitionen auf beiden Festplatten reserviert - verwenden Sie diese - RAID für Swap wird ohnehin nicht verwendet). Erstellen Sie dort Dateisysteme und führen Sie sie pg_test_fsyncauf jedem Laufwerk aus. Wenn Probleme auftreten, muss ein guter darauf warten, wenn beide gespiegelt sind.


Überprüfen Sie, ob Ihr BIOS den AHCI-Modus anstelle des IDE-Modus verwendet. Ein Server würde von Native Command Queuing profitieren , das im IDE-Modus nicht verfügbar ist.


Vergleich mit SSD ignorieren. Es ist lächerlich zu vergleichen.

Tometzky
quelle
Ich habe bonnie ++ ausgeführt, das eine gute Leistung zeigt (so gut, wie Sie es von normalen Sata-Festplatten erwarten würden). Außerdem sind die Partitionen ausgerichtet. Als ich pg_test_fsync zum ersten Mal auf einer VM ausführte. Dann habe ich es auf der eigentlichen Hardware ausgeführt, nachdem ich alle anderen Prozesse (einschließlich VMs) heruntergefahren hatte. Die Leistung war mit rund 40 Ops / Sek. Etwas besser, was immer noch bedauerlich ist. Ich werde noch einige Tests auf separaten Partitionen durchführen, wenn ich heute Zeit habe. Vielen Dank für alle Vorschläge.
Blubber
Ich habe meine ursprüngliche Frage mit zusätzlichen Informationen zu Mount-Optionen und Partitionsausrichtung geändert.
Blubber
1

Ich weiß, ich könnte viel zu spät sein, um darauf zu antworten. Bei der Verwendung von O_DIRECT sind bei PostgreSQL und MySQL ähnliche Leistungsprobleme aufgetreten. Ich habe das System mithilfe von iozone mit Synchronisierungsschreibvorgängen (Option - + r) und mit und ohne O_DIRECT (Option -I) mikro-Benchmarking durchgeführt. Unten sind die zwei Befehle, die ich verwendet habe:

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

und

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

Der erste ist O_SYNC + O_DIRECT, während der zweite nur O_SYNC ist. Mit dem ersten bekam ich ungefähr 30 MB / s und mit dem zweiten ungefähr 220 MB / s (SSD-Laufwerk). Was ich herausgefunden habe war, dass die Option has_journal auf ext4-Nähten das Problem verursacht. Ich weiß nicht wirklich warum ...

Filesystem features:      has_journal 

Nachdem ich diese Option ausgewählt hatte, funktionierten die Dinge einwandfrei. Beide Tests erreichten und hielten 220 MB / s aufrecht. Um die Option auszuschalten, können Sie Folgendes verwenden:

tune2fs -O ^has_journal /dev/sdX

Sie können das testen und sehen, ob es Ihre Leistungsprobleme löst.

Scribul
quelle
1
Das Deaktivieren des Journals in ext3 / 4 ist nicht ohne sorgfältige Überlegung und ein sehr gutes Verständnis der Auswirkungen möglich.
ThatGraemeGuy
2
Ich stimme dir nicht zu. Ein DBMS führt seine eigene Protokollierung und Wiederherstellung durch, um die Dauerhaftigkeit und Atomizität von Transaktionen zu gewährleisten. Das FS-Journal ist in dieser Hinsicht völlig nutzlos. Solange fsync ordnungsgemäß funktioniert, können die Auswirkungen festgeschriebener Transaktionen jederzeit wiederhergestellt werden.
Caetano Sauer