mysql fsync_深入理解Fsync「建议收藏」

mysql fsync_深入理解Fsync「建议收藏」1介绍数据库系统从诞生那天开始,就面对一个很棘手的问题,fsync的性能问题。组提交(groupcommit)就是为了解决fsync的问题。最近,遇到一个业务反映MySQL创建分区表很慢,仔细分析了一下,发现InnoDB在创建表的时候有很多fsync——每个文件会有4个fsync的调用。当然,并不每个fsync的开销都很大。这里引出几个问题:(1)问题1:为什么fsync开销相对都比较大?它到…

大家好,又见面了,我是你们的朋友全栈君。

1 介绍

数据库系统从诞生那天开始,就面对一个很棘手的问题,fsync的性能问题。组提交(group commit)就是为了解决fsync的问题。最近,遇到一个业务反映MySQL创建分区表很慢,仔细分析了一下,发现InnoDB在创建表的时候有很多fsync——每个文件会有4个fsync的调用。当然,并不每个fsync的开销都很大。

129a85dfbd0246ed90f9e08c2b02f255.png

这里引出几个问题:

(1)问题1:为什么fsync开销相对都比较大?它到底做了什么?

(2)问题2:细心的人可以发现,第一次open数据文件后,第二次fsync的时间远远小于第1次调用fsync的时间,为什么?

a797b3b066b555e3da0e52d0c042bfa6.png

(3)问题3:能否优化fsync?

来着这些疑问,一起来了解一下fsync。

2 原因分析

我们先通过一个测试程序来学习一下fsync在块层的基本流程。

2.1 测试程序1

Write page 0

Sleep 5

Fsync

用blktrace跟踪结果如下:

df574213331fa93417e7897470713c81.png

上半部红色框内为pwrite在块层的流程,下半部黄色框内为fsync在块层流程,中间刚好相差5秒。

4722712为测试文件的第1个block对应的扇区号,590339(block号) * 8=4722712(扇区号)。

2461819098825331ff3a864481bb8f5e.png

无论是pwrite,还是fsync,主要的开销都发生IO请求提交给驱动和IO完成之间,也就是说开自设备驱动。差不多占了整个系统调用的1/2的开销。

另外,可以看到调用fsync时,发生了3次块层IO,起始扇区分别是19240、19248和19256,物理上3个连续的块。实际上这3个块为内核线程kjournald写的日志,分别描述块(2405)、数据块(2406)和提交块(2407)。为了验证,不妨看一下这三个块的实际数据。

块2405:

cc5fd71772d693f8a69b9ff0472867fb.png

#define JFS_MAGIC_NUMBER 0xc03b3998U

#define JFS_DESCRIPTOR_BLOCK 1

#define JFS_COMMIT_BLOCK 2

开始的4个字节为JFS_MAGIC_NUMBER,然后是block type:JFS_DESCRIPTOR_BLOCK。

块2407:

dd73ce2b96eb2847fa8b4cece30c1e74.png

的确是提交块。

2.2 fsync的实现

既然fsync的开销很大,就来看看代码吧。

函数ext3_sync_file:

f9faca20ec530322361b517d5c988595.png

函数log_start_commit负责唤醒kjounald内核线程,log_wait_commit等待jbd事务提交完成。

69b495548fffe7d8b2a1b7da003c1a45.png

从代码来看,fsync的主要开销在于调用log_wait_commit后的等待。也就是说fsync要等待kjournald把事务提交完成,才会返回。

到这里,我们已经知道了fsync开销的主要来源:(1)硬件驱动层的开销;(2)ext3写日志。

另外,当log_start_commit返回0时,fsync就不会等待事务提交完成。到这里已经基本可以确认第2次fsync的开销为什么那么小了——没有wait事务提交。

下面验证这一想法。为了方便调试,打开了内核jbd debug日志。

2.3 测试程序2

Write page 0

Fsync

Write page 0

Fsync

Write page 1

Fsync

Write page 2

Fsync

a9afd879a5622fb73581a53c78451527.png

746c708e18c5a260bbb2dbef8249eb4a.png

从第2个红框的日志来看,第2次fsync时,的确是没有wait的,所以开销这么小,而其它3次fsync都调用了log_wait_commit函数。

问题4:第2次fsync为什么不会调用log_wait_commit?

因为挂载文件系统的时候,data=writeback,即写数据本身不会写jbd日志。第2次pwrite没有引起文件扩展,只会修改ext3 inode的i_mtime,而i_mtime只精确到second,也就是说第2次pwrite不会引起inode信息改变,所以,不会生成jbd日志,也就不需要等待事务提交完成。

bc08db63bcd440d7214dd6e37c6b3d1f.png

下面验证一下该想法。

2.4 测试程序3

Write page 0

Fsync

Sleep 1 second

Write page 0

Fsync

Write page 1

Fsync

Write page 2

Fsync

在第2次pwrite之前,sleep 1秒钟,保证ext3 inode的i_mtime修改。

b70f918d8f98caa4dbca9742811c9526.png

想法被证实了,第2次fsync的时间回到正常水平。

d776d23f596a6ccd88708a047b6c57fc.png

可以看到,第2次fsync调用提交了新的事务,并调用了log_wait_commit等待事务完成。

3 优化

如何优化fsync?是个难题。

(1)系统减少对fsync的调用。

作者:YY哥

出处:http://www.cnblogs.com/hustcat/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138156.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 框架梳理|企业大数据管理之道「建议收藏」

    框架梳理|企业大数据管理之道「建议收藏」大数据管理——企业转型升级与竞争力重塑之道》一书,从大数据驱动决策、大数据优化管理、大数据智慧营销、大数据发现创新、大数据推动转型、大数据保障安全六个维度全面分析了大数据对传统企业的应用价值,提供可借鉴的案例和深度有格局的思考。本文主要讲述的就是对于这本书的个人看法。

    2022年5月1日
    62
  • 树莓派介绍以及FAQ【这是我见过最全的树莓派教程】

    树莓派介绍以及FAQ【这是我见过最全的树莓派教程】一、树莓派简介树莓派是什么?树莓派(RaspberryPi)是尺寸仅有信用卡大小的一个小型电脑,您可以将树莓派连接电视、显示器、键盘鼠标等设备使用。树莓派能替代日常桌面计算机的多种用途,包括文字处理、电子表格、媒体中心甚至是游戏。并且树莓派还可以播放高至4K的高清视频。我们希望将树莓派推广给全世界的青少年电脑爱好者,用于培养计算机程序设计的兴趣和能力。树莓派各版本发布时间和差异对照?二、购买与配送在哪里购买?(说人话京东和淘宝都可以直接购买)树莓派基金会与E络盟与…

    2022年10月14日
    4
  • 2.5.1大礼包

    2.5.1大礼包查找:全局搜索 prefs:root=或者 openURL:不要有“prefs:root=xxxx”这个可能出在自己项目中,特别是接手老项目,另一种可能是第三方sdk里出现的特别是调用相册相机调用wifi这类的第三方框架或SDK。如果第三方出现重新下载最新的包或者换第三方,联系第三方sdk开发者修改。修改一般只弹框提示不做跳转或者用苹果提供的方法。不要出现:@"pre…

    2022年7月16日
    16
  • 十大气势背景音乐(适合战队,广告招商会场用)

    十大气势背景音乐(适合战队,广告招商会场用)

    2021年11月17日
    328
  • LAMP安全配置「建议收藏」

    LAMP安全配置「建议收藏」1.设置mysql密码,删除多余root账号[root@localhost~]#mysql-uroot-pmysql>setpassword=password(“111″);mysql>usemysql;mysql>deletefrom`user`whereuser!=”root”;mysql>deletefrom`user`whereuser=”root”

    2022年5月16日
    42
  • Java实现数组反转的几种方法

    Java实现数组反转的几种方法Java实现数组反转的几种方法要求:首先创建一个长度是5的数组,并填充随机数。对这个数组实现反转效果方法一:/***方法一:使用临时数组*/@Testpublicvoidmethod1(){int[]array=newint[5];System.out.println(“【方法一】:…

    2022年5月3日
    92

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号