本文主要探索以mmap接口访问文件时,文件自身大小、mmap映射范围和我们所能访问区间之间的关系。主要通过几个小的实验程序来说明。 本文假定读者了解mmap可以作为文件访问的接口,若没有用过可以在Linux中直接man mmap看相关说明,或者去网上搜索其他资料。简单来说,文件的某一段经过mmap系统调用映射后会返回一个地址,这样我们可以像操纵内存一样操纵磁盘上的数据,因此”open +mmap+memcpy+msync “这套文件操作可以在很多的时候代替”open+read/write+fsync“这套文件操作。 但是相比write进行追加写的操作,被mmap映射的地址是无法做到改变被映射文件大小的,那么我们如果想改变文件大小怎么办?如果我们写的地址大于实际文件大小会出现什么情况?如果我们写的地址大于所映射的地址范围会有什么情况? 通过两组简单的测试,我们可以探究这个问题: 测试1:”文件范围内, mmap范围外” 会产生SIGSEGV段错误 测试1是简单的情况,我们mmap映射的范围小于文件的实际大小,那么当我们访问在文件范围内但不是映射区范围内的地址时,会产生”segmentation fault”(SIGSEGV)错误!这很好理解,因为我们访问了非法的内存地址。 如下图,具体的,我们创建一个1 MB的文件,然后将其前512 KB用mmap映射,然后尝试访问文件第800 KB,第800 KB虽然在文件的范围内,但是不在映射范围内。结果是产生segmentation fault (SIGSEGV) 段错误。 +——————+——————+ file_testmap: | mmapped | not mmapped | +——————+——————+ 0 (KB) 512 ^ 1024 | we try to access here –+ (it will cause seg. fault) 程序1: #define _GNU_SOURCE #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> […]

原文: MySQL 5.7 Reference Manual — 9.12.2 Optimizing Disk I/O 本节将介绍当你决定更多更快的存储硬件设备投入到数据库服务器时,应该如何配置它们。 软件配置上优化InnoDB以提高I / O性能的信息,请参见第9.5.8节“优化InnoDB磁盘I/O”。 磁盘寻道是一个巨大的性能瓶颈,当数据量剧增到使得缓存命中率减小时,这个问题会更为明显。对于或多或少会进行随机访问的大型的数据库,可以确定对于读至少需要一次磁盘寻道,而对于写需要好几次磁盘寻道。要最小化这个问题,应该用磁盘寻道时间较小的磁盘。 增加可以用磁盘数,这样就可以通过符号链接将不同文件存储到不同磁盘,或者可以通过磁盘分条,来降低寻道开销。 使用符号链接: 这意味着,对于MyISAM表,可以将索引文件和数据文件从它们在数据目录中的通常位置符号链接到另一个磁盘(也可能是条带化的)。假设磁盘不用于其他通途,那么这会使得查找和读取时间减小。详情请参见第9.12.3节“使用符号链接”。 条带化: 分条意味着有多个磁盘使用的情况下,将第一个数据块放在第一个磁盘上,第二个块在第二个磁盘上,第N个块在(N对磁盘数取模)磁盘上,这意味着如果一般的数据大小小于条带大小(或者完全对齐),那么你将获得更好的性能。分条的性能非常依赖于操作系统和条带大小,因此应该设置不同的条带大小分别进行基准测试。详情请参见第9.13.2节“使用自己的基准”。 条带化的速度差异十分依赖于参数配置。根据如何设置条带化参数和硬盘数量,你可能会得到数量级的差异。对于优化随机访问还是顺序访问,你必须做出选择。 为了可靠性,你可能需要使用RAID 0+1(条带加镜像),但在这种情况下,需要2×N个磁盘来N个磁盘的数据。如果你有足够的钱,这可能是最好的选择,而且,你可能还需要额外投资一些卷管理软件来有效地管理它们。 一个好的选择是根据数据类型的关键程度来改变RAID级别。 例如,可以再生的一般重要数据可以放在RAID 0上,但将真正重要的数据(如主机信息和日志)存储在RAID 0+1或 RAID N磁盘上。 如果写入较多,则由于更新奇偶校验位需要时间,RAID N可能不太合适。 你也可以设置数据库所涉及的文件系统的参数:如果您不需要知道上次访问文件的时间(这在数据库服务器上通常用途不大),则可以使用-o noatime选项来挂载文件系统。 这会跳过对文件系统上inode的最后访问时间的更新,从而避免某些磁盘寻道。在许多操作系统上,您可以通过使用-o async选项挂载文件系统以将其设为异步更新。 如果您的计算机相当稳定,这应该给你更好的性能,而不会牺牲太多的可靠性。 (在Linux上,此标志默认是打开的) 对于使用NFS的MySQL,应该注意的潜在问题如下: 放在NFS卷上的MySQL数据和日志文件变成锁定状态并且无法使用:锁定问题可能发生在多个MySQL实例访问相同数据目录或MySQL由于断电等而不正常关闭的情况下。 NFS版本4解决了咨询或租赁导致的锁定问题。 但是,MySQL实例之间共享数据目录是不被推荐的。 由于收到无序的消息或丢失的网络流量,引入了数据不一致: 为了避免此问题,请在使用hard和intr挂载选项的情况下使用TCP。 最大文件大小限制: NFS版本2客户端能访问的最大文件只有2GB(带符号的32位偏移量)。 NFS V3客户端支持更大的文件(最多64位偏移量)。 最大支持的文件大小还取决于NFS服务器的本地文件系统。 在专业SAN环境或其他存储系统中使用NFS比在这种环境之外使用NFS更可靠。 但是,SAN环境中的NFS可能比直接连接或总线连接的非旋转存储更慢。 如果使用NFS,建议用NFS V4或更高版本。在部署到生产环境之前,也应彻底测试NFS设置。

原文:8.5.8 Optimizing InnoDB Disk I/O 这页感觉比较重要,翻译一下。。 如果你遵循了数据库设计和SQL操作调优的最佳实践,但是数据库仍然由于磁盘I/O负载过重而运行慢,请考虑这些磁盘I/O优化方法。如果Unix top工具或Windows任务管理器显示你的工作负载的CPU使用率百分比小于70%,那么你的数据库系统瓶颈在于磁盘。 增加缓冲池(buffer pool)的大小 当表中数据被缓存到InnoDB的buffer pool中时,对它的查询请求就不会引起任何磁盘I/O请求。使用innodb_buffer_pool_size选项就可以指定buffer pool的大小。buffer pool这块内存很重要,所以通常建议将innodb_buffer_pool_size配置为系统内存的50%到75%。 有关更多信息,请参见第9.12.4.1节“MySQL如何使用内存”。 调整刷新方法 在某些版本的Linux或Unix中,使用Unix fsync()调用(InnoDB默认用它)或其他类似调用将文件刷入磁盘的速度是非常慢的。如果数据库的写入性能有问题,请在执行基准测试时将innodb_flush_method参数设置为O_DSYNC。 noop和deadline两种I/O调度程序的选择 InnoDB在Linux上使用异步I/O子系统(naive AIO)来执行数据文件页的预读操作和写请求操作。此行为由innodb_use_native_aio选项进行控制,默认情况下是启用的。 对于naive AIO来说,I/O调度程序(I/O Scheduler)的类型对I/O性能有很大的影响。一般来说,建议使用noop和deadline这两种类型的I/O调度程序。这里就应该进行测试以决定当前的环境和工作负载适合使用哪一个I/O调度器。有关更多信息,请参见第15.6.8节“在Linux上使用异步I / O”。 x86_64架构的Solaris 10上使用direct I/O