Desempenho de consolidação lenta do PostgreSQL

9

Estamos tendo alguns problemas com a configuração do PostgreSQL. Após alguns benchmarks, descobri que consultas muito simples demoram um tempo relativamente longo, após uma inspeção mais detalhada, parece que o comando COMMIT real é realmente lento.

Fiz um teste muito simples usando a seguinte tabela:

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

Depois de ativar o log de todas as instruções, executei a seguinte consulta 10000 vezes:

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

O BEGIN e o INSERT estão levando <1 ms para serem concluídos, mas o COMMIT está levando uma média de 22ms para ser concluído.

A execução do mesmo benchmark no meu próprio PC, que é muito mais lento, produz a mesma média para as instruções BEGIN e INSERT, mas a COMMIT média é de cerca de 0,4ms (mais de 20 vezes mais rápido).

Após algumas leituras, tentei a pg_test_fsyncferramenta para tentar identificar o problema. No servidor, eu recebo estes resultados:

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

No meu próprio PC, recebo:

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

A configuração do servidor:

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

A máquina usada para comparação é um i5 com 16 GB de RAM e discos SATA simples (sem invasão).

Mais informações:

  • SO: servidor Ubuntu 12.10
  • Kernel: Linux ... 3.5.0-22-generic # 34-Ubuntu SMP Ter 8 de janeiro 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • RAID de software 1
  • O sistema de arquivos é ext4
  • Nenhuma outra opção de montagem especificada.
  • Postgres versão 9.1
  • Invasão mdadm do Linux

Saída 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 - saída detalhada:

/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

Atualização 25/03/2013 : Fiz um longo teste inteligente nos dois discos, que não revelou problemas. Ambos os discos são da Seagate, modelo: ST3000DM001-9YN166.

Atualização 2013-03-27 : Executei o pg_test_fsync da versão mais recente (9.2.3) em uma máquina completamente ociosa:

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

É um pouco melhor do que antes, mas ainda deplorável. As partições nos dois discos estão alinhadas:

$ 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

Montagem -v saída:

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

O dispositivo md2 está sendo usado para os testes. Vai destruir a partição swap e execute pg_test_fsync em discos individuais.

Se eu executar o pg_test_fsync nos dois discos individualmente, obterá aproximadamente o mesmo desempenho, a partição foi montada com 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

Depois de executar o teste algumas vezes, tanto na matriz quanto no disco único, os números parecem variar bastante. Na pior das hipóteses, o desempenho é de cerca de 50% do que publiquei aqui (algo em torno de 30 operações / s para o primeiro teste.) Isso é normal? A máquina está completamente ociosa, o tempo todo.

Além disso, de acordo com a saída dmesg, o controlador está no modo AHCI.

Gordura
fonte
Você pode fornecer alguns detalhes sobre esse RAID de software? Qual software? Linux mdadmou dmraid? Algo específico do fornecedor? Algo mais? Sua versão do PostgreSQL e a versão do sistema operacional do host também ajudariam.
Craig Ringer

Respostas:

6

O servidor tem um desempenho incrivelmente, indescritível e incrivelmente lento fsync. Há algo muito errado com a configuração do RAID 1 do seu software. O fsyncdesempenho terrível é quase certamente a causa dos seus problemas de desempenho.

A área de trabalho simplesmente fica muito lenta fsync.

Você pode solucionar os problemas de desempenho com o custo de perder alguns dados após uma falha, definindo synchronous_commit = offe configurando a commit_delay. Você realmente precisa resolver o desempenho do disco no servidor, no entanto, isso é extremamente lento.

Para comparação, eis o que recebo no meu laptop (i7, 8 GB de RAM, SSD de 128 G de gama média, 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

É certo que esse SSD provavelmente não é seguro contra perda de energia, mas não é como um SSD decente com falha de energia que custa muito quando falamos em custos de servidor.

Craig Ringer
fonte
1
Sim, mas o que está causando o mau desempenho do fsync?
Blubber
Tentei executar o pg_test_fsync no meu próprio SSD e recebo números de desempenho comparáveis. Sei que poderia desativar os commit de sincronização, mas a pergunta permanece: qual é a causa desse problema?
Blubber
@ Blubber Qual software RAID você está usando? Qual sistema de arquivos? Qual sistema operacional host e versão? Quais opções de montagem do sistema de arquivos? Todas essas informações são críticas se você estiver procurando a causa raiz; atualize sua pergunta. Você também deve fazer verificações de integridade do SMART nos discos rígidos ( smartctl -d ata -a /dev/sdx|lesse smartctl -d ata -t long /dev/sdxseguidas de uma sleep 90mou outra informação smartctlque seja seguida por outra -d ata -apara obter os resultados).
Craig Ringer
@ Blubber Mesmo se você corrigir os problemas de RAID, seu desempenho ainda será ruim, mas não tão ruim assim. Discos antigos simples de 7200RPM (ou, pior, 5400RPM) são uma péssima escolha para o desempenho do banco de dados, especialmente sem um controlador RAID de hardware adequado com cache com bateria que permite que o controlador agrupe e faça gravações no buffer.
Craig Ringer
Atualizei a pergunta com mais detalhes sobre o sistema de arquivos e a configuração do raid. Entendo que esta máquina nunca terá um desempenho muito bom em sua configuração atual. Mas o desempenho atual é muito ruim.
Blubber
1

Isso é pg_test_fsyncproduzido no meu servidor, com uma configuração muito semelhante - software Linux RAID1 em 2 discos de consumo ( 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
...

Você testou isso em um servidor completamente ocioso, não é?


Talvez você tenha partições desalinhadas. Verifica:

parted /dev/sda unit s print

Esta é a saída do meu servidor:

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

Verifique se cada número na Startcoluna é divisível até 2048 (o que significa 1MiB). Para um bom alinhamento 4096B divisível por 4, seria suficiente, mas os utilitários com reconhecimento de alinhamento iniciam partições nos limites de 1MiB.


Talvez você esteja usando opções de montagem não padrão, como data=journal, que têm grande impacto no desempenho. Mostre seu: mount -v | grep ^/dev/. Isso é meu:

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

Talvez um dos seus discos esteja quebrado. Crie uma partição em cada disco sem RAID (talvez você tenha reservado algumas partições de troca nos dois discos - use-as - não há nenhuma utilidade para RAID na troca de qualquer maneira). Crie sistemas de arquivos lá e execute pg_test_fsyncem cada unidade - se houver um problema, um bom sistema terá que esperar por isso quando ambos estiverem espelhados.


Verifique se o BIOS está configurado para usar o modo AHCI em vez do modo IDE. Um servidor se beneficiaria do serviço de enfileiramento de comandos nativo , que não está disponível no modo IDE.


Ignore a comparação com o SSD. É ridículo comparar.

Tometzky
fonte
Corri o bonnie ++, que mostra um bom desempenho (tão bom quanto o esperado em discos sata regulares). Além disso, as partições estão alinhadas. Quando executei o pg_test_fsync na primeira vez em uma VM. Depois, executei-o no hardware real, depois de desligar todos os outros processos (incluindo VMs). O desempenho foi um pouco melhor, em torno de 40 ops / s, o que ainda é deplorável. Vou executar mais alguns testes, em partições separadas, se tiver tempo hoje. Obrigado por todas as sugestões.
Blubber
Alterei minha pergunta original com informações adicionais sobre opções de montagem e alinhamento de partição.
quer
1

Eu sei que talvez seja tarde demais para responder a isso. Eu tenho visto problemas de desempenho semelhantes com o PostgreSQL e o MySQL, ao usar o O_DIRECT. Eu fiz uma micro-avaliação do sistema usando o iozone com gravações de sincronização (opção - + r) e com e sem O_DIRECT (opção -I). Abaixo estão os dois comandos que usei:

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

O primeiro é O_SYNC + O_DIRECT, enquanto o segundo é apenas O_SYNC. No primeiro, eu estava com aproximadamente 30 MB / s e no segundo, com cerca de 220 MB / s (unidade SSD). O que eu descobri foi que a opção has_journal em ext4 costuras para causar o problema. Não sei realmente por que ...

Filesystem features:      has_journal 

Depois de escolher essa opção, tudo começou a funcionar bem, ambos os testes atingindo e mantendo 220 MB / s. Para retirar a opção, você pode usar algo como:

tune2fs -O ^has_journal /dev/sdX

Você pode fazer um teste e ver se ele resolve seus problemas de desempenho.

rabisco
fonte
1
Desabilitar o diário no ext3 / 4 não é algo a ser feito sem uma consideração cuidadosa e uma compreensão muito boa do impacto.
precisa saber é o seguinte
2
Discordo. Um DBMS faz seu próprio registro e recuperação para fornecer durabilidade e atomicidade às transações. O diário FS é completamente inútil nesse sentido. Enquanto o fsync funcionar corretamente, os efeitos das transações confirmadas sempre poderão ser restaurados.
Caetano Sauer