在 PostgreSQL 基准测试中最小化 I/O

问题描述 投票:0回答:1

我正在使用 PostgreSQL 进行一些实验,这一切都是为了了解 Postgres 在底层如何工作,并且我正在测试的内容没有生产价值。我只是摆弄系统。

我有两台机器,一台客户端和一台服务器,我使用 benchbase 进行 TPCC 基准测试。 我做了一些配置,基本上将磁盘使用量归零,但我看到后端使用

iotop
iostat
的磁盘使用量。另外
inotifywait
正在报告磁盘上有大量已修改的文件。

我的目标是最大化CPU使用率并最小化IO。显然,如果不实现后者,我就无法实现前者。

我将更详细地描述我的问题:

我在 DDL 中使用

CREATE UNLOGGED TABLE
来最小化 WAL 写入。 数据目录差不多10GB(100个TPCC仓库,虽然我之前实验过1000个大的数字,最终结果没有任何区别),全部都在
base
目录下。
pg_wal
实验开始时是空的,这是预料之中的。

我正在使用

READ COMMITTED
隔离级别运行,以最大限度地减少事务序列化开销。

我设置这些配置以确保所有内容都适合内存: (对后来偶然发现这个问题的人的免责声明:这些配置根本不适合生产中的真实数据库系统)

shared_buffers = 128GB 
checkpoint_timeout = 1d
synchronous_commit = off
work_mem = 6MB
max_wal_senders = 0
wal_level = minimal 
full_page_writes = off 
fsync = off
autovacuum = off 
bgwriter_flush_after = 0        # measured in pages, 0 disables

作为第一个工作负载,我仅使用仅具有

SELECT
查询的 TPCC 查询。没有写。 所有核心的 CPU 利用率非常接近 100%(使用 150 个终端(后端))。 磁盘利用率为 0%,并且
inotifywait
仅报告对
pg_stat
文件的写入次数可以忽略不计。

另一方面,如果我运行原始 TPCC 工作负载,其中大多数查询要么是

INSERT
s 要么
UPDATE
s 要么
DELETE
s,结果会大不相同。

CPU 利用率不会超过 40%,除了少数核心显示在 60% 左右,这是分辨率为 2 秒的磁盘利用率: Disk Util Plot

有趣的是,之后的数据目录中有一个225MB的

pg_wal
目录。 我将日志放入
FlushBuffer
中的
bufmgr.c
函数中,并且没有人将脏缓冲区写入磁盘。至少在我停止服务器之前我看不到这些日志。

我使用了

pg_stats
,这是
pg_stat_wal
的输出: pg_stat_wal output screenshot (我还进行了实验,其中
track_activities
完全关闭以消除开销)

看起来,罪魁祸首是 WAL。但为什么?桌子是

UNLOGGED
。谁在写这个?我在缓冲区管理器实现中缺少什么?

我尝试了上面提到的配置的不同组合,但我确信我缺少 Postgres 专业人士可以提供帮助的东西。

谢谢!

postgresql buffer wal
1个回答
0
投票

每次事务提交都会将一条COMMIT记录写入WAL流中;即使事务中涉及的每个表都未记录。在您的情况下,该记录的写出应该是异步的(由于多种原因,表被取消记录,加上 synchronous_commit 关闭,加上 fsync 关闭),但它仍然存在。

但是你没有证据表明这是瓶颈。你的推理似乎是“CPU <100%, and IO is happening, so it must be the fault of IO", but that is not valid. The bottleneck could be IPC overhead, lock contention, spinlock contention, etc. Just because IO is not nonexistent doesn't mean that it is the cause of the bottleneck.

如果您查看

top
输出,应该有一行类似这样的内容:

%Cpu(s): 19.2 us, 64.0 sy,  0.0 ni,  2.3 id,  0.6 wa,  0.0 hi, 13.9 si,  0.0 st

在这种情况下,即使发生大量 IO,事情也只花费 0.6% 的时间等待它——它大部分发生在后台。他们大部分时间都花在等待系统上,我认为这主要是由上下文切换驱动的,而不是直接由 IO 驱动(尽管 IO 是可能导致上下文切换的因素之一)。

如果你想对此进行快速而肮脏的测试,你可以将数据库或只是 pg_wal 放在 RAM 磁盘上,例如 /dev/shm,然后看看事情如何改变或不改变。

此外,150 个后端似乎有些过大,除非每个后端的工作负载中都内置了一些“思考时间”。为了获得最大的 CPU 使用率,有必要有这么多吗?

© www.soinside.com 2019 - 2024. All rights reserved.