Optimizing Disk IO & Optimizing InnoDB Disk IO

一直听说磁盘I/O会影响数据库性能,所以本文来看看到底什么是MySQL层面的磁盘I/O。本文涉及磁盘相关的知识,如有翻译不完善的地方请查看源文档。

磁盘I/O是一次从磁盘上的文件读取数据到返回的过程。

对于InnoDB来说,个人理解数据库的磁盘I/O主要问题是当InnoDB缓冲池不够用的时候,需要到磁盘读取数据,就会产生磁盘I/O,下面是官方对优化io的简介

  • 磁盘寻道是巨大的性能瓶颈。这个问题在数据量变得非常大以至于无法实现有效缓存的时候变得更加明显。对于具有大量随机访问的数据库,可以确保至少需要一次磁盘寻道来读写数据。为了最小化这个问题的影响,可以使用低寻道时间的磁盘。

  • 通过将文件符号连接到不同的磁盘或分割磁盘来增加可用磁盘主轴的数量(从而减少查找开销):

  1. 使用符号链接 意思是说,对于MyISAM表,链接索引文件和数据文件从数据库目录到其他的磁盘(可能是条带化的)。这样会使查找和读取更快,前提是磁盘不用于其他目的。 符号链接不支持InnoDB表。但是你可以通过在CREATE TABLE语句中使用DATA DIRECTORY = absolute_path_to_directory在MySQL的数据目录之外的地方创建InnoDB单表空间。如下;创建完之后会在默认的数据库目录里面生成一个isl后缀的文件,这个文件的内容即为/absolute_path_to_directory/test_symbolic_link.ibd,即链接至默认目录外面的目标文件。
mysql> create table test_symbolic_link (
    id int not null primary key auto_increment,
    name varchar(20) not null default '') 
    character set utf8
    data directory = '/absolute_path_to_directory';
  1. 条带化 条带化意味着你有很多磁盘,将第一个分块放在第一个磁盘,第二个分块放在第二个磁盘,第N个分块放在第(N MOD number_of_disks)个磁盘上。这意味着如果数据大小小于条带化大小或者正好相等,将会得到非常好的性能。条带化非常依赖操作系统和条带化的大小,所以需要用不同的条带化大小来测试应用。

条带化的速度非常依赖参数,依赖于如何设置条带化的参数以及磁盘的数量,你可能会得到数量级上的差异。你需要选择对随机访问和顺序访问进行优化。

  • 为了保证可靠性,您可能需要使用磁盘阵列 0 + 1(条带化+镜像),但在这种情况下,您需要2×N个驱动器来处理N个数据驱动器。 如果你有钱,这可能是最好的选择。 但是,您可能还必须投资一些卷管理软件来有效处理它。

  • 一个好方案是通过数据的紧急程度来调整磁盘阵列的等级。例如,存储次重要的数据在RAID 0上,但是存储像host或日志这样的重要数据在RAID 0+1或者RAID N上。如果你有很多写操作,由于需要更新奇偶校验位需要时间,RAID N可能会有问题。

  • 你也可以给数据库使用的文件系统设置参数: 如果你不需要文件最后被访问的时间(对数据库服务来说通常不重要),你可以通过-o noatime参数来挂载文件系统。这个操作会跳过更新文件系统(in inodes)的最后访问时间,从而避免一些磁盘寻道。

在一些操作系统上,你可以通过-o async选项挂载来设置文件系统异步更新。如果你的电脑很稳定,那么这会在不牺牲可靠性的基础上给你提供更好的性能。(这个选项在Linux默认是开启的)

优化InnoDB磁盘I/O

如果你已经遵循了数据库设计的最佳实践和SQL调优技术,但是你的数据库始终因繁重的I/O而缓慢,那么需要研究一下底层磁盘I/O相关的技术。如果Unix的top工具或Windows的任务管理器显示CPU的使用率低于70%,那么你的工作负载可能是磁盘限制的。

  • 当表数据缓存在InnoDB缓冲池中的时候,它能不需要访问磁盘I/O反复获取数据。使用innodb_buffer_pool_size选项来设置缓冲池大小。这块内存区域非常重要,通常配置为系统内存的50%到75%。

  • 官方文档上还有部分内容介绍,基本与机器有关,这里就不翻译了,有需要可直接看文档。

(完)