postgresql email列表对NVM WAL BUFFER的讨论

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: postgresql email列表对NVM WAL BUFFER的讨论

 

本文介绍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 serverpgbench,分别绑定到不同的2numa节点。Server端的numa节点用于PMPCI 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 初始化ts=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的环境配置,得到原始PGNVM WAL BUFFER性能好的结果。需要进一步分析。NVM WAL BUFFERXLogInsert花费的时间较长。这个拖累了XLogFlush带来的提升,整体上性能衰减了。VTune显示NVM WAL BUFFERXLogInsert => 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

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
7月前
|
存储 Oracle 关系型数据库
postgresql数据库|wal日志的开启以及如何管理
postgresql数据库|wal日志的开启以及如何管理
1290 0
|
18天前
|
存储 关系型数据库 数据库
【赵渝强老师】PostgreSQL的WAL预写日志文件
PostgreSQL数据库的物理存储结构包含多种文件,其中WAL(预写日志)用于确保数据完整性和高效恢复。WAL机制允许在不频繁刷新数据至磁盘的情况下,通过先写日志再改数据的方式,减少I/O操作,提高性能。每个WAL文件默认大小为16MB,位于pg_wal目录下,支持手动和自动切换。WAL不仅有助于数据恢复,还能显著降低I/O成本。
|
7月前
|
SQL 关系型数据库 数据库
实时计算 Flink版产品使用合集之同步PostgreSQL数据时,WAL 日志无限增长,是什么导致的
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
存储
图解PostgreSQL-local buffer管理
图解PostgreSQL-local buffer管理
96 0
|
Oracle 安全 关系型数据库
如何在openGauss/PostgreSQL手动清理XLOG/WAL 文件?
openGauss/PostgreSQL中的预写式日志WAL(Write Ahead Log),又名Xlog或redo log,相当于oracle的online redo log, 不同的是oracle online redo log是提前创建几组滚动使用,但在opengauss中只需要本配置参数控制WAL日志的周期,数据库会一直的创建并自动清理,但存在一些情况WAL日志未清理导致目录空间耗尽,或目录空间紧张时手动删除wal日志时,比如如何确认在非归档模式下哪些WAL日志文件可以安全删除?
1010 0
|
存储 算法 安全
[翻译]PostgreSQL中的WAL压缩以及版本15中的改进
[翻译]PostgreSQL中的WAL压缩以及版本15中的改进
225 0
|
关系型数据库 PostgreSQL
PostgreSQL崩溃恢复读取WAL
PostgreSQL崩溃恢复读取WAL
227 0
|
存储 关系型数据库 PostgreSQL
PostgreSQL WAL解析:构建WAL记录准备
PostgreSQL WAL解析:构建WAL记录准备
146 0
|
关系型数据库 数据库 文件存储
PG技术大讲堂 - 第12讲:PostgreSQL wal作用与管理
PostgreSQL从小白到专家,技术大讲堂 - 第12讲:PostgreSQL wal作用与管理
273 1
|
7月前
|
关系型数据库 分布式数据库 PolarDB
PolarDB 开源版通过 postgresql_hll 实现高效率 UV滑动分析、实时推荐已读列表过滤
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍PolarDB 开源版通过 postgresql_hll 实现高效率 UV...
113 0