PostgreSQL 느린 커밋 성능


9

PostgreSQL 구성에 문제가 있습니다. 일부 벤치 마크 후 매우 간단한 쿼리가 비교적 오랜 시간이 걸리는 것을 알았으므로 더 자세히 검사하면 실제 COMMIT 명령이 실제로 느립니다.

다음 표를 사용하여 매우 간단한 테스트를 실행했습니다.

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

모든 명령문에 대한 로깅을 설정 한 후 다음 쿼리를 10000 회 실행했습니다.

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

BEGIN과 INSERT는 완료하는 데 1ms 미만의 시간이 걸리지 만 COMMIT는 완료하는 데 평균 22ms가 걸립니다.

내 PC에서 동일한 벤치 마크를 실행하면 속도가 훨씬 느려 BEGIN 및 INSERT 문의 평균이 같지만 평균 COMMIT는 약 0.4ms (20 배 이상 빠름)입니다.

약간의 독서 후에 나는 pg_test_fsync문제를 찾아 내려고 도구를 시도했다. 서버에서 다음과 같은 결과를 얻습니다.

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

내 PC에서 다음을 얻습니다.

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

서버 구성 :

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

비교에 사용되는 머신은 16GB RAM 및 일반 SATA 디스크가있는 i5입니다 (공격 없음).

더 많은 정보:

  • 운영체제 : Ubuntu server 12.10
  • 커널 : Linux ... 3.5.0-22-generic # 34-Ubuntu SMP 화요일 1 월 8 일 21:47:00 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • 소프트웨어 RAID 1
  • 파일 시스템은 ext4입니다
  • 다른 마운트 옵션이 지정되지 않았습니다.
  • Postgres 버전 9.1
  • 리눅스 mdadm 습격

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-세부 출력 :

/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

2013-03-25 업데이트 : 두 디스크 모두에서 긴 스마트 테스트를 실행했는데 아무런 문제가 없었습니다. 두 디스크 모두 Seagate의 모델입니다 (ST3000DM001-9YN166).

2013-03-27 업데이트 : 완전히 유휴 상태 인 컴퓨터에서 최신 버전 (9.2.3)의 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                      39.650 ops/sec
        fdatasync                          34.283 ops/sec
        fsync                              19.309 ops/sec
        fsync_writethrough                            n/a
        open_sync                          55.271 ops/sec

그것은 이전보다 약간 낫지 만 여전히 비참합니다. 두 디스크의 파티션이 정렬되었습니다.

$ 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

마운트 -v 출력 :

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

md2 장치가 테스트에 사용되고 있습니다. 스왑 파티션을 파괴하고 개별 디스크에서 pg_test_fsync를 실행하십시오.

두 디스크 모두에서 pg_test_fsync를 개별적으로 실행하면 대략 동일한 성능을 얻을 수 있으며 파티션은 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

어레이와 단일 디스크 모두에서 테스트를 몇 번 실행 한 후에는 숫자가 크게 다른 것처럼 보입니다. 최악의 경우 성능은 내가 여기에 게시 한 것의 약 50 %입니다 (첫 번째 테스트의 경우 약 30 ops / s). 이것이 정상입니까? 기계는 항상 완전히 유휴 상태입니다.

또한 dmesg 출력에 따라 컨트롤러가 AHCI 모드에 있습니다.


해당 소프트웨어 RAID에 대한 세부 정보를 제공 할 수 있습니까? 어떤 소프트웨어? 리눅스 mdadm또는 dmraid? 벤더에 특정한 것이 있습니까? 다른 것? PostgreSQL 버전과 호스트 OS 버전도 도움이 될 것입니다.
Craig Ringer

답변:


6

서버는 놀랍게도 말할 것도없이 fsync성능이 놀랍게 느립니다 . 소프트웨어 RAID 1 설정에 문제가 있습니다. 끔찍한 fsync성능은 거의 확실하게 성능 문제의 원인입니다.

데스크탑은 매우 느리다 fsync.

a를 설정 synchronous_commit = off하고 설정하여 충돌 후 일부 데이터가 손실되는 대신 성능 문제를 해결할 수 있습니다 commit_delay. 당신은 정말 그의 턱 droppingly 히 천천히,하지만, 서버의 디스크 성능을 제압해야합니다.

비교를 위해 다음은 랩톱에서 얻는 것입니다 (i7, 8GB RAM, 미드 레인지 128G SSD, 9.2의 pg_test_fsync).

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

틀림없이이 SSD는 전력 손실이 안전하지는 않지만 서버 비용을 이야기 할 때 적절한 전원 장애 안전 SSD 비용과 크게 다르지 않습니다.


1
예, 그러나 무엇이 fsync 성능을 떨어 뜨리고 있습니까?
Blubber

내 SSD에서 pg_test_fsync를 실행하려고 시도했는데 비슷한 성능 수치를 얻었습니다. 동기화 커밋을 비활성화 할 수 있지만 질문이 남아 있습니다.이 문제의 원인은 무엇입니까?
Blubber

@Blubber 어떤 소프트웨어 RAID를 사용하고 있습니까? 어떤 파일 시스템입니까? 어떤 호스트 OS 및 버전? 어떤 파일 시스템 마운트 옵션? 근본 원인을 찾고 있다면 이것들은 모두 중요한 정보입니다. 질문을 업데이트하십시오. 또한 하드 드라이브의 SMART 상태 확인을 (해야 smartctl -d ata -a /dev/sdx|less하고 smartctl -d ata -t long /dev/sdx다음에 의해 sleep 90m또는 어떤 smartctl다른 다음에 알려줍니다 -d ata -a결과를 얻을 수).
Craig Ringer

당신은 RAID 문제를 해결 @Blubber 경우에도 성능은 여전히 꽤 나쁜 것 같은 나쁜. 일반 오래된 7200RPM (또는 악화, 5400RPM) 디스크는 있습니다 나쁜 특히 컨트롤러 그룹을 할 수 있습니다 및 쓰기 버퍼 배터리 백업 캐시와 적절한 하드웨어 RAID 컨트롤러없이 데이터베이스 성능을위한 선택.
Craig Ringer

파일 시스템 및 RAID 구성에 대한 자세한 내용으로 질문을 업데이트했습니다. 이 시스템은 현재 구성에서 매우 우수한 성능을 제공하지 않습니다. 그러나 현재 성능은 정말 나쁩니다.
Blubber

1

이것은 pg_test_fsync2 개의 소비자 급 디스크 ( WD10EZEX-00RKKA0) 에 Linux 소프트웨어 RAID1과 매우 유사한 구성으로 서버에서 출력됩니다 .

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

완전 유휴 서버에서 이것을 테스트 했습니까?


정렬되지 않은 파티션이있을 수 있습니다. 검사:

parted /dev/sda unit s print

이것은 내 서버의 출력입니다.

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

Start열의 각 숫자를 2048 (1MiB)로 나눌 수 있는지 확인하십시오 . 4로 나눌 수있는 4096B 정렬은 충분하지만 정렬 인식 유틸리티는 1MiB 경계에서 파티션을 시작합니다.


또한과 같은 기본이 아닌 마운트 옵션을 사용 data=journal하는 경우 성능에 큰 영향을 미칩니다. 보여주세요 : mount -v | grep ^/dev/. 이 내 꺼야:

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

디스크 중 하나가 고장 났을 수 있습니다. RAID없이 각 디스크에 하나의 파티션을 작성하십시오 (두 디스크 모두에 일부 스왑 파티션을 예약 한 경우-이 디스크를 사용하십시오-어쨌든 스왑에서 RAID를 사용하지 않음). 거기에 파일 시스템을 만들고 pg_test_fsync각 드라이브에서 실행하십시오 -문제가 있으면 둘 다 미러링 될 때 기다려야합니다.


BIOS가 IDE 모드 대신 AHCI 모드를 사용하도록 설정되어 있는지 확인하십시오. 서버는 IDE 모드에서는 사용할 수없는 Native Command Queuing의 이점을 누릴 수 있습니다.


SSD와의 비교를 무시하십시오. 비교하기가 우스운 일입니다.


보니 ++을 실행하여 우수한 성능을 보여줍니다 (일반적인 sata 디스크에서 기대할 수있는 수준). 또한 파티션이 정렬됩니다. pg_test_fsync를 VM에서 처음 실행했을 때 그런 다음 다른 모든 프로세스 (VM 포함)를 종료 한 후 실제 하드웨어에서 실행했습니다. 성능은 약 40 ops / sec로 약간 나아졌지 만 여전히 무시할 수 있습니다. 오늘 시간이 있다면 별도의 파티션에서 몇 가지 테스트를 더 진행할 것입니다. 모든 제안에 감사드립니다.
Blubber

마운트 옵션 및 파티션 정렬에 대한 추가 정보를 사용하여 원래 질문을 수정했습니다.
Blubber

1

나는 이것에 대답하기에 너무 늦을 수도 있다는 것을 안다. O_DIRECT를 사용할 때 PostgreSQL 및 MySQL에서 비슷한 성능 문제가 발생했습니다. 동기화 쓰기 (-+ r 옵션) 및 O_DIRECT (-I 옵션) 유무에 관계없이 iozone을 사용하여 시스템을 마이크로 벤치마킹했습니다. 다음은 내가 사용한 두 가지 명령입니다.

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

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

첫 번째는 O_SYNC + O_DIRECT이고 두 번째는 O_SYNC입니다. 첫 번째는 약 30MB / sec이고 두 번째는 약 220MB / sec (SSD 드라이브)입니다. 내가 찾은 것은 ext4 이음새의 has_journal 옵션이 문제를 일으킨다는 것입니다. 왜 그런지 모르겠다 ...

Filesystem features:      has_journal 

이 옵션을 꺼내면 테스트가 220MB / sec에 도달하고 지속되는 상태에서 정상적으로 작동하기 시작했습니다. 옵션을 꺼내려면 다음과 같은 것을 사용할 수 있습니다.

tune2fs -O ^has_journal /dev/sdX

테스트를 수행하여 성능 문제가 해결되는지 확인할 수 있습니다.


1
ext3 / 4에서 저널을 비활성화하는 것은주의 깊게 고려하고 그 영향을 잘 이해하지 않고는 수행 할 것이 아닙니다.
ThatGraemeGuy

2
동의하지 않습니다. DBMS는 자체 로깅 및 복구를 수행하여 트랜잭션의 내구성과 원 자성을 제공합니다. FS 저널은 그 점에서 완전히 쓸모가 없습니다. fsync가 제대로 작동하면 커밋 된 트랜잭션의 영향을 항상 복원 할 수 있습니다.
Caetano Sauer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.