前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >postgresql email列表对NVM WAL BUFFER的讨论

postgresql email列表对NVM WAL BUFFER的讨论

作者头像
yzsDBA
发布2021-01-05 14:36:18
5930
发布2021-01-05 14:36:18
举报

本文介绍NVM WAL BUFFER的email list,详细了解开发者对此的讨论,以此深入

了解机制。

1、Heikki

使用mmap()/msync()映射WAL文件,替代WAL buffer。如果读memory-mapped文件有IO错误时,进程会通过SIGBUS杀掉。

重新阅读了[1][2],使用WAL段文件映射到内存作为WAL BUFFER,依赖于WAL文件是否放在PM上切换CPU指令或者msync()用于持久化WAL记录。

听起来挺合理,但是我没测试过。我会尝试与NVM WAL BUFFER进行比对测试。现在,有点担心对于每个段文件mmap/munmap带来的消耗。

同时提到内存映射IO的SIGBUS问题,从坏的内存块读取时会有这个问题,向这个块[3]写时也有这个问题。未来会处理这个问题。

[1]https://www.postgresql.org/message-id/83eafbfd-d9c5-6623-2423-7cab1be3888c%40iki.fi

[2]https://www.postgresql.org/message-id/2aec6e2a-6a32-0c39-e4e2-aad854543aa8%40iki.fi

[3] https://pmem.io/2018/11/26/bad-blocks.htm

https://www.postgresql.org/message-id/2aec6e2a-6a32-0c39-e4e2-aad854543aa8%40iki.fi

2、mmap/munmap带来的消耗

mmap/munmap每个WAL段文件的消耗与write一个block的消耗谁更大。mmap比read消耗大,但是减小系统调用又可以使mmap更具优势。这只是猜测,并不知道mmap真实消耗是多少。

我有一个不同想法,当重用一个段文件时,会一次写所有整个页,段文件的即使没有读取过,也会被重写。但是使用mmap时就不会有这样的行为了。只要想mapped页写一个字节,老内容就会被加载到内存。VM页在该点设置读写后,系统不知道将要写整个页。读取回收文件的老内容显然代价太过糟糕。

当修改mapped区和write()时,对于write-back行为是否有所不同。不管哪种方式,同一个文件同一个页面都会被写脏,但内核可能对何时写回磁盘有不同行为,这对性能影响很大。

这个问题可以分为两类:性能和一致性。程序的作者同样忧虑这些问题,但是也没有一个很好的答案。作者认为同一个文件被多个后端进程调用mmap(flags | MAP_SHARED)对于PM和非PM设备都是保持一致性的,但是还没找到任何如规范文件来证明。

作者在同一个mmaped文件上做了一个小程序,调用memcpy和msync,并行的地址范围不同,没发现损坏的数据。但这也无妨确保一致性,如果有损坏,作者会放弃...

作者会测试Heikki所说的使用mmap和munmap映射每个段文件,来看是否合理。

Mmap/munmap可伸缩性确实很差,但是不认为会影响我们,因为PG不是多线程。

针对mmap/munmap,这样做有很多改进。即使现在,在快速存储方面,使用open_datasync会更快(至少在O_DIRECT上)。WAL扩展是一个挑战性问题。不修改IO方式,有很多地方可以优化以提升性能:

1)将WALWriteLock分成两个锁:一个用于写,一个用于flush wal。现在,一个会话进行flush一个wal时,其他会话不能write wal,即使该wal位于其他段文件。没有必要这样做。

2)XLogFlush()中刷写WAL时不要将刷写请求的大小增加到最大(cf "try to write/flush later additions to XLOG as well" in XLogFlush()),可以显著减小OLTP负载。在SATA盘上有意义,但是对于SSD来说影响较小。写的多,持久锁时间就更长,增加了事务提交的延迟,组织更多的WAL写。

3)应该立即将所有的XLOG页的writes刷写会操作系统。现在,在OLTP负载中IO永远不会再commit之前出现,也就是说在XLogWrite()和commit之间的完全是在浪费时间。

做了这几点,猜想能有2-3倍的性能提升。但是不得不从根本上改变WAL write的IO方式。使用异步IO,可以像18k一样每秒持久化8kb的write。在我笔记本上,写4k,就是22k。

当然这和PG的wal flush没可比性,因为WAL 经常会重复写最后一个block。但不会记录到组提交里。

NVM WAL BUFFER的path:

0001-Preallocate-more-WAL-segments.patch (3K) Download Attachment

0002-Use-WAL-segments-as-WAL-buffers.patch(40K) Download Attachment

0003-Lazy-unmap-WAL-segments.patch (2K) Download Attachment

0004-Speculative-map-WAL-segments.patch (1K) Download Attachment

0005-Allocate-WAL-segments-to-utilize-hugepage.patch(1K) Download Attachment

3、是否可以模拟PM用于测试

通过“memmap=nnG!ssG”内核参数使用DRAM模拟PM。参考[1]和[2]了解详细模拟步骤。如果不起作用,检查PM和DAX的内核配置选项,比如CONFIG_FOOBAR,是否配置正确。

[1] How to Emulate Persistent Memory Using Dynamic Random-access Memory (DRAM)

https://software.intel.com/en-us/articles/how-to-emulate-persistent-memory-on-an-intel-architecture-server

[2] how_to_choose_the_correct_memmap_kernel_parameter_for_pmem_on_your_system

https://nvdimm.wiki.kernel.org/how_to_choose_the_correct_memmap_kernel_parameter_for_pmem_on_your_system

[3] Persistent Memory Wiki

https://nvdimm.wiki.kernel.org/

4、对于mmap WAL性能的测试

针对PG12分别进行修改。通过pgbench进行压测。SSD上存储WAL,map后的结果比原生PG性能差很多。VTune显示CopyXLogRecordToWAL的memcpy动作消耗的CPU时间比原生的大的多。使用NVDIMM-N,ext4-dax存储WAL,结果差不多,XLogInsert() 和XLogFlush()消耗的时间mmap和NVM WAL BUFFER的差不多。在PM上通过mmap WAL段文件作为WAL BUFFER是个很好的尝试。但是该path可能还有bug,并不能说性能提升或者下降。

5、作者的NVM WAL BUFFER测试

通过pgbench,指定不同的-c/--client和-j/--job,数据量规模因子s=50或者1000.结果如下:

Results (s=50) :

==============

Throughput [10^3 TPS] Average latency [ms]

( c, j) before after before after

------- --------------------- ---------------------

( 8, 8) 35.7 37.1 (+3.9%) 0.224 0.216 (-3.6%)

(18,18) 70.9 74.7 (+5.3%) 0.254 0.241 (-5.1%)

(36,18) 76.0 80.8 (+6.3%) 0.473 0.446 (-5.7%)

(54,18) 75.5 81.8 (+8.3%) 0.715 0.660 (-7.7%)

Results (s=1000)

================

Throughput [10^3 TPS] Average latency [ms]

( c, j) before after before after

------- --------------------- ---------------------

( 8, 8) 37.4 40.1 (+7.3%) 0.214 0.199 (-7.0%)

(18,18) 79.3 86.7 (+9.3%) 0.227 0.208 (-8.4%)

(36,18) 87.2 95.5 (+9.5%) 0.413 0.377 (-8.7%)

(54,18) 86.8 94.8 (+9.3%) 0.622 0.569 (-8.5%)

每个规模因子下,负载和延迟都有所改进。负载在(c,j)=(36,18)下TPS最高。S=1000案例下,提升百分比较大。规模因子大,对于同表和索引的竞争就小些,也就是加锁和解锁的操作较少。这种情况下WAL对性能更重要。

条件

1)使用一个物理server,2个numa节点:PG绑定到node 0,pgbench到node 1,每个节点18个core,192GB的DRAM

2)PGDATA在nvme ssd上,pg_wal在交互6-in-1的NVDIMM-N上:都安装在server端,node 0,都用ext4,NVDIMM-N被mounted时有“-o dax”

3)新增nvwal_path和nvwal_size参数到postgresql.conf中

步骤:

对每个(c,j)都做三次,然后取平均值:

(1) Run initdb with proper -D and -X options; and also give --nvwal-path and --nvwal-size options after patch

(2) Start postgres and create a database for pgbench tables

(3) Run "pgbench -i -s ___" to create tables (s = 50 or 1000)

(4) Stop postgres, remount filesystems, and start postgres again

(5) Execute pg_prewarm extension for all the four pgbench tables

(6) Run pgbench during 30 minutes

pgbench command line

====================

$ pgbench -h /tmp -p 5432 -U username -r -M prepared -T 1800 -c ___ -j ___ dbname

I gave no -b option to use the built-in "TPC-B (sort-of)" query.

软件

========

- Distro: Ubuntu 18.04

- Kernel: Linux 5.4 (vanilla kernel)

- C Compiler: gcc 7.4.0

- PMDK: 1.7

- PostgreSQL: d677550 (master on Mar 3, 2020)

硬件

========

- System: HPE ProLiant DL380 Gen10

- CPU: Intel Xeon Gold 6154 (Skylake) x 2sockets

- DRAM: DDR4 2666MHz {32GiB/ch x 6ch}/socket x 2sockets

- NVDIMM-N: DDR4 2666MHz {16GiB/ch x 6ch}/socket x 2sockets

- NVMe SSD: Intel Optane DC P4800X Series SSDPED1K750GA

Patch

v2-0001-Support-GUCs-for-external-WAL-buffer.patch(36K) Download Attachment

v2-0002-Non-volatile-WAL-buffer.patch (53K) Download Attachment

v2-0003-README-for-non-volatile-WAL-buffer.patch(7K) Download Attachment

nvwal-performance-s50.png (39K) Download Attachment

nvwal-performance-s1000.png(40K)Download Attachmentpostgresql.conf (1K) Download Attachment

6、增加支持流复制

v4-0001-Support-GUCs-for-external-WAL-buffer.patch (42K) Download Attachment

v4-0002-Non-volatile-WAL-buffer.patch (73K) Download Attachment

v4-0003-walreceiver-supports-non-volatile-WAL-buffer.patch (7K) Download Attachment

v4-0004-pg_basebackup-supports-non-volatile-WAL-buffer.patch (25K) Download Attachment

v4-0005-README-for-non-volatile-WAL-buffer.patch (9K) Download Attachment

7、其他人对NVM WAL BUFFER测试

数据文件放到nvme ssd,WAL放到PM。使用下面两种方式存储WAL文件:

1)NVM WAL BUFFER的分支,利用libpmem

2)通过文件系统接口访问P,就是说将PM当做传统的块设备。都是APP DIRECT方式使用PM。

进行了两种insert场景:

1)插入小记录,记录长度为24字节

2)插入大记录,记录长度328字节

初衷是看下场景2)对于WAL写密集下性能提升多大,但是发现场景1)NVM WAL BUFFER和原生PG相比有大概5%的性能提升,但是在2)有大概20%的性能衰减。

分析后,XlogFlush函数可以通过NVM WAL BUFFER提升,但是会影响CopyXlogRecordToWAL的性能。可能和PM比DRAM的memcpy延迟高有关。下面是测试结果:

Scenario A (length of record to be inserted: 24 bytes per record):

==============================

NVWAL SoAD

------------------------------------ ------- -------

Througput (10^3 TPS) 310.5 296.0

CPU Time % of CopyXlogRecordToWAL 0.4 0.2

CPU Time % of XLogInsertRecord 1.5 0.8

CPU Time % of XLogFlush 2.1 9.6

Scenario B (length of record to be inserted: 328 bytes per record):

==============================

NVWAL SoAD

------------------------------------ ------- -------

Througput (10^3 TPS) 13.0 16.9

CPU Time % of CopyXlogRecordToWAL 3.0 1.6

CPU Time % of XLogInsertRecord 23.0 16.4

CPU Time % of XLogFlush 2.3 5.9

8、作者对于328字节性能衰减的回复

对于328字节,作者测试没有性能衰减,认为环境及安装步骤等可能不一样。

结果显示NVM WAL BUFFER比原始有更好性能:

步骤

在同一个机器上跑PG server和pgbench,分别绑定到不同的2个numa节点。Server端的numa节点用于PM和PCI SSD:

01) 创建PMEM namespace (sudo ndctl create-namespace -f -t pmem -m fsdax -M dev -e namespace0.0)

02) 在PM上做ext4文件系统并以dax方式mount(sudo mkfs.ext4 -q -F /dev/pmem0 ; sudo mount -o dax /dev/pmem0 /mnt/pmem0)

03) PCIE SSD也是ext4文件系统,正常mount(sudo mkfs.ext4 -q -F /dev/nvme0n1 ; sudo mount /dev/nvme0n1 /mnt/nvme0n1)

04) /mnt/pmem0/pg_wal 作为WAL目录

05) /mnt/nvme0n1/pgdata PGDATA目录

06) 执行initdb初始化 (initdb --locale=C --encoding=UTF8 -X /mnt/pmem0/pg_wal ...)

- Also give -P /mnt/pmem0/pg_wal/nvwal -Q 81920 in the case of Non-volatile WAL buffer

07) 在附件的postgresql.conf中删除nvmwal_*对于原始PG测试

08) PG server绑定到NUMA node 0 (numactl -N 0 -m 0 -- pg_ctl -l pg.log start)

09) 创建database (createdb --locale=C --encoding=UTF8)

10) 使用pgbench 初始化t,s=50 (pgbench -i -s 50)

11) ALTER TABLE pgbench_history ALTER filler TYPE character(300);)

-使表行大小为328 bytes

12) pg_ctl -l pg.log -m smart stop

13) 重新mount PMEM 和 PCIe SSD

14) numactl -N 0 -m 0 -- pg_ctl -l pg.log start

15) 执行 pg_prewarm 预热表 pgbench_* tables

16) 执行pgbench on NUMA node 1 30分钟(numactl -N 1 -m 1 -- pgbench -r -M prepared -T 1800 -c __ -j __)

- 执行默认的 tpcb-like事务

执行3次并取平均值。环境变量:

export PGHOST=/tmp

export PGPORT=5432

export PGDATABASE="$USER"

export PGUSER="$USER"

export PGDATA=/mnt/nvme0n1/pgdata

环境

- System: HPE ProLiant DL380 Gen10

- CPU: Intel Xeon Gold 6240M x2 sockets (18 cores per socket; HT disabled by BIOS)

- DRAM: DDR4 2933MHz 192GiB/socket x2 sockets (32 GiB per channel x 6 channels per socket)

- Optane PMem: Apache Pass, AppDirect Mode, DDR4 2666MHz 1.5TiB/socket x2 sockets (256 GiB per channel x 6 channels per socket; interleaving enabled)

- PCIe SSD: DC P4800X Series SSDPED1K750GA

- Distro: Ubuntu 20.04.1

- C compiler: gcc 9.3.0

- libc: glibc 2.31

- Linux kernel: 5.7 (vanilla)

- Filesystem: ext4 (DAX enabled when using Optane PMem)

- PMDK: 1.9

- PostgreSQL (Original): 14devel (200f610: Jul 26, 2020)

- PostgreSQL (Non-volatile WAL buffer): 14devel (200f610: Jul 26, 2020) + non-volatile WAL buffer patchset v4

作者按照Gang的环境配置,得到原始PG比NVM WAL BUFFER性能好的结果。需要进一步分析。NVM WAL BUFFER的XLogInsert花费的时间较长。这个拖累了XLogFlush带来的提升,整体上性能衰减了。VTune显示NVM WAL BUFFER的XLogInsert => XLogInsertRecord => CopyXLogRecordsToWAL =>中memcpy花费的时间较长,XLogFlush时间较短。整体结果和Gang一致。PM上的WAL BUFFER相对于DRAM来说,memcpy WAL记录时间长,因为现阶段PM延迟比DRAM大。作为回报,NVM WAL BUFFER减小了让记录命中设备的时间,因为不需要将他们从缓冲区写到其他地方,只需要将CPU cache中内容持久化到NVM。会继续跟踪。

原文

https://www.postgresql-archive.org/PoC-Non-volatile-WAL-buffer-td6120484.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yanzongshuaiDBA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Heikki
  • 2、mmap/munmap带来的消耗
  • 3、是否可以模拟PM用于测试
  • 4、对于mmap WAL性能的测试
  • 5、作者的NVM WAL BUFFER测试
  • 6、增加支持流复制
  • 7、其他人对NVM WAL BUFFER测试
  • 8、作者对于328字节性能衰减的回复
  • 原文
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档