PostgreSQL prestazioni di commit lento


9

Stiamo riscontrando alcuni problemi con una configurazione PostgreSQL. Dopo alcuni benchmark ho scoperto che le query molto semplici richiedono un tempo relativamente lungo, dopo un'ispezione più approfondita sembra che l'attuale comando COMMIT sia molto lento.

Ho eseguito un test molto semplice usando la seguente tabella:

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

Dopo aver attivato l'accesso a tutte le istruzioni ho eseguito la seguente query 10000 volte:

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

BEGIN e INSERT stanno richiedendo <1ms per il completamento, ma COMMIT impiega in media 22ms per il completamento.

L'esecuzione dello stesso benchmark sul mio PC, che è molto più lenta, produce la stessa media per le istruzioni BEGIN e INSERT, ma il COMMIT medio è di circa 0,4 ms (più di 20 volte più veloce).

Dopo alcune letture ho provato lo pg_test_fsyncstrumento per cercare di individuare il problema. Sul server ottengo questi risultati:

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

Sul mio PC ottengo:

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

La configurazione del server:

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

La macchina utilizzata per il confronto è un i5 con 16 GB di RAM e dischi SATA semplici (nessun raid).

Ulteriori informazioni:

  • Sistema operativo: server Ubuntu 12.10
  • Kernel: Linux ... 3.5.0-22-generic # 34-Ubuntu SMP mar 8 gen 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • Software RAID 1
  • Il filesystem è ext4
  • Non sono state specificate altre opzioni di montaggio.
  • Postgres versione 9.1
  • RAID mdadm raid

Output di 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 - output dettaglio:

/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

Aggiornamento 25-03-2013 : ho eseguito un lungo test intelligente su entrambi i dischi, che non ha rivelato problemi. Entrambi i dischi sono di Seagate, modello: ST3000DM001-9YN166.

Aggiornamento 27-03-2013 : ho eseguito pg_test_fsync dell'ultima versione (9.2.3) su una macchina completamente inattiva:

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

È leggermente meglio di prima, ma ancora deplorevole. Le partizioni su entrambi i dischi sono allineate:

$ 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 output:

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

Il dispositivo md2 viene utilizzato per i test. Andare a distruggere la partizione di swap ed eseguire pg_test_fsync su singoli dischi.

Se eseguo pg_test_fsync su entrambi i dischi singolarmente ottengo all'incirca le stesse prestazioni, la partizione è stata montata con 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

Dopo aver eseguito il test un paio di volte, sia sull'array che sul singolo disco, i numeri sembrano variare notevolmente. Nel peggiore dei casi, le prestazioni sono circa il 50% di ciò che ho pubblicato qui (da qualche parte circa 30 operazioni al secondo test). È normale? La macchina è completamente inattiva, sempre.

Inoltre, secondo l'output di dmesg, il controller è in modalità AHCI.


Potete fornire alcuni dettagli su quel RAID software? Quale software? Linux mdadmo dmraid? Qualcosa di specifico del fornitore? Qualcos'altro? Anche la tua versione PostgreSQL e la versione del sistema operativo host sarebbero di aiuto.
Craig Ringer,

Risposte:


6

Il server ha fsyncprestazioni incredibilmente, indicibilmente, incredibilmente lente . C'è qualcosa di molto grave nell'installazione del RAID 1 del tuo software. Le fsyncprestazioni terribili sono quasi certamente la causa dei tuoi problemi di prestazioni.

Il desktop è semplicemente molto lento fsync.

È possibile aggirare i problemi di prestazioni al costo di perdere alcuni dati dopo un arresto anomalo impostando synchronous_commit = offe impostando a commit_delay. Tuttavia, è davvero necessario risolvere le prestazioni del disco sul server, che è incredibilmente lento.

Per fare un confronto, ecco cosa ottengo sul mio laptop (i7, 8 GB di RAM, SSD da 128 G di fascia media, pg_test_fsync da 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

È vero che questo SSD probabilmente non è sicuro per la perdita di energia, ma non è come un discreto SSD a risparmio energetico che costa molto quando parliamo dei costi del server.


1
Sì, ma cosa sta causando le cattive prestazioni di fsync?
Blubber,

Ho provato a eseguire pg_test_fsync sul mio SSD e ho ottenuto risultati comparabili. So che potrei disabilitare i commit di sincronizzazione, ma la domanda rimane: qual è la causa di questo problema?
Blubber,

@Blubber Quale software RAID stai usando? Quale file system? Quale sistema operativo host e versione? Quali opzioni di montaggio del file system? Queste sono tutte informazioni importanti se stai cercando la causa principale; per favore aggiorna la tua domanda. È inoltre necessario eseguire controlli di integrità SMART sui dischi rigidi ( smartctl -d ata -a /dev/sdx|lesse smartctl -d ata -t long /dev/sdxseguiti da una sleep 90mo qualsiasi altra smartctlcosa seguita da un'altra -d ata -aper ottenere i risultati).
Craig Ringer,

@Blubber Anche se risolvere i problemi RAID vostra performance sarà ancora male, ma non abbastanza come male. I vecchi dischi semplici 7200 RPM (o, peggio, 5400 RPM) sono una cattiva scelta per le prestazioni del database, in particolare senza un controller RAID hardware adeguato con cache supportata da batteria che consente al controller di raggruppare e scrivere sul buffer.
Craig Ringer,

Ho aggiornato la domanda con maggiori dettagli sul filesystem e sulla configurazione del raid. Capisco che questa macchina non darà mai ottime prestazioni nella sua configurazione attuale. Ma le prestazioni attuali sono davvero pessime.
Blubber,

1

Questo viene pg_test_fsyncemesso sul mio server, con una configurazione molto simile - Software Linux RAID1 su 2 dischi consumer ( 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
...

Hai provato questo su server completamente inattivo, vero?


Forse hai partizioni non allineate. Dai un'occhiata:

parted /dev/sda unit s print

Questo è l'output del mio server:

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

Controlla che ogni numero nella Startcolonna sia divisibile per 2048 (che significa 1 MiB). Per un buon allineamento di 4096B divisibile per 4 sarebbe sufficiente, ma i programmi di utilità consapevoli dell'allineamento avviano partizioni ai limiti di 1 MiB.


Inoltre, forse stai usando opzioni di montaggio non predefinite, come data=journal, che hanno un grande impatto sulle prestazioni. Mostra il tuo: mount -v | grep ^/dev/. Questo è mio:

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

Forse uno dei tuoi dischi è rotto. Crea una partizione su ogni disco senza RAID (forse hai prenotato alcune partizioni di swap su entrambi i dischi - usa questi - comunque non è utile per RAID su swap). Crea lì i filesystem ed eseguilo pg_test_fsyncsu ogni unità - se uno ha dei problemi, allora uno buono dovrebbe aspettarlo quando entrambi sono sottoposti a mirroring.


Verifica che il BIOS sia impostato per utilizzare la modalità AHCI anziché la modalità IDE. Un server trarrebbe vantaggio da Accodamento comandi nativo , che non è disponibile in modalità IDE.


Ignora il confronto con SSD. È ridicolo confrontare.


Ho eseguito Bonnie ++ che mostra buone prestazioni (buone come ci si aspetterebbe dai normali dischi SATA). Inoltre, le partizioni sono allineate. Quando ho eseguito pg_test_fsync la prima volta su una VM. Quindi l'ho eseguito sull'hardware effettivo, dopo aver chiuso ogni altro processo (comprese le macchine virtuali). Le prestazioni sono state leggermente migliori, circa 40 operazioni al secondo, il che è ancora deplorevole. Eseguirò altri test, su partizioni separate se oggi ho tempo. Grazie per tutti i suggerimenti.
Blubber,

Ho modificato la mia domanda originale con ulteriori informazioni sulle opzioni di montaggio e l'allineamento delle partizioni.
Blubber,

1

So che potrei essere troppo tardi per rispondere a questa domanda. Ho riscontrato problemi di prestazioni simili con PostgreSQL e MySQL durante l'utilizzo di O_DIRECT. Ho effettuato un micro-benchmarking del sistema usando iozone con sync write (opzione - + r) e con e senza O_DIRECT (opzione -I). Di seguito sono riportati i due comandi che ho usato:

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

e

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

Il primo è O_SYNC + O_DIRECT mentre il secondo è solo O_SYNC. Con il primo stavo ottenendo circa 30 MB / sec e con il secondo stavo ottenendo circa 220 MB / sec (unità SSD). Quello che ho scoperto è che l'opzione has_journal sulle cuciture ext4 ha causato il problema. Non so davvero perché ...

Filesystem features:      has_journal 

Dopo aver scelto questa opzione, le cose hanno iniziato a funzionare bene, entrambi i test hanno raggiunto e sostenuto 220 MB / sec. Per eliminare l'opzione, puoi usare qualcosa come:

tune2fs -O ^has_journal /dev/sdX

Puoi fare un test e vedere se risolve i problemi di prestazioni.


1
Disabilitare il journal su ext3 / 4 non è qualcosa da fare senza un'attenta considerazione e un'ottima comprensione dell'impatto.
ThatGraemeGuy,

2
Non sono d'accordo. Un DBMS esegue la propria registrazione e il ripristino per garantire durata e atomicità delle transazioni. La rivista FS è completamente inutile al riguardo. Fintanto che fsync funziona correttamente, è sempre possibile ripristinare gli effetti delle transazioni impegnate.
Caetano Sauer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.