惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Project Zero
Project Zero
GbyAI
GbyAI
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
小众软件
小众软件
The GitHub Blog
The GitHub Blog
阮一峰的网络日志
阮一峰的网络日志
J
Java Code Geeks
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
IT之家
IT之家
F
Fortinet All Blogs
博客园 - 【当耐特】
H
Hackread – Cybersecurity News, Data Breaches, AI and More
P
Proofpoint News Feed
Schneier on Security
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
Spread Privacy
Spread Privacy
O
OpenAI News
V
V2EX
博客园 - 三生石上(FineUI控件)
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Stack Overflow Blog
Stack Overflow Blog
P
Privacy International News Feed
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
H
Help Net Security
L
LINUX DO - 最新话题
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tenable Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cisco Talos Blog
Cisco Talos Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 叶小钗
V
Vulnerabilities – Threatpost
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
酷 壳 – CoolShell
酷 壳 – CoolShell
Hacker News: Ask HN
Hacker News: Ask HN
S
Security @ Cisco Blogs
S
Securelist
T
The Blog of Author Tim Ferriss
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
雷峰网
雷峰网
V2EX - 技术
V2EX - 技术

博客园 - MSSQL123

PostgreSQL 18 新特性 skip scan,一个鸡肋的功能 PostgreSQL 17 流复制中开启逻辑复制槽同步,以及逻辑槽的故障转移 记一次PostgreSQL交叉表crosstab行转列导致的OOM TiDB 扩容与缩容 PostgreSQL 高可用集群 patroni 自动故障转移测试 Ubuntu 20 环境下 patroni 自动化安装,一分钟快速搭建 patroni 集群 Ubuntu 20 环境下 pg_auto_failover 自动化安装,一分钟快速搭建pg_auto_failover集群 PostgreSQL的消息队列扩展pgmq 磁盘IO延迟和队列深度的关系 TiDB 最小拓扑架构集群安装 PostgreSQL 逻辑复制中的同步和异步模式以及其表现 prometheus 的 altermanager Silences静默告警,优雅地抑制告警 “世界上百分之99的博士和他们的论文都是垃圾”,原本以为这个观点偏激 pg_auto_failover 在多种场景下自动故障转移的验证 pgbouncer连接池设置与压力测试的最大连接数测试 pg_auto_failover 自动故障转移参数 博文阅读密码验证 - 博客园 pg_auto_failover 高可用中,PostgreSQL实例配置文件的加载步骤 pg_auto_failover集群monitor节点的高可用 prometheus监控Linux Server node_exporter代理安装和配置 prometheus监控windows window_exporter代理安装和配置 Prometheus 和 Grafana 监控 PostgreSQL 记一次MySQL binlog日志导致磁盘空间占满的问题 SQLServer 2019 标准版在虚拟机上无法充分利用CPU的问题诊断 Windows Failover Cluster集群中的EventId 1196错误日志 pg_auto_failover 环境变量导致的show命令错误 SqlServer 事务复制(transaction replication)的复制位点信息 SqlServer 事务复制的两个参数immediate_sync,allow_anonymous MySQL,SqlServer,PostgreSQL中,如何实现锁定一张表 PostgreSQL pg_auto_failover 高可用 2:pg_auto_failover集群运维 PostgreSQL pg_auto_failover 高可用 1:pg_auto_failover集群搭建 PostgreSQL patroni 高可用 4:HAProxy和Keepalived实现读写分离 PostgreSQL patroni 高可用 3:patroni 运维
ubuntu24下 ext4和xfs类型磁盘以及PostgreSQL实例性能对比测试
MSSQL123 · 2026-07-17 · via 博客园 - MSSQL123

ext和xfs文件系统

ext是Linux原生的文件系统,版本依次从ext2迭代到ext4,xfs文件系统在90年代以商业化的形式出现,2009年之后才移植到Linux平台,从特征上来说,ext以轻量稳定为核心,xfs以大容量高性能为核心,xfs是否一定优于ext4,本文就该问题进行一个简单的测试验证。

本文的重点在于对比笔者自己常用的场景下,ext4和xfs在“相同条件下”的性能表现,而非测试硬件或者软件自身的极限性能。

fio IO压力测试工具

fio是Linux下的一个IO压力测试工具,可以生成自定义 IO 负载,模拟业务读写模型,测量存储性能,创建多个线程 / 进程,按照配置持续发起 IO 请求;统计 带宽 (BW)、IOPS、延迟分布、队列利用率 util等一系列跟性能相关的指标。

fio 磁盘压力测试

本文测试环境为ubuntu 24操作系统的虚拟机,物理磁盘是STAT类型的SSD,虚拟机的配置为4C+8G的配置,如下,分别挂载ext4和xfs两块文件类型的磁盘,用以做IO压力对比测试。

root@ubuntu30:/home/ubuntu# lsblk -f
NAME   FSTYPE  FSVER            LABEL                           UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1
├─sda2 ext4    1.0                                              f24e6ace-4e10-407d-9da0-300792128569  802.2M    11% /boot
└─sda3 xfs                                                      14609fa0-73be-4194-a72c-1672aa73e953   41.3G    30% /
sdb    ext4    1.0                                              be8519af-ce4a-4860-83a7-429b864fe1d1   45.7G    17% /usr/data
sr0    iso9660 Joliet Extension Ubuntu-Server 24.04.3 LTS amd64 2025-08-05-23-54-07-00
root@ubuntu30:/home/ubuntu#
root@ubuntu30:/home/ubuntu#

对于磁盘的测试,这里使用fio命令,用随机读加写,70%的读操作,30%的写操作,队列深度为32的测试方式

### ext4磁盘分区
fio -name=randrw-8k -ioengine=libaio -direct=1 -rw=randrw -rwmixread=70 -bs=8k -size=10G -numjobs=4 -runtime=120 --time_based -iodepth=32 -filename=/fio.test

### xfs磁盘分区
fio -name=randrw-8k -ioengine=libaio -direct=1 -rw=randrw -rwmixread=70 -bs=8k -size=10G -numjobs=4 -runtime=120 --time_based -iodepth=32 -filename=/usr/data/fio.test

一次典型的fio测试如下

fio测试结果
root@ubuntu30:/home/ubuntu# fio -name=randrw-8k -ioengine=libaio -direct=1 -rw=randrw -rwmixread=70 -bs=8k -size=10G -numjobs=4 -runtime=120 --time_based -iodepth=32 -filename=/usr/data/fio.test
randrw-8k: (g=0): rw=randrw, bs=(R) 8192B-8192B, (W) 8192B-8192B, (T) 8192B-8192B, ioengine=libaio, iodepth=32
...
fio-3.36
Starting 4 processes
Jobs: 4 (f=4): [m(4)][100.0%][r=87.9MiB/s,w=38.3MiB/s][r=11.3k,w=4899 IOPS][eta 00m:00s]
randrw-8k: (groupid=0, jobs=1): err= 0: pid=1547: Wed Jul 15 08:01:29 2026
  read: IOPS=3390, BW=26.5MiB/s (27.8MB/s)(3179MiB/120009msec)
    slat (nsec): min=1428, max=169935k, avg=69690.46, stdev=670894.67
    clat (usec): min=2, max=204221, avg=6218.01, stdev=6328.43
     lat (usec): min=58, max=204756, avg=6287.70, stdev=6357.47
    clat percentiles (usec):
     |  1.00th=[   453],  5.00th=[   857], 10.00th=[  1205], 20.00th=[  1827],
     | 30.00th=[  2507], 40.00th=[  3359], 50.00th=[  4424], 60.00th=[  5735],
     | 70.00th=[  7242], 80.00th=[  9372], 90.00th=[ 13173], 95.00th=[ 17171],
     | 99.00th=[ 29230], 99.50th=[ 36963], 99.90th=[ 57934], 99.95th=[ 71828],
     | 99.99th=[109577]
   bw (  KiB/s): min=11328, max=48176, per=25.01%, avg=27111.31, stdev=6098.33, samples=238
   iops        : min= 1416, max= 6022, avg=3388.67, stdev=762.29, samples=238
  write: IOPS=1456, BW=11.4MiB/s (11.9MB/s)(1365MiB/120009msec); 0 zone resets
    slat (nsec): min=1559, max=57787k, avg=72491.01, stdev=582537.80
    clat (nsec): min=1158, max=204767k, avg=7252447.95, stdev=7918867.24
     lat (usec): min=78, max=204771, avg=7324.94, stdev=7932.98
    clat percentiles (usec):
     |  1.00th=[   441],  5.00th=[   832], 10.00th=[  1221], 20.00th=[  1942],
     | 30.00th=[  2737], 40.00th=[  3687], 50.00th=[  4883], 60.00th=[  6456],
     | 70.00th=[  8356], 80.00th=[ 10945], 90.00th=[ 15664], 95.00th=[ 20841],
     | 99.00th=[ 36963], 99.50th=[ 45876], 99.90th=[ 72877], 99.95th=[ 86508],
     | 99.99th=[126354]
   bw (  KiB/s): min= 4624, max=21008, per=24.98%, avg=11646.62, stdev=2694.12, samples=238
   iops        : min=  578, max= 2626, avg=1455.59, stdev=336.76, samples=238
  lat (usec)   : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.02%
  lat (usec)   : 100=0.05%, 250=0.20%, 500=1.07%, 750=2.42%, 1000=3.30%
  lat (msec)   : 2=15.01%, 4=23.20%, 10=35.21%, 20=15.62%, 50=3.67%
  lat (msec)   : 100=0.21%, 250=0.02%
  cpu          : usr=1.28%, sys=28.10%, ctx=208596, majf=0, minf=17
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=406867,174750,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32
randrw-8k: (groupid=0, jobs=1): err= 0: pid=1548: Wed Jul 15 08:01:29 2026
  read: IOPS=3387, BW=26.5MiB/s (27.7MB/s)(3176MiB/120009msec)
    slat (nsec): min=1454, max=152785k, avg=69838.54, stdev=700426.96
    clat (nsec): min=1947, max=175067k, avg=6208002.91, stdev=6417046.59
     lat (usec): min=70, max=175070, avg=6277.84, stdev=6444.81
    clat percentiles (usec):
     |  1.00th=[   461],  5.00th=[   873], 10.00th=[  1221], 20.00th=[  1844],
     | 30.00th=[  2540], 40.00th=[  3359], 50.00th=[  4424], 60.00th=[  5669],
     | 70.00th=[  7242], 80.00th=[  9372], 90.00th=[ 13042], 95.00th=[ 16909],
     | 99.00th=[ 29230], 99.50th=[ 36963], 99.90th=[ 62129], 99.95th=[ 79168],
     | 99.99th=[132645]
   bw (  KiB/s): min=10506, max=47075, per=24.99%, avg=27087.85, stdev=6101.88, samples=238
   iops        : min= 1313, max= 5884, avg=3385.75, stdev=762.74, samples=238
  write: IOPS=1460, BW=11.4MiB/s (12.0MB/s)(1369MiB/120009msec); 0 zone resets
    slat (nsec): min=1569, max=69377k, avg=73472.05, stdev=628177.68
    clat (usec): min=11, max=165134, avg=7268.70, stdev=7838.10
     lat (usec): min=90, max=165139, avg=7342.17, stdev=7852.69
    clat percentiles (usec):
     |  1.00th=[   449],  5.00th=[   848], 10.00th=[  1237], 20.00th=[  1975],
     | 30.00th=[  2769], 40.00th=[  3752], 50.00th=[  5014], 60.00th=[  6521],
     | 70.00th=[  8356], 80.00th=[ 11076], 90.00th=[ 15664], 95.00th=[ 20841],
     | 99.00th=[ 36439], 99.50th=[ 45876], 99.90th=[ 72877], 99.95th=[ 88605],
     | 99.99th=[145753]
   bw (  KiB/s): min= 4614, max=20254, per=25.05%, avg=11677.46, stdev=2682.05, samples=238
   iops        : min=  576, max= 2531, avg=1459.43, stdev=335.24, samples=238
  lat (usec)   : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.02%
  lat (usec)   : 100=0.05%, 250=0.18%, 500=1.04%, 750=2.33%, 1000=3.21%
  lat (msec)   : 2=14.97%, 4=23.24%, 10=35.57%, 20=15.54%, 50=3.59%
  lat (msec)   : 100=0.23%, 250=0.02%
  cpu          : usr=1.22%, sys=28.38%, ctx=207948, majf=0, minf=17
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=406499,175255,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32
randrw-8k: (groupid=0, jobs=1): err= 0: pid=1549: Wed Jul 15 08:01:29 2026
  read: IOPS=3417, BW=26.7MiB/s (28.0MB/s)(3204MiB/120008msec)
    slat (nsec): min=1460, max=120727k, avg=67489.07, stdev=586036.62
    clat (usec): min=2, max=161462, avg=6152.00, stdev=6311.85
     lat (usec): min=83, max=161465, avg=6219.49, stdev=6333.94
    clat percentiles (usec):
     |  1.00th=[   461],  5.00th=[   873], 10.00th=[  1205], 20.00th=[  1844],
     | 30.00th=[  2507], 40.00th=[  3326], 50.00th=[  4359], 60.00th=[  5669],
     | 70.00th=[  7177], 80.00th=[  9372], 90.00th=[ 12911], 95.00th=[ 16909],
     | 99.00th=[ 28705], 99.50th=[ 35914], 99.90th=[ 59507], 99.95th=[ 74974],
     | 99.99th=[135267]
   bw (  KiB/s): min= 9992, max=51424, per=25.20%, avg=27315.33, stdev=6352.85, samples=238
   iops        : min= 1249, max= 6428, avg=3414.19, stdev=794.11, samples=238
  write: IOPS=1465, BW=11.5MiB/s (12.0MB/s)(1374MiB/120008msec); 0 zone resets
    slat (nsec): min=1596, max=72174k, avg=73942.54, stdev=643502.98
    clat (nsec): min=1791, max=152333k, avg=7247229.63, stdev=7872188.82
     lat (usec): min=105, max=152336, avg=7321.17, stdev=7896.87
    clat percentiles (usec):
     |  1.00th=[   445],  5.00th=[   857], 10.00th=[  1254], 20.00th=[  1975],
     | 30.00th=[  2769], 40.00th=[  3720], 50.00th=[  4948], 60.00th=[  6456],
     | 70.00th=[  8356], 80.00th=[ 10945], 90.00th=[ 15533], 95.00th=[ 20841],
     | 99.00th=[ 35914], 99.50th=[ 44827], 99.90th=[ 76022], 99.95th=[102237],
     | 99.99th=[141558]
   bw (  KiB/s): min= 4318, max=20733, per=25.14%, avg=11719.82, stdev=2678.11, samples=238
   iops        : min=  539, max= 2591, avg=1464.76, stdev=334.77, samples=238
  lat (usec)   : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.02%
  lat (usec)   : 100=0.04%, 250=0.19%, 500=1.03%, 750=2.33%, 1000=3.21%
  lat (msec)   : 2=15.01%, 4=23.56%, 10=35.39%, 20=15.45%, 50=3.55%
  lat (msec)   : 100=0.18%, 250=0.03%
  cpu          : usr=1.28%, sys=27.71%, ctx=208372, majf=0, minf=17
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=410091,175924,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32
randrw-8k: (groupid=0, jobs=1): err= 0: pid=1550: Wed Jul 15 08:01:29 2026
  read: IOPS=3355, BW=26.2MiB/s (27.5MB/s)(3146MiB/120008msec)
    slat (nsec): min=1458, max=64036k, avg=69779.03, stdev=556041.90
    clat (nsec): min=1061, max=146162k, avg=6257973.28, stdev=6147059.49
     lat (usec): min=84, max=146170, avg=6327.75, stdev=6160.76
    clat percentiles (usec):
     |  1.00th=[  465],  5.00th=[  889], 10.00th=[ 1237], 20.00th=[ 1893],
     | 30.00th=[ 2606], 40.00th=[ 3458], 50.00th=[ 4490], 60.00th=[ 5735],
     | 70.00th=[ 7308], 80.00th=[ 9503], 90.00th=[13173], 95.00th=[17171],
     | 99.00th=[29492], 99.50th=[36439], 99.90th=[53740], 99.95th=[63177],
     | 99.99th=[92799]
   bw (  KiB/s): min=11344, max=42874, per=24.80%, avg=26885.74, stdev=5860.63, samples=238
   iops        : min= 1418, max= 5359, avg=3360.49, stdev=732.59, samples=238
  write: IOPS=1444, BW=11.3MiB/s (11.8MB/s)(1355MiB/120008msec); 0 zone resets
    slat (nsec): min=1558, max=59757k, avg=74464.14, stdev=577719.22
    clat (usec): min=2, max=190257, avg=7366.86, stdev=7702.63
     lat (usec): min=78, max=190259, avg=7441.33, stdev=7721.18
    clat percentiles (usec):
     |  1.00th=[   449],  5.00th=[   873], 10.00th=[  1287], 20.00th=[  2040],
     | 30.00th=[  2835], 40.00th=[  3851], 50.00th=[  5080], 60.00th=[  6587],
     | 70.00th=[  8455], 80.00th=[ 11207], 90.00th=[ 15795], 95.00th=[ 21103],
     | 99.00th=[ 36963], 99.50th=[ 45351], 99.90th=[ 69731], 99.95th=[ 76022],
     | 99.99th=[115868]
   bw (  KiB/s): min= 5360, max=19120, per=24.84%, avg=11578.18, stdev=2567.29, samples=238
   iops        : min=  670, max= 2390, avg=1447.01, stdev=320.91, samples=238
  lat (usec)   : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.02%
  lat (usec)   : 100=0.05%, 250=0.19%, 500=0.98%, 750=2.23%, 1000=3.04%
  lat (msec)   : 2=14.43%, 4=23.33%, 10=35.97%, 20=15.80%, 50=3.75%
  lat (msec)   : 100=0.20%, 250=0.01%
  cpu          : usr=1.22%, sys=28.24%, ctx=201096, majf=0, minf=17
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=402719,173382,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32

Run status group 0 (all jobs):
   READ: bw=106MiB/s (111MB/s), 26.2MiB/s-26.7MiB/s (27.5MB/s-28.0MB/s), io=12.4GiB (13.3GB), run=120008-120009msec
  WRITE: bw=45.5MiB/s (47.7MB/s), 11.3MiB/s-11.5MiB/s (11.8MB/s-12.0MB/s), io=5463MiB (5729MB), run=120008-120009msec

Disk stats (read/write):
  sdb: ios=1625786/699203, sectors=26014920/11187536, merge=146/54, ticks=8435438/4194989, in_queue=12630428, util=100.00%
root@ubuntu30:/home/ubuntu#
root@ubuntu30:/home/ubuntu#
root@ubuntu30:/home/ubuntu#

这里采用shell循环交替测试的方式,对于ext4和xfs分别测试10次,最终把测试结果丢给AI,让AI帮助汇总测试结果并生成相关图例

#!/bin/bash

# ============================================
# fio 自动化测试
# EXT4 / XFS 各 10 次
# ============================================

EXT4_FILE="/fio.test"
XFS_FILE="/usr/data/fio.test"
RESULT_DIR="./"

EXT4_LOG="${RESULT_DIR}/ext4_results.log"
XFS_LOG="${RESULT_DIR}/xfs_results.log"
SUMMARY_LOG="${RESULT_DIR}/summary.log"

RUNTIME="120"
NUM_JOBS="4"
IODEPTH="32"
BS="8k"
SIZE="10G"
RWMIXREAD="70"

mkdir -p "${RESULT_DIR}"

# 初始化 summary
if [ ! -f "${SUMMARY_LOG}" ]; then
    echo "========================================" > "${SUMMARY_LOG}"
    echo "fio benchmark (EN locale)" >> "${SUMMARY_LOG}"
    echo "Start: $(date '+%Y-%m-%d %H:%M:%S')" >> "${SUMMARY_LOG}"
    echo "========================================" >> "${SUMMARY_LOG}"
fi

for i in $(seq 1 10); do
    echo ""
    echo ">>>> Round ${i} start: $(date '+%H:%M:%S')"
    echo "===== Round ${i} | $(date '+%Y-%m-%d %H:%M:%S') =====" >> "${EXT4_LOG}"
    echo "===== Round ${i} | $(date '+%Y-%m-%d %H:%M:%S') =====" >> "${XFS_LOG}"

    # ---------- EXT4 ----------
    echo "  -> Running EXT4..."
    LC_ALL=C fio \
        -name=randrw-8k \
        -ioengine=libaio \
        -direct=1 \
        -rw=randrw \
        -rwmixread=${RWMIXREAD} \
        -bs=${BS} \
        -size=${SIZE} \
        -numjobs=${NUM_JOBS} \
        -runtime=${RUNTIME} \
        --time_based \
        -iodepth=${IODEPTH} \
        -filename=${EXT4_FILE} \
        >> "${EXT4_LOG}" 2>&1

    echo "  -> EXT4 done"

    sleep 5

    # ---------- XFS ----------
    echo "  -> Running XFS..."
    LC_ALL=C fio \
        -name=randrw-8k \
        -ioengine=libaio \
        -direct=1 \
        -rw=randrw \
        -rwmixread=${RWMIXREAD} \
        -bs=${BS} \
        -size=${SIZE} \
        -numjobs=${NUM_JOBS} \
        -runtime=${RUNTIME} \
        --time_based \
        -iodepth=${IODEPTH} \
        -filename=${XFS_FILE} \
        >> "${XFS_LOG}" 2>&1

    echo "  -> XFS done"

    echo "Round ${i}: EXT4=$(date '+%H:%M:%S') | XFS=$(date '+%H:%M:%S')" >> "${SUMMARY_LOG}"
    echo "" >> "${EXT4_LOG}"
    echo "" >> "${XFS_LOG}"

    if [ ${i} -lt 10 ]; then
        echo "  -> Sleep 5s..."
        sleep 5
    fi
done

echo "========================================" >> "${SUMMARY_LOG}"
echo "Finished: $(date '+%Y-%m-%d %H:%M:%S')" >> "${SUMMARY_LOG}"
echo "========================================" >> "${SUMMARY_LOG}"

echo ""
echo "All tests finished"
echo "EXT4 log: ${EXT4_LOG}"
echo "XFS  log: ${XFS_LOG}"

fio 测试结果

这里重点绘制出来两个核心技术指标IOPS和读写IO延迟比,从中可以发现

1,IOPS这一指标,分别为read IOPS和write IOPS,整体上看两者没有明显的差异,相差不到1%,但是ext4相对xfs来说波动更小
2,对于read clat 95以及clat 99的percentiles指标,两者几乎一致,相差同样小于1%

以下图例数据来自于shell脚本的生成的fio测试结果的汇总,图例由AI根据测试结果整理生成

image

image

image

基于ext4和xfs类型磁盘的PostgreSQL压力测试

PostgreSQL安装

这里安装了2个实例,分别是postgresql9800和postgresql9900,两个实例的数据文件分别位于ext4和xfs所在的磁盘分区,两个postgresql实例配置完全一致,其中share_buffer配置为1G。

root@ubuntu30:/usr/local/pg_install# systemctl status postgresql9800
● postgresql9800.service - PostgreSQL database server
     Loaded: loaded (/etc/systemd/system/postgresql9800.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-07-16 04:54:33 UTC; 1h 12min ago
    Process: 36462 ExecStart=/usr/local/pgsql18/server/bin/pg_ctl start -D ${PGDATA} -s -w -t ${PGSTARTTIMEOUT} (code=exited, status=0/SUCCESS)
   Main PID: 36465 (postgres)
      Tasks: 10 (limit: 9374)
     Memory: 6.1G (peak: 6.8G swap: 680.0K swap peak: 680.0K)
        CPU: 10min 47.010s
     CGroup: /system.slice/postgresql9800.service
             ├─36465 /usr/local/pgsql18/server/bin/postgres -D /usr/local/pgsql18/pg9800/data
             ├─36466 "postgres: logger "
             ├─36467 "postgres: io worker 0"
             ├─36468 "postgres: io worker 1"
             ├─36469 "postgres: io worker 2"
             ├─36470 "postgres: checkpointer "
             ├─36471 "postgres: background writer "
             ├─36473 "postgres: walwriter "
             ├─36474 "postgres: autovacuum launcher "
             └─36475 "postgres: logical replication launcher "

Jul 16 04:54:33 ubuntu30 systemd[1]: Starting postgresql9800.service - PostgreSQL database server...
Jul 16 04:54:33 ubuntu30 pg_ctl[36465]: 2026-07-16 04:54:33.406 UTC [36465] LOG:  redirecting log output to logging collector process
Jul 16 04:54:33 ubuntu30 pg_ctl[36465]: 2026-07-16 04:54:33.406 UTC [36465] HINT:  Future log output will appear in directory "/usr/local/pgsql18/pg9800/log".
Jul 16 04:54:33 ubuntu30 systemd[1]: Started postgresql9800.service - PostgreSQL database server.
root@ubuntu30:/usr/local/pg_install# systemctl status postgresql9900
● postgresql9900.service - PostgreSQL database server
     Loaded: loaded (/etc/systemd/system/postgresql9900.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-07-16 06:07:12 UTC; 16s ago
    Process: 37352 ExecStart=/usr/data/pgsql18/server/bin/pg_ctl start -D ${PGDATA} -s -w -t ${PGSTARTTIMEOUT} (code=exited, status=0/SUCCESS)
   Main PID: 37355 (postgres)
      Tasks: 10 (limit: 9374)
     Memory: 57.1M (peak: 57.6M)
        CPU: 82ms
     CGroup: /system.slice/postgresql9900.service
             ├─37355 /usr/data/pgsql18/server/bin/postgres -D /usr/data/pgsql18/pg9900/data
             ├─37356 "postgres: logger "
             ├─37357 "postgres: io worker 0"
             ├─37358 "postgres: io worker 1"
             ├─37359 "postgres: io worker 2"
             ├─37360 "postgres: checkpointer "
             ├─37361 "postgres: background writer "
             ├─37363 "postgres: walwriter "
             ├─37364 "postgres: autovacuum launcher "
             └─37365 "postgres: logical replication launcher "

Jul 16 06:07:12 ubuntu30 systemd[1]: Starting postgresql9900.service - PostgreSQL database server...
Jul 16 06:07:12 ubuntu30 pg_ctl[37355]: 2026-07-16 06:07:12.896 UTC [37355] LOG:  redirecting log output to logging collector process
Jul 16 06:07:12 ubuntu30 pg_ctl[37355]: 2026-07-16 06:07:12.896 UTC [37355] HINT:  Future log output will appear in directory "/usr/data/pgsql18/pg9900/log".
Jul 16 06:07:12 ubuntu30 systemd[1]: Started postgresql9900.service - PostgreSQL database server.
root@ubuntu30:/usr/local/pg_install#

pgbench准备

这里基于pgbench创建一个50000000条数据的测试环境(pgbench -h 127.0.0.1 -p 9800 -U postgres -d pgbench_db  -i -s 500),两个实例的生成的测试数据完全一致。

root@ubuntu30:/usr/local/pg_install# psql -h 127.0.0.1 -p 9800 -U postgres postgres
Password for user postgres:
psql (18.3)
Type "help" for help.

postgres=# create database pgbench_db;
CREATE DATABASE
postgres=# \q
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# pgbench -h 127.0.0.1 -U postgres  -p 9800 pgbench_db -i
Password:
dropping old tables...
NOTICE:  table "pgbench_accounts" does not exist, skipping
NOTICE:  table "pgbench_branches" does not exist, skipping
NOTICE:  table "pgbench_history" does not exist, skipping
NOTICE:  table "pgbench_tellers" does not exist, skipping
creating tables...
generating data (client-side)...
vacuuming...
creating primary keys...
done in 0.25 s (drop tables 0.00 s, create tables 0.00 s, client-side generate 0.10 s, vacuum 0.04 s, primary keys 0.10 s).
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# pgbench -h 127.0.0.1 -p 9800 -U postgres -d pgbench_db  -i -s 500
Password:
dropping old tables...
creating tables...
generating data (client-side)...
vacuuming...
creating primary keys...
done in 169.31 s (drop tables 0.03 s, create tables 0.01 s, client-side generate 100.66 s, vacuum 3.76 s, primary keys 64.86 s).
root@ubuntu30:/usr/local/pg_install#

pgbench压测

利用如下脚本,分别用"2 4 8 16 32 64" 线程数对两个postgresql分别进行压力测试,每个一组测试运行60秒,测试期间会关停另一个实例的服务,防止两个实例之间相互干扰。

HOST=127.0.0.1
PGPORT=9800 
DBNAME=pgbench_db
DBUSER=postgres
export PGPASSWORD=****** 

RUNSEC=60 # 运行时间
THREADS="2 4 8 16 32 64" 线程数
for threadCnt in $THREADS ; do 
    tps=`pgbench -r -T$RUNSEC $DBNAME -U$DBUSER -h $HOST -p $PGPORT -c$threadCnt -j$threadCnt  2>&1 |awk '/tps/{print $3}'`
    echo "concurrent: $threadCnt ,postgres tps: ${tps:-0}" 
done

测试结果

root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9800_test.sh
concurrent: 2 ,postgres tps: 873.224907
concurrent: 4 ,postgres tps: 1150.755581
concurrent: 8 ,postgres tps: 2161.466191
concurrent: 16 ,postgres tps: 3119.279227
concurrent: 32 ,postgres tps: 3055.131493
concurrent: 64 ,postgres tps: 2835.200960
concurrent: 128 ,postgres tps: 2859.829723
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9800_test.sh
concurrent: 2 ,postgres tps: 743.739950
concurrent: 4 ,postgres tps: 1066.351943
concurrent: 8 ,postgres tps: 2234.594472
concurrent: 16 ,postgres tps: 3165.805190
concurrent: 32 ,postgres tps: 3402.018566
concurrent: 64 ,postgres tps: 3046.540664
concurrent: 128 ,postgres tps: 2965.726659
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9800_test.sh
concurrent: 2 ,postgres tps: 761.140493
concurrent: 4 ,postgres tps: 1353.549987
concurrent: 8 ,postgres tps: 2392.809218
concurrent: 16 ,postgres tps: 3337.523674
concurrent: 32 ,postgres tps: 3223.437427
concurrent: 64 ,postgres tps: 3057.000292
concurrent: 128 ,postgres tps: 2956.257316
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9800_test.sh
concurrent: 2 ,postgres tps: 809.081475
concurrent: 4 ,postgres tps: 1218.683222
concurrent: 8 ,postgres tps: 2411.138366
concurrent: 16 ,postgres tps: 3348.417863
concurrent: 32 ,postgres tps: 3420.398202
concurrent: 64 ,postgres tps: 3270.371034
concurrent: 128 ,postgres tps: 3073.792106
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9800_test.sh
concurrent: 2 ,postgres tps: 847.993710
concurrent: 4 ,postgres tps: 1205.544455
concurrent: 8 ,postgres tps: 2299.767415
concurrent: 16 ,postgres tps: 3416.636078
concurrent: 32 ,postgres tps: 3197.307265
concurrent: 64 ,postgres tps: 3231.308020
concurrent: 128 ,postgres tps: 3262.546457
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# systemctl stop postgresql9800
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# systemctl start postgresql9900
root@ubuntu30:/usr/local/pg_install#
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9900_test.sh
concurrent: 2 ,postgres tps: 910.148271
concurrent: 4 ,postgres tps: 945.297788
concurrent: 8 ,postgres tps: 1984.848836
concurrent: 16 ,postgres tps: 3463.093250
concurrent: 32 ,postgres tps: 3415.695770
concurrent: 64 ,postgres tps: 3299.900340
concurrent: 128 ,postgres tps: 3163.273326
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9900_test.sh
concurrent: 2 ,postgres tps: 972.202275
concurrent: 4 ,postgres tps: 1199.432083
concurrent: 8 ,postgres tps: 2331.193031
concurrent: 16 ,postgres tps: 3409.552122
concurrent: 32 ,postgres tps: 3447.767055
concurrent: 64 ,postgres tps: 3356.412922
concurrent: 128 ,postgres tps: 3315.727438
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9900_test.sh
concurrent: 2 ,postgres tps: 878.067693
concurrent: 4 ,postgres tps: 1291.111674
concurrent: 8 ,postgres tps: 2399.937215
concurrent: 16 ,postgres tps: 3561.428644
concurrent: 32 ,postgres tps: 3711.227386
concurrent: 64 ,postgres tps: 3414.528734
concurrent: 128 ,postgres tps: 3197.026801
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9900_test.sh
concurrent: 2 ,postgres tps: 918.756230
concurrent: 4 ,postgres tps: 1202.624052
concurrent: 8 ,postgres tps: 2359.952643
concurrent: 16 ,postgres tps: 3539.555993
concurrent: 32 ,postgres tps: 3560.534475
concurrent: 64 ,postgres tps: 3462.045914
concurrent: 128 ,postgres tps: 2837.921359
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9900_test.sh
concurrent: 2 ,postgres tps: 791.815163
concurrent: 4 ,postgres tps: 1205.374922
concurrent: 8 ,postgres tps: 2493.116099
concurrent: 16 ,postgres tps: 3456.360421
concurrent: 32 ,postgres tps: 3568.589185
concurrent: 64 ,postgres tps: 3331.357654
concurrent: 128 ,postgres tps: 3262.971818
root@ubuntu30:/usr/local/pg_install# bash pgbench_postgresql9900_test.sh
concurrent: 2 ,postgres tps: 825.601480
concurrent: 4 ,postgres tps: 1210.087214
concurrent: 8 ,postgres tps: 2508.689554
concurrent: 16 ,postgres tps: 3591.199202
concurrent: 32 ,postgres tps: 3548.136655
concurrent: 64 ,postgres tps: 3440.649905
concurrent: 128 ,postgres tps: 3115.197624
root@ubuntu30:/usr/local/pg_install#

pgbench压测结果分析

如下图是上述两次测试结果,交给AI后生成的折线图,可以看出

在中低并发(2~8线程):ext4 与 XFS的TPS差别很小
在中高并发(16~128线程):两者性能非常接近,XFS比ext4高出约10%左右,并且tps更加趋于稳定

平均 TPS 数据汇总

并发数

ext4 平均 TPS

ext4 标准差

xfs 平均 TPS

xfs 标准差

2

807.0

49.3

882.8

60.0

4

1199.0

94.1

1175.7

107.8

8

2300.0

94.3

2346.3

174.1

16

3277.5

114.5

3503.5

64.6

32

3259.7

136.5

3542.0

95.4

64

3088.1

155.2

3384.2

58.9

128

3023.6

137.3

3148.7

153.4

image

总结

fio 磁盘 IO 测试中:
1,IOPS方面,ext4 与 XFS 差异 < 1%,ext4 波动更小
2,读写延迟(clat 95 / clat 99)方面,两者几乎一致,差异 < 1%

在ext4与xfs上的postgresql实例测试中:
1,在中低并发下ext4略有优势,
2,而中高并发下xfs表现出来一定的优势,本文测试中大概有10%左右的提升

鉴于ext4与xfs都是非常成熟的文件系统,都具经历了长期的考验,仅通过本文相对简单的测试,说明在本文的测试场景下,并没有发现两者有明显的差异,而不是两者没有差异。

相关链接,本文没有参考该链接的测试,只是觉得测试的很全面,放在这里
https://www.enterprisedb.com/blog/postgres-vs-file-systems-performance-comparison