PostgreSQL DirectIO开发实践

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 在数据库开源的背景下,基于PG的DirectIO的研发方案分享。

分享人:唐成   中启乘数科技(杭州)有限公司联合创始人

正文:本文从五方面介绍了PostgreSQL DirectIO开发实践。

DirectIO的基本知识

为什么需要DirectIO?

实现DirectIO需要解决的一些问题

DirectIO和AIO的具体代码

DirectIO和AIO的使用


一、DirectIO的基本知识

image.png

DirectIO是绕过文件系统的缓存,直接把IO发到磁盘或底下,实现里有一个特点是打开一个文件的时候加一个O下划线Direct的标志。我们用代码打开这个文件,把标志加上是实现不了的。因为要求内存对齐,申请内存的虚地址要跟扇区的512的虚地址一致,如果中间开始程序就会是无效的参数,要实现DirectIO就要把IO的内存地址改到这里。

Direct IO中的一些疑问?

image.png

DirectIO有几个让人迷惑的地方:假设我们已经用了DirectIO是否还要fsync,其实很多时候还是需要的,比如文件的末尾写了一个东西文件就会变大了,

文件在原数据里面变大,如果没有fsync而只有DirectIO的话,原数据的大小没变。如果把大数据变回之前的小数据,后面的数据就会丢失。很多时候fsync是去不掉。

DirectIO对齐大小到底是有多大呢?有些人认为就是4k,但实际上是512个扇区的大小,但如果底下SID是4k要对齐,那对齐大小是多大?


二、为什么需要DirectIO?


image.png

在PG里有double buffering的问题,假设PG有共享内存的数据块做缓存,实际上PG是基于文件系统的cache,cache的数据块占两块内存,内存利用率不高。

如果一个机器是128G内存,给了buffering 64G,实际上64G在PG的共享内存有个cache,但文件系统也有cache。Linux操作系统的文件系统的缓存大小是无法控制的,有很多参数可以小,但是文件系统缓存不能超过总内存的10%,这是不好控制的。

在最佳实践PG的数据库如何配置呢?double buffering有两种方案:一种是把PG的buffering设的很小,比如16g以下,更多内存让文件系统去做。另一种是把buffering设置的很大,文件系统很小,文件系统会把剩余的内存给吃掉。

如果把PG内存数据化缓存的性能提高,文件系统的性能会变低,实测结果会高10%左右。如果把buffering设置的很小,更多的使用文件系统,稳定性会变差,对云厂商来说更严重。

DirectIO可以提高性能, bufferingIO用程序化内存把IO放在这里,发给操作系统后,操作系统拷贝到内核,内存会变慢。如果使用DirectIO后,可以直接把数据块以DMA的方式发送到存储设备中。

如果用操作系统的bufferingIO去写脏数据,有时候性能会大起大落太不稳定了,用DirectIO后就更平稳了。

还有潜在的实现了WAL的并发写。


三、实现DirectIO需要解决的一些问题


1)DirectIO的几座大山


image.png

如果把IO的模型直接换成DirectIO把内存对齐,通常会变慢,从快变慢就难以接受。以前大批量导数据的时候,数据给操作系统缓存来做会比较快,现在真实的落盘后就变慢了。

代码需要修改的地方还有很多,以前PG是基于bufferingIO设计的,有人做的补丁文件,是否合到社区主干版本里还没有定。对齐没做好会导致内存浪费。


2)使用AIO


image.png

在AIO没有返回前可以干一些其他的事情,过一会儿再看IO是否回到AIO模型了,以前在Linux里面有IO的模型,对PG来说可以自己实现。PG有了AIO后,就能专注干lO的现实进程,如果没有AIO,很多性能问题就比较难解决。


四、DirectIO和AIO的具体代码


1)一些链接

image.png

这里有一些链接给到大家,感兴趣的可以来看。


2)提供的内存对齐的函数

image.png

代码里除了palloc,现在加了两个对齐函数,底下lO对齐,在PG里面函数最多用的是申请一个块大小8k的内存,函数返回来指针边界对齐。下次发IO时,right函数就不会报无效参数,如果是点IO的模式就已经提供了这两个函数。


3)内存分配原理

image.png

在PG里有一个内存管理的Memorytext,用来防止内存泄露。只要SQL执行完相关的内存,Context每次申请一块内存时,又把前面八个字节指针,按照现在4k的内存搭起来对齐,增加了对齐的分配模式,它前面加的Context,从操作系统获得一个可能是没对齐的指针,再往后找一个位置对齐返回。这个代码是这样实现的。


4)代码修改: palloc内存对齐

image.png

这个地方要改的地方挺多的,把polloc跟IO相关的全改成对齐,否则IO就会报错。


5)代码修改:对齐内存的palloc_io_aligned的使用

image.png

这里就不详细介绍了。


6)代码修改:共享内存的对齐 buf_init.c

image.png

我们申请过共享内存8k缓存,缓存从8k直接写下去,边界内存也在对齐,在共享内存这里要改一下,在前面加一行对齐。这里比以前多加了一个块儿,因为要对齐又怕会浪费一个数据块,改一下共享内存就对齐了。


7)代码修改: 在md.c中加O_DIRECT

image.pngimage.png

最重要的是打开文件的时候要把O_DIRECT加上,对PG还有PG_O_DIRECT,它和标志位是一样的。


五、DirectIO和AIO的使用


1)配置参数

image.png

在使用实现时加了一些参数,第一个参数是io_data_direct,默认设置成off,如果把它设置成on,就开启功能了。最重要的参数io_method,默认是worker,io_wal_concurrency默认是32,如果用这个刷日志最多是32个,io_wal_direct默认值是off,如果想使用就设置成on,日志初始化块,把参数可以设置成on,后面还有参数要填,比如worker线程的个数。


2)配置参数之 io_method

image.png

以前内核没有这些代码时,要处理单线程百万的这个IO时,对CPU占用率比较高,每个核能处理百万是达不到的。以前英特尔黑科技叫DVDK,它实现的存储层叫SPDK,SPDK把不要的操作系统内核绕过去叫kernel by pass,现在的内核io_uring也有赶超的架势了。io_uring 和 SPDK 的性能非常接近,它的通用性比较好,同时完爆 liba_io。


3)异步IO的worker进程

image.png

打开后可以看到八个io worker在后台进程里,看起来有点像MySQL的数据库,MySQL有io线程的,但这个版本是否合进去社区还在讨论。

 

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
关系型数据库 数据库 C语言
PostgreSQL服务端开发学习 -- Datum
在使用C语言开发PostgreSQL后端、客户端应用时,Datum无处不在,所以必须要对Datum有很清楚的了解。
|
关系型数据库 开发工具 C语言
PostgreSQL libpq开发入门
简单入门C语言开发基于PostgreSQL libpq应用
|
关系型数据库 C语言 PostgreSQL
PostgreSQL服务端开发学习 --- 常用结构及宏定义1
本篇主要讲解使用C语言开发PostgreSQL服务端应用(libpq、自定义函数、扩展)常用到的结构及宏定义。
|
4月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
511 0
|
6月前
|
自然语言处理 关系型数据库 数据库
技术经验解读:【转】PostgreSQL的FTI(TSearch)与中文全文索引的实践
技术经验解读:【转】PostgreSQL的FTI(TSearch)与中文全文索引的实践
74 0
|
关系型数据库 C语言 PostgreSQL
PostgreSQL服务端开发学习 -- fmgr.h
fmgr按官方的解释就是Postgres函数管理器和函数调用接口,在使用C语言开发PostgreSQL后端应用时,所以与backend交互时必须遵循fmgr.h中定义的一些规范。
|
7月前
|
SQL 运维 关系型数据库
基于AnalyticDB PostgreSQL的实时物化视图研发实践
AnalyticDB PostgreSQL版提供了实时物化视图功能,相较于普通(非实时)物化视图,实时物化视图无需手动调用刷新命令,即可实现数据更新时自动同步刷新物化视图。当基表发生变化时,构建在基表上的实时物化视图将会自动更新。AnalyticDB PostgreSQL企业数据智能平台是构建数据智能的全流程平台,提供可视化实时任务开发 + 实时数据洞察,让您轻松平移离线任务,使用SQL和简单配置即可完成整个实时数仓的搭建。
144011 8
|
7月前
|
弹性计算 关系型数据库 数据库
开源PostgreSQL在倚天ECS上的最佳优化实践
本文基于倚天ECS硬件平台,以自顶向下的方式从上层应用、到基础软件,再到底层芯片硬件,通过应用与芯片的硬件特性的亲和性分析,实现PostgreSQL与倚天芯片软硬协同的深度优化,充分使能倚天硬件性能,帮助开源PostgreSQL应用实现性能提升。
|
7月前
|
SQL 关系型数据库 MySQL
MySQL【实践 02】MySQL迁移到PostgreSQL数据库的语法调整说明及脚本分享(通过bat命令修改mapper文件内的SQL语法)
MySQL【实践 02】MySQL迁移到PostgreSQL数据库的语法调整说明及脚本分享(通过bat命令修改mapper文件内的SQL语法)
282 0
|
关系型数据库 测试技术 分布式数据库
PolarDB | PostgreSQL 高并发队列处理业务的数据库性能优化实践
在电商业务中可能涉及这样的场景, 由于有上下游关系的存在, 1、用户下单后, 上下游厂商会在自己系统中生成一笔订单记录并反馈给对方, 2、在收到反馈订单后, 本地会先缓存反馈的订单记录队列, 3、然后后台再从缓存取出订单并进行处理. 如果是高并发的处理, 因为大家都按一个顺序获取, 容易产生热点, 可能遇到取出队列遇到锁冲突瓶颈、IO扫描浪费、CPU计算浪费的瓶颈. 以及在清除已处理订单后, 索引版本未及时清理导致的回表版本判断带来的IO浪费和CPU运算浪费瓶颈等. 本文将给出“队列处理业务的数据库性能优化”优化方法和demo演示. 性能提升10到20倍.
860 4