PostgreSQLの設定で問題が発生しています。いくつかのベンチマークの後で、非常に単純なクエリに比較的長い時間がかかることがわかりました。さらに詳しく調べたところ、実際のCOMMITコマンドは本当に遅いようです。
次の表を使用して、非常に簡単なテストを実行しました。
CREATE TABLE test (
id serial primary key,
foo varchar(16),
);
すべてのステートメントのロギングをオンにした後、次のクエリを10000回実行しました。
BEGIN;
INSERT INTO test (a) VALUES ('bar');
COMMIT;
BEGINとINSERTの完了には1ミリ秒未満かかりますが、COMMITの完了には平均22ミリ秒かかります。
自分の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ディスク(RAIDなし)のi5です。
より詳しい情報:
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年3月25日更新:両方のディスクで長いスマートテストを実行しましたが、問題はありませんでした。どちらのディスクもSeagate製で、モデルはST3000DM001-9YN166です。
2013年3月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デバイスがテストに使用されています。 swapパーティションを破棄して、個々のディスクで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モードです。
サーバーのfsync
パフォーマンスは信じられないほど、言葉では言い表せないほど、驚くほど遅いです。ソフトウェアRAID 1のセットアップに非常に大きな問題があります。ひどいfsync
パフォーマンスは、ほぼ間違いなくパフォーマンスの問題の原因です。
デスクトップのfsync
が非常に遅いだけです。
synchronous_commit = off
を設定し、commit_delay
を設定することで、クラッシュ後に一部のデータが失われる代わりに、パフォーマンスの問題を回避できます。あなたは本当にサーバーのディスクパフォーマンスを整理する必要がありますが、それは非常に遅いです。
比較のために、これが私のラップトップで得られるものです(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はかなりのコストがかかるとは言えません。
これは私のサーバーでのpg_test_fsync
の出力で、非常によく似た構成で、2つのコンシューマーグレードのディスク上のLinuxソフトウェアRAID1(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
...
完全にアイドル状態のサーバーでこれをテストしましたか?
多分あなたは整列されていないパーティションを持っています。小切手:
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)
ディスクの1つが壊れている可能性があります。 RAIDなしで各ディスクに1つのパーティションを作成します(両方のディスクでいくつかのスワップパーティションを予約した可能性があります-これらを使用してください-とにかくスワップ上のRAIDは使用できません)。そこでファイルシステムを作成し、各ドライブでpg_test_fsync
を実行します。問題が発生した場合、両方がミラーリングされているときは、それを待つ必要があります。
BIOSがIDEモードの代わりにAHCIモードを使用するように設定されていることを確認してください。サーバーは ネイティブコマンドキューイング の恩恵を受けます。これはIDEモード。
SSDとの比較を無視します。比較するのはばかげています。
私はこれに答えるには遅すぎるかもしれないことを知っています。 O_DIRECTを使用すると、PostgreSQLとMySQLで同様のパフォーマンスの問題が発生しました。同期書き込み(-+ rオプション)あり、O_DIRECTあり/なし(-Iオプション)のiozoneを使用して、システムをマイクロベンチマークしました。以下は、私が使用した2つのコマンドです。
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ですが、2番目はO_SYNCのみです。 1つ目は約30MB /秒、2つ目は約220MB /秒(SSDドライブ)でした。私が見つけたのは、ext4シームのhas_journalオプションが問題の原因であることです。なぜか本当にわからない...
Filesystem features: has_journal
このオプションを削除すると、テストは正常に機能し始め、テストは220MB /秒に達し、それを維持しました。オプションを削除するには、次のようなものを使用できます。
tune2fs -O ^has_journal /dev/sdX
これをテストして、パフォーマンスの問題が解決するかどうかを確認できます。