Performances de validation lente de PostgreSQL

9

Nous rencontrons quelques problèmes avec une configuration PostgreSQL. Après quelques repères, j'ai découvert que les requêtes très simples prennent un temps relativement long, après une inspection plus poussée, il apparaît que la commande COMMIT réelle est vraiment lente.

J'ai exécuté un test très simple en utilisant le tableau suivant:

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

Après avoir activé la journalisation de toutes les instructions, j'ai exécuté la requête suivante 10000 fois:

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

Le BEGIN et l'INSERT prennent <1 ms pour terminer, mais le COMMIT prend en moyenne 22 ms pour terminer.

L'exécution du même benchmark sur mon propre PC, qui est beaucoup plus lent, donne la même moyenne pour les instructions BEGIN et INSERT, mais le COMMIT moyen est d'environ 0,4 ms (plus de 20 fois plus rapide).

Après quelques lectures, j'ai essayé l' pg_test_fsyncoutil pour essayer de cerner le problème. Sur le serveur, j'obtiens ces résultats:

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

Sur mon propre PC, je reçois:

$ ./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 configuration du serveur:

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

La machine utilisée pour la comparaison est un i5 avec 16 Go de RAM et des disques SATA ordinaires (sans raid).

Plus d'informations:

  • Système d'exploitation: serveur Ubuntu 12.10
  • Noyau: Linux ... 3.5.0-22-generic # 34-Ubuntu SMP mar 8 jan 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • RAID logiciel 1
  • Le système de fichiers est ext4
  • Aucune autre option de montage spécifiée.
  • Postgres version 9.1
  • Raid Linux mdadm

Sortie de 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 - sortie détaillée:

/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

Mise à jour 2013-03-25 : j'ai exécuté un long test intelligent sur les deux disques, qui n'a révélé aucun problème. Les deux disques proviennent de Seagate, modèle: ST3000DM001-9YN166.

Mise à jour 2013-03-27 : J'ai exécuté le pg_test_fsync de la dernière version (9.2.3) sur une machine complètement inactive:

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

C'est un peu mieux qu'avant, mais toujours déplorable. Les partitions sur les deux disques sont alignées:

$ 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

Montez la sortie -v:

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

Le périphérique md2 est utilisé pour les tests. Va détruire la partition de swap et exécuter pg_test_fsync sur des disques individuels.

Si j'exécute pg_test_fsync sur les deux disques individuellement, j'obtiens à peu près les mêmes performances, la partition a été montée sans délai:

$ 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

Après avoir exécuté le test plusieurs fois, à la fois sur la baie et sur le disque unique, les chiffres semblent varier énormément. Le pire des cas, la performance est d'environ 50% de ce que j'ai posté ici (quelque part autour de 30 ops / s pour le premier test.) Est-ce normal? La machine est complètement inactive, tout le temps.

De plus, selon la sortie dmesg, le contrôleur est en mode AHCI.

Chialer
la source
Pouvez-vous fournir des détails sur ce RAID logiciel? Quel logiciel? Linux mdadmou dmraid? Quelque chose de spécifique au fournisseur? Autre chose? Votre version PostgreSQL et la version du système d'exploitation hôte pourraient également vous aider.
Craig Ringer

Réponses:

6

Le serveur a des fsyncperformances incroyablement, indiciblement et incroyablement lentes . Il y a quelque chose de très grave dans la configuration de votre logiciel RAID 1. Les fsyncperformances terribles sont presque certainement la cause de vos problèmes de performances.

Le bureau est simplement très lent fsync.

Vous pouvez contourner les problèmes de performances au prix de la perte de certaines données après un crash en définissant synchronous_commit = offet en définissant a commit_delay. Vous avez vraiment besoin de trier les performances du disque sur le serveur, cependant, c'est incroyablement lent.

À titre de comparaison, voici ce que j'obtiens sur mon ordinateur portable (i7, 8 Go de RAM, SSD 128G de milieu de gamme, pg_test_fsync à partir de 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

Certes, ce SSD n'est probablement pas sûr contre les pertes de puissance, mais ce n'est pas comme un SSD décent de sécurité contre les pannes de courant coûte cher lorsque nous parlons des coûts de serveur.

Craig Ringer
la source
1
Oui, mais qu'est-ce qui cause les mauvaises performances de fsync?
Blubber
J'ai essayé d'exécuter pg_test_fsync sur mon propre SSD et j'obtiens des performances comparables. Je sais que je pourrais désactiver les validations de synchronisation, mais la question demeure, quelle est la cause de ce problème?
Blubber
@Blubber Quel RAID logiciel utilisez-vous? Quel système de fichiers? Quel OS hôte et quelle version? Quelles options de montage du système de fichiers? Ce sont toutes des informations essentielles si vous recherchez la cause première; veuillez mettre à jour votre question. Vous devriez également faire des vérifications d'intégrité SMART sur les disques durs ( smartctl -d ata -a /dev/sdx|lesset smartctl -d ata -t long /dev/sdxsuivies d'un sleep 90mou de tout ce qui smartctlvous dit suivi d'un autre -d ata -apour obtenir les résultats).
Craig Ringer
@Blubber Même si vous corrigez les problèmes de RAID, vos performances seront toujours mauvaises, mais pas aussi mauvaises. Les vieux disques à 7200 tr / min (ou pire, à 5400 tr / min) sont un mauvais choix pour les performances de la base de données, en particulier sans un contrôleur RAID matériel approprié avec un cache sauvegardé par batterie qui permet au groupe de contrôleurs de monter et de tamponner les écritures.
Craig Ringer
J'ai mis à jour la question avec plus de détails sur le système de fichiers et la configuration du raid. Je comprends que cette machine ne donnera jamais de très bonnes performances dans sa configuration actuelle. Mais les performances actuelles sont vraiment mauvaises.
Blubber
1

Ceci est pg_test_fsyncproduit sur mon serveur, avec une configuration très similaire - Logiciel Linux RAID1 sur 2 disques grand public ( 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
...

Vous l'avez testé sur un serveur complètement inactif, n'est-ce pas?


Vous avez peut-être des partitions non alignées. Vérifier:

parted /dev/sda unit s print

Voici la sortie de mon serveur:

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

Vérifiez que chaque nombre dans la Startcolonne est divisible par 2048 (ce qui signifie 1 Mo). Pour un bon alignement 4096B divisible par 4, cela suffirait, mais les utilitaires sensibles à l'alignement démarrent les partitions aux limites de 1 Mo.


Peut-être que vous utilisez des options de montage non par défaut, comme data=journal, qui ont un grand impact sur les performances. Montrez votre: mount -v | grep ^/dev/. C'est à moi:

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

Peut-être qu'un de vos disques est cassé. Créez une partition sur chaque disque sans RAID (peut-être avez-vous réservé des partitions de swap sur les deux disques - utilisez-les - il n'y a pas d'utilisation de RAID sur swap de toute façon). Créez des systèmes de fichiers là-bas et exécutez-les pg_test_fsyncsur chaque disque - si l'un a des problèmes, un bon devra l'attendre lorsque les deux sont en miroir.


Vérifiez que votre BIOS est configuré pour utiliser le mode AHCI au lieu du mode IDE. Un serveur bénéficierait de Native Command Queuing , qui n'est pas disponible en mode IDE.


Ignorez la comparaison avec le SSD. C'est ridicule de comparer.

Tometzky
la source
J'ai exécuté bonnie ++ qui affiche de bonnes performances (aussi bonnes que vous attendez des disques sata normaux). De plus, les partitions sont alignées. Lorsque j'ai exécuté pg_test_fsync la première fois, c'était sur une machine virtuelle. Ensuite, je l'ai exécuté sur le matériel réel, après avoir arrêté tous les autres processus (y compris les machines virtuelles). La performance était légèrement meilleure, autour de 40 ops / sec, ce qui est toujours déplorable. Je vais exécuter quelques tests supplémentaires, sur des partitions séparées si j'ai le temps aujourd'hui. Merci pour toutes les suggestions.
Blubber
J'ai modifié ma question d'origine avec des informations supplémentaires sur les options de montage et l'alignement des partitions.
Blubber
1

Je sais que je pourrais être bien trop tard pour répondre à cette question. J'ai vu des problèmes de performances similaires avec PostgreSQL et MySQL, lors de l'utilisation de O_DIRECT. J'ai micro-testé le système en utilisant iozone avec des écritures de synchronisation (option - + r) et avec et sans O_DIRECT (option -I). Voici les deux commandes que j'ai utilisées:

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

et

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

Le premier est O_SYNC + O_DIRECT tandis que le second est uniquement O_SYNC. Avec le premier, j'obtenais environ 30 Mo / s et avec le second, j'obtenais environ 220 Mo / s (lecteur SSD). Ce que j'ai découvert, c'est que l'option has_journal sur les coutures ext4 est à l'origine du problème. Je ne sais pas vraiment pourquoi ...

Filesystem features:      has_journal 

Une fois que j'ai retiré cette option, les choses ont commencé à bien fonctionner, les deux tests atteignant et soutenant 220 Mo / s. Pour retirer l'option, vous pouvez utiliser quelque chose comme:

tune2fs -O ^has_journal /dev/sdX

Vous pouvez tester cela et voir si cela résout vos problèmes de performances.

scribul
la source
1
La désactivation du journal sur ext3 / 4 n'est pas quelque chose à faire sans un examen attentif et une très bonne compréhension de l'impact.
ThatGraemeGuy
2
Je ne suis pas d'accord. Un SGBD effectue sa propre journalisation et récupération pour assurer la durabilité et l'atomicité des transactions. Le journal FS est complètement inutile à cet égard. Tant que fsync fonctionne correctement, les effets des transactions validées peuvent toujours être restaurés.
Caetano Sauer