Postgresql 的 ZFS 磁盘在写入密集型应用程序中会快速碎片化

Postgresql 的 ZFS 磁盘在写入密集型应用程序中会快速碎片化

我正在运行一个写入密集型应用程序,其中我将 Postgresql 存储在 ZFS 上。通常,它运行良好,但我发现我的 ZFS 池碎片严重。我甚至创建了一个新的 ZFS 池并使用 zfs send / recv 将数据移到那里,以便对整个空间进行碎片整理并尝试一些可能限制碎片的新设置,但无济于事。

我不确定发生了什么。应用程序主要在进行更新,但 Postgres 应该能够重用磁盘上已有的空间(因为它会生成死元组并自动清理它们,它会重新使用这些页面)。我确实看到分配的空间基本保持不变,因此它不会增加磁盘使用率。但是,ZFS 的 COW 特性似乎使文件系统耗尽了可用空间并严重碎片化。

因此,经过大约 15 分钟的大量写入后,ZFS 池碎片从 0%(初始值)上升到 14%。这不应该是这样的:

NAME               SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
postgres_data       149G  89.0G  60.0G        -         -    14%    59%  1.00x    ONLINE  -
postgres_wal       9.50G   289M  9.22G        -         -     0%     2%  1.00x    ONLINE  -

(注意:在我写这篇文章的时候,碎片化已经上升到了 16%。这里有些不对劲。)

关于我的实施的一些说明:

  • 我将 WAL 放在一个单独的池中,理论上,对 WAL 的持续写入不会使主数据存储碎片化。显然,这行不通。
  • sync=disabled我也曾尝试过根据 ZIL 会将我的磁盘变成瑞士奶酪的理论进行设置。同样没有任何效果。
  • 我目前使用logbias=throughput。我看到过关于此的相互矛盾的建议;官方文档建议对于 postgres 应该使用throughput,而非常有用的指南说“logbias=throughput 会将写入池中的每个单个块碎片化。”因此,在我的初始池中(现在不再使用,因为它碎片化程度高达 80%),我最初使用了它,logbias=latency但这显然也碎片化了整个磁盘。
  • 我之所以使用是ashift=9因为物理磁盘(这是云存储)的块大小为 512。

我的完整 zfs 设置:

NAME                PROPERTY              VALUE                  SOURCE
postgres_data/data  type                  filesystem             -
postgres_data/data  creation              Tue May 17 23:36 2022  -
postgres_data/data  used                  88.9G                  -
postgres_data/data  available             55.4G                  -
postgres_data/data  referenced            88.9G                  -
postgres_data/data  compressratio         1.98x                  -
postgres_data/data  mounted               yes                    -
postgres_data/data  quota                 none                   default
postgres_data/data  reservation           none                   default
postgres_data/data  recordsize            8K                     inherited from postgres_data
postgres_data/data  mountpoint            /var/lib/postgresql    local
postgres_data/data  sharenfs              off                    default
postgres_data/data  checksum              on                     default
postgres_data/data  compression           zstd                   inherited from postgres_data
postgres_data/data  atime                 off                    inherited from postgres_data
postgres_data/data  devices               on                     default
postgres_data/data  exec                  on                     default
postgres_data/data  setuid                on                     default
postgres_data/data  readonly              off                    default
postgres_data/data  zoned                 off                    default
postgres_data/data  snapdir               hidden                 default
postgres_data/data  aclmode               discard                default
postgres_data/data  aclinherit            restricted             default
postgres_data/data  createtxg             619                    -
postgres_data/data  canmount              on                     default
postgres_data/data  xattr                 sa                     inherited from postgres_data
postgres_data/data  copies                1                      default
postgres_data/data  version               5                      -
postgres_data/data  utf8only              off                    -
postgres_data/data  normalization         none                   -
postgres_data/data  casesensitivity       sensitive              -
postgres_data/data  vscan                 off                    default
postgres_data/data  nbmand                off                    default
postgres_data/data  sharesmb              off                    default
postgres_data/data  refquota              none                   default
postgres_data/data  refreservation        none                   default
postgres_data/data  guid                  10551245409099064921   -
postgres_data/data  primarycache          all                    default
postgres_data/data  secondarycache        all                    default
postgres_data/data  usedbysnapshots       0B                     -
postgres_data/data  usedbydataset         88.9G                  -
postgres_data/data  usedbychildren        0B                     -
postgres_data/data  usedbyrefreservation  0B                     -
postgres_data/data  logbias               throughput             local
postgres_data/data  objsetid              595                    -
postgres_data/data  dedup                 off                    default
postgres_data/data  mlslabel              none                   default
postgres_data/data  sync                  disabled               local
postgres_data/data  dnodesize             legacy                 default
postgres_data/data  refcompressratio      1.98x                  -
postgres_data/data  written               88.9G                  -
postgres_data/data  logicalused           176G                   -
postgres_data/data  logicalreferenced     176G                   -
postgres_data/data  volmode               default                default
postgres_data/data  filesystem_limit      none                   default
postgres_data/data  snapshot_limit        none                   default
postgres_data/data  filesystem_count      none                   default
postgres_data/data  snapshot_count        none                   default
postgres_data/data  snapdev               hidden                 default
postgres_data/data  acltype               off                    default
postgres_data/data  context               none                   default
postgres_data/data  fscontext             none                   default
postgres_data/data  defcontext            none                   default
postgres_data/data  rootcontext           none                   default
postgres_data/data  relatime              off                    default
postgres_data/data  redundant_metadata    most                   inherited from postgres_data
postgres_data/data  overlay               on                     default
postgres_data/data  encryption            off                    default
postgres_data/data  keylocation           none                   default
postgres_data/data  keyformat             none                   default
postgres_data/data  pbkdf2iters           0                      default
postgres_data/data  special_small_blocks  0                      default

答案1

碎片并不意味着你所想的那样。

它表示的是可用空间的碎片程度。它并不能显示实际数据的碎片程度。

实际上,除非您的空间真的很紧张或者遇到性能问题,否则不要担心这个值。

您应该撤消一些更改,因为它们可能会对您的实际工作量产生负面影响。

较小的 8k 记录大小也造成了这种情况(考虑默认的 128k 或者大于 8k 的值

看:https://utcc.utoronto.ca/~cks/space/blog/solaris/ZFSZpoolFragmentationMeaning

看:https://bun.uptrace.dev/postgres/tuning-zfs-aws-ebs.html#zfs-recordsize

相关内容