我们在 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 的时间完成。
在我自己的电脑上运行相同的基准测试,速度要慢得多,BEGIN 和 INSERT 语句的平均值相同,但平均 COMMIT 约为 0.4 毫秒(快 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
在我自己的电脑上我得到:
$ ./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。
更多信息:
- 操作系统:Ubuntu 服务器 12.10
- 内核:Linux ... 3.5.0-22-generic #34-Ubuntu SMP 2013 年 1 月 8 日星期二 21:47:00 UTC x86_64 x86_64 x86_64 GNU/Linux
- 软件 RAID 1
- 文件系统是 ext4
- 未指定其他安装选项。
- Postgres 版本 9.1
- Linux 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 --detail 输出:
/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
mount -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 模式。
答案1
服务器的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 的成本并不会很高。
答案2
这是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)整除。对于好的 4096B 对齐,能被 4 整除就足够了,但对齐感知实用程序会从 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 是否设置为使用 AHCI 模式而不是 IDE 模式。服务器将受益于本机命令队列,这在 IDE 模式下不可用。
忽略与 SSD 的比较。比较起来很荒谬。
答案3
我知道我可能回答这个问题太晚了。在使用 O_DIRECT 时,我发现 PostgreSQL 和 MySQL 存在类似的性能问题。我使用 iozone 对系统进行了微基准测试,使用同步写入(-+r 选项)以及使用和不使用 O_DIRECT(-I 选项)。以下是我使用的两个命令:
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/秒,使用第二个时,我获得大约 220MB/秒(SSD 驱动器)。我发现 ext4 上的 has_journal 选项似乎导致了问题。真的不知道为什么...
Filesystem features: has_journal
在我取消此选项后,一切开始正常运转,两项测试均达到并维持 220MB/秒。要取消此选项,您可以使用以下方法:
tune2fs -O ^has_journal /dev/sdX
您可以进行测试,看看它是否能解决您的性能问题。