我有一个繁重的 postgres 查询。它需要十多分钟才能运行。我想升级我的硬件以使其运行得更快。我认为更多的 RAM 会有所帮助,但我的主板已经满了,所以我需要一个全新的主板。除非我知道我会得到更好的结果,否则我不想投资。这是我在 iotop 中看到的内容:
总磁盘读取速度:46.81 M/s | 总磁盘写入速度:0.00 B/s TID PRIO 用户磁盘读取磁盘写入 SWAPIN IO> 命令 27 be/4 根 0.00 B/秒 0.00 B/秒 0.00 % 99.99 % [kswapd0] 2514 be/4 postgres 46.81 M/s 2.45 M/s 0.00 % 18.36 % postgres:postgres db1 127.0.0.1(55328) 选择 1 be/4 根 0.00 B/s 0.00 B/s 0.00 % 0.00 % 初始化 2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd] 3 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [ksoftirqd/0] 4 be/4 root 0.00 B/秒 0.00 B/秒 0.00 % 0.00 % [kworker/0:0] 5 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kworker/u:0] 6 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [迁移/0] 7 rt/4 根 0.00 B/s 0.00 B/s 0.00 % 0.00 % [看门狗/0] 8 rt/4 根 0.00 B/s 0.00 B/s 0.00 % 0.00 % [迁移/1] 9 be/4 根 0.00 B/秒 0.00 B/秒 0.00 % 0.00 % [kworker/1:0] 10 be/4 根 0.00 B/s 0.00 B/s 0.00 % 0.00 % [ksoftirqd/1]
注意 kswapd0 对硬盘的访问最多(99.99% IO)。但是,kswap0 的 DISK READ、DISK WRITE 和 SWAPIN 均为零。kswap0 在做什么?它真的在访问我的硬盘吗?给这个系统添加更多 RAM 会有帮助吗?
答案1
你从错误的角度来处理这个问题。只有在优化 SQL 之后,你才应该考虑投入更多的 RAM/CPU/磁盘(I/O 带宽)来解决问题——并按照你发现的方式解决问题。
首先询问 Postgres EXPLAIN
(或EXPLAIN ANALYZE
)它如何执行查询。
优化其中的猫咪,然后如果仍然有性能问题,进一步调查以确定瓶颈在哪里(sonassi 还给你提供了一些很好的建议,除了iotop
)。
如果您在同一台服务器上运行 Web 堆栈和 DB,那么现在也是将它们拆分的好时机……
答案2
您没有提及任何其他有助于诊断的重要信息。
free -m
cat /proc/meminfo
top -b
很可能来自的 I/Okswapd
只是从的 I/O 伪报告的postgres
。其中一个进程可能处于状态D
,但来自上述命令的所有数据都可以确认。尽管令人好奇的是它swapin
是空的。
答案3
您是否 110% 确定您的 IO-sub 系统没有问题 - 例如所有硬盘都正常 [智能 / RAID 自我检测],写回缓存已启用 [如果您的 RAID 卡上有电池支持的缓存]?
postgres 不是通过 48MB/s 的读取传输来饱和 IO 吗?
答案4
kswapd 正在执行处理 Linux 上的虚拟内存所需的部分工作。因此,如果 kswapd 的占用率为 100%,则可能表明它正在执行过多的工作,尽管也可能是因为您的 PG 进程占用了太多资源(例如,没有剩余 RAM 用于缓冲区 IO)。
我将通过常用工具检查已使用/未使用的内存量。
关于除了 kswapd0 的 IO 列之外缺少统计数据,我不确定以下解释是否正确,但可能是内核无法在内核空间(kswapd 所在的位置)中跟踪 swapin/swapout,因为 Linux 根本不会将任何东西换出内核空间中分配的页面。