PostgreSQL 不支持的 O_DIRECT,MySQL 和 Oracle 都有
sinye56 2024-10-17 15:21 21 浏览 0 评论
在 MySQL 数据库中,几乎默认会将 InnoDB 的磁盘刷新参数 innodb_flush_method 设置为 O_DIRECT ,以此提升数据库的刷新性能。
Oracle 数据库也有提供了参数 FILESYTEMIO_OPTIONS 可将刷新设置为 O_DIRECT。
然而,PostgreSQL 数据库并不支持 O_DIRECT,所以 PG 存在数据库性能抖动的问题,无法在海量互联网业务中使用。
然而,什么是 O_DIRECT 呢?
O_DIRECT 内存地址对齐
相信很多同学会说,O_DIRECT 是指文件读写时,数据直接访问磁盘,而不要经过操作系统的缓存。
嗯,这个没有错,但 show me your code 。
接着,Java 开发工程师、DBA 们就一脸茫然了。
估计你让一个 P8 工程师来,也写不出。
不信?那你问问身边的工程师们。
O_DIRECT 原理本身不特别复杂,一看即懂,一句话就能说清。
但这个特性却非常小众,按我的理解只存在于类似数据库的开发领域。
绝大部分业务的开发工程师们,与文件打交道就是打印日志。
日志打印主要目的是性能,不需要 O_DIRECT ,数据若发生丢失,丢就丢了吧。
甚至,Java 语言本身都没提供 O_DIRECT 的文件选项。若想使用,还需要自己额外进行一层底层的封装。
好吧,接着让姜老师写个最简单的 demo :
这个 demo 就是向文件 f.test 写入16384个字节。
可以看到,这里 open 的时候加入了额外的 O_DIRECT 选项,接着通过 pwrite 函数将数据写入文件。
但这里需要特别注意的是 O_DIRECT 写入,要求内存地址与扇区大小对齐。下面是官方文档的说明:
The O_DIRECT flag may impose alignment restrictions on the length and address of user-space buffers and the file offset of I/Os.
因此,你会看到下面这两行用于处理内存对齐的逻辑:
buf = (char*)malloc(sizeof(char*)*PAGE_SIZE*2);
buf_aligned = (char*)ut_align(buf,SECTOR_SIZE); // align address for DIRECT_IO
只有做了地址对齐,才能使用 O_DIRECT,否则 pwrite 后的 assert 校验就会失败。
但扇区大小是多少呢?文档的说法就相当玄幻了:
In Linux alignment restrictions vary by filesystem and kernel version and might be absent entirely. However there is currently no filesystem-independent interface for an application to discover these restrictions for a given file or filesystem.
文档的意思大致就是扇区大小是可变化的,而且也没有提供一个统一的接口去获取文件系统的扇区大小。
根据经验,我们知道大部分磁盘的扇区大小是 512 字节,SSD 的扇区大小是 4K。
因此,若要使用 O_DIRECT ,建议直接按 4K 对齐,这样就无需关注下面的具体存储类型了(至少目前好像还没有扇区大小超过 4K 的设备)。
细心的同学会发现,在上面的代码中,使用 O_DIRECT 后,还需要进行 fsync 这又是为什么呢?
O_DIRECT 到底还要不要 fsync ?
是的,使用 O_DIRECT 选项后,文件写入时会绕过操作系统缓存,数据直接落盘:
从上图可以看到使用 O_DIRECT 选项后,磁盘读写从文件系统层直接访问最底层的存储设备,不走操作系统层的 Page Cache。
但即便使用 O_DIRECT ,在写入后,还是需要通过调用一次 fsync 用于保证数据真正落到磁盘。
这是因为文件对应的元数据信息还没有落盘,例如文件的大小,最后的修改时间等。
但是,若文件没有增长呢?只是更新了一个页的数据。
是的,那这时就无需在写入文件后,再进行 fsync 操作,从而进一步提升系统性能。
MySQL 5.7.25 版本开始,就进行了类似这样的优化,对参数 innodb_flush_method 提供了新的选项 O_DIRECT_NO_FSYNC 。看文档的说明:
O_DIRECT_NO_FSYNC: InnoDB uses O_DIRECT during flushing I/O, but skips the fsync() system call after each write operation.
Prior to MySQL 5.7.25, this setting is not suitable for file systems such as XFS and EXT4, which require an fsync() system call to synchronize file system metadata changes. If you are not sure whether your file system requires an fsync() system call to synchronize file system metadata changes, use O_DIRECT instead.
As of MySQL 5.7.25, fsync() is called after creating a new file, after increasing file size, and after closing a file, to ensure that file system metadata changes are synchronized. The fsync() system call is still skipped after each write operation.
总结
今天姜老师深入讲解了 O_DIRECT 的使用,这是一个文件系统操作非常底层的使用选项,一般仅用于数据库中。
今天留下2道思考题,相信答对者年薪百万那是妥妥的:
MySQL InnoDB存储引擎刷新磁盘使用 O_DIRECT,他是根据多少大小进行字节对齐的呢?
为什么重做日志文件写入却不需要启用 O_DIRECT 选项呢?
RAW格式是否还有性能优势呢?
相关推荐
- 程序员:JDK的安装与配置(完整版)_jdk的安装方法
-
对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...
- Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置
-
一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...
- 麒麟系统安装JAVA JDK教程_麒麟系统配置jdk
-
检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...
- 学习笔记-Linux JDK - 安装&配置
-
前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...
- Linux新手入门系列:Linux下jdk安装配置
-
本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...
- 测试员必备:Linux下安装JDK 1.8你必须知道的那些事
-
1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...
- Linux 下安装JDK17_linux 安装jdk1.8 yum
-
一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...
- 在Ubuntu系统中安装JDK 17并配置环境变量教程
-
在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...
- 如何在 Linux 上安装 Java_linux安装java的步骤
-
在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...
- Windows和Linux环境下的JDK安装教程
-
JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...
- linux安装jdk_linux安装jdk软连接
-
JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...
- linux安装jdk,全局配置,不同用户不同jdk
-
jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...
- 运维大神教你在linux下安装jdk8_linux安装jdk1.7
-
1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...
- window和linux安装JDK1.8_linux 安装jdk1.8.tar
-
Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...
- 最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?
-
默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)