如何将 mysql 调整为类似内存

sti*_*tiv 2 mysql innodb performance

我给了 MySQL 5GB 的内存(我使用 innodb),但是当我插入大量数据(转储文件是 1GB)时,硬盘驱动器 I/O 仍然是一个瓶颈(CPU 不忙,硬盘驱动器忙)。

是否可以强制 MySQL 不让硬盘成为瓶颈?

Rol*_*DBA 9

我有五(5)个方面要在这里讨论

方面 #1:innodb_buffer_pool_size

您需要运行此查询

SELECT CEILING(SUM(data_length+index_length)/power(1024,3)) BPSIZE
FROM information_schema.tables WHERE engine='InnoDB';
Run Code Online (Sandbox Code Playgroud)

这将为您提供理想大小的缓冲池,因为 InnoDB 缓存数据和索引页。

如果 DB Server 有32GRAM,则最大的缓冲池将是 Machine 的 75%(即24G)或BPSIZE,以较小者为准。换句话说,对于32GRAM,如果BPSIZE是10G,则使用10G。如果BPSIZE30G,使用24G.

方面 #2:InnoDB 日志缓冲区

设置日志缓冲区的大小可能是梦想成真,也可能是最糟糕的噩梦。如何?

梦想成真

上的MySQL 文档innodb_log_buffer_size说明如下:

InnoDB 用于写入磁盘上日志文件的缓冲区的大小(以字节为单位)。默认值为 8MB。大型日志缓冲区使大型事务能够运行,而无需在事务提交之前将日志写入磁盘。因此,如果您有大事务,增大日志缓冲区可以节省磁盘 I/O。

你最可怕的噩梦

根据

书本形象

第 428 页第 8 段如下:

InnoDB 存储引擎在内存缓冲区中记录有关当前事务的信息。当事务提交或回滚时,日志缓冲区会刷新到磁盘。如果日志缓冲区很小,它可能会在事务结束之前填满,需要在知道事务结果之前刷新日志文件。对于提交的事务,这会导致多个磁盘操作而不是一个。对于回滚事务,它会导致写入,如果缓冲区较大,则根本不需要进行写入。要设置日志缓冲区的大小,请使用该innodb_log_buffer_size选项。默认值为 1MB。典型值范围从 1MB 到 8MB。大于 8MB 的值没有任何好处。

此摘录适用于 MySQL 5.0.13。从那时起 InnoDB 已经成熟了很多,但原理还是一样:设置innodb_log_buffer_size太高会产生两个不利影响:

  1. 它可能会为低写入环境或非常小的事务更改浪费内存
  2. 产生更长的提交

学过的知识

看看默认的 innodb_log_buffer_size

  • 5.0 (默认:1M)
  • 5.1 (默认:1M)
  • 5.5 (默认:8M)
  • 5.6 (默认:8M)

您将不得不尝试更大的值,可能是 16M、32M、64M 或 128M。

只记得

  • 设置越低innodb_log_buffer_size,可能刷新的较大事务越频繁
  • innodb_log_buffer_size设置得越高,提交可能需要的时间越长

所以,不要为价值观而疯狂。尽可能保守,但寻找所需的减少磁盘 I/O。

方面 #3:缓冲池中的脏页

无论 MySQL 的版本如何,您都应该将其设置为 90。它越高,重写负载的刷新延迟越多。鉴于 MySQL 5.5/5.6 的性能提高,这可能没有必要。

方面 #4:磁盘问题

运行此查询:

SHOW VARIABLES LIKE 'innodb_file_per_table';
Run Code Online (Sandbox Code Playgroud)

如果你得到OFFinnodb_file_per_table,你需要清理InnoDB的基础设施。我在 2010 年 10 月 29 日写了一篇关于如何做到这一点的帖子

关于将 InnoDB 数据放在不同的磁盘上,这可能会减少磁盘 I/O,但存在降低整体 InnoDB 性能的风险。为什么 ?回过头来Feb 06, 2012我写过为什么在不同的磁盘上传播 InnoDB 并不是那么高效

另外值得注意的是这方面是系统表空间ibdata1。每次访问 InnoDB 表时,都会查阅数据字典。因此,将表分散到其他磁盘上并不会否定ibdata1datadir 中的访问。访问两个磁盘总是有序的。

InnoDB 在 ibdata1 中有许多活动部分:

  • 数据字典
  • 双写缓冲区
    • 防止数据损坏的安全网
    • 帮助绕过操作系统进行缓存
  • 插入缓冲区(简化对二级索引的更改)
  • 回滚段
  • 撤消日志
  • 单击此处查看图示 ibdata1

期望最高的 I/O 围绕ibdata1. 有鉴于此,无论您进行什么磁盘调整,都要重视ibdata1.

方面 #5:事务刷新

我不喜欢将innodb_flush_log_at_trx_commit设置 为 0 或 2,因为它执行以下操作:

  • 放宽 ACID 合规性
  • 发生崩溃时有 1 秒数据丢失的风险
  • 更加信任操作系统和硬件以进行刷新磁盘更改

结语

请牢记这一点:您的目标应该是让 InnoDB 尽可能多地缓存事务更改并尽可能少地刷新到磁盘。这肯定会减少磁盘 I/O,而不会太快地在硬件上花费精力。只有在所需的尽职调查未能减少磁盘 I/O 之后,您才应该探索硬件。


Nat*_*lly 5

简短的回答是你不能消除对磁盘的写入,因为 InnoDB 正在尽最大努力确保它可以在服务器崩溃时恢复。

我强烈建议不要迁移到 MyISAM - 如果您的服务器崩溃,一个被大量写入的 MyISAM 表极有可能被损坏,并且您可能会丢失数据(或需要从备份中恢复)。

但是,在事务期间有几个点可以在性能和数据安全之间进行权衡。您还可以调整服务器上的磁盘配置。

调整您的导入

您可能会发现改变加载数据的方式将是解决问题的最有效方法。

转储文件是在另一个 MySQL 数据库上运行 mysqldump 的结果吗?如果是这样,并且源数据库是 MyISAM,您可能会发现按主键顺序导出 MyISAM 数据会使导入更顺利(尽管它会导致导出在源系统上花费更长的时间)。

如果数据是通过某种其他机制加载的,则有一些行为更改可能会有所帮助 - 更小或更大的事务大小,在加载数据之前对数据进行排序,故意增加写入之间的延迟等。

一般磁盘调优

如果您还没有这样做,您可能希望将 InnoDB 数据与其他所有数据放在不同的磁盘上,最好是快速的。

InnoDB/MySQL 的不同部分也以不同的方式写入磁盘,如果可以,尝试将它们保存在不同的磁盘上是有益的。例如,二进制日志和innodb日志文件一般是按顺序写入的(位置1、位置2、位置3...),而数据文件是随机读写的(位置200、位置38937、位置2...)。

如果您使用的是本地旋转磁盘(而不是 SAN 或 SSD),则在不同磁盘上保持随机和顺序 IO 可以显着提高性能。

调整您的硬盘配置也有帮助 - 如果您使用的是 Linux,请考虑使用 XFS 或 ext4 等现代文件系统,或者在挂载文件系统时使用noatime 等选项,这样就不必每次都将更新写入磁盘数据库读取一个文件。

最后,如果您使用的是 Unix 类型的操作系统,磁盘调度程序也将发挥重要作用。如果磁盘配置为使用调度程序(如noopdeadline)而不是默认的cfq,则数据库通常会表现得更好。在 SO 上有一些关于这个的详细讨论

高性能 MySQL》一书是一本极好的读物,其中对大多数这些主题进行了大量详细介绍。

二进制日志

默认情况下,MySQL 中的二进制日志是关闭的。它由log_bin服务器设置控制。

如果它打开,这将提供一些显着的好处。没有它就不可能进行复制,如果您的数据库损坏并且您拥有的只是 12 小时前的备份,您将无法进行时间点恢复。

但是,写入二进制日志和 master.info 文件是磁盘要做的另一件事。

如果您不需要二进制日志提供的好处,您可以将其关闭。

innodb 日志文件

这通常是大多数写入活动发生的地方。

默认行为是这样的:当您提交对数据库的更改时,数据库将“写入”innodb 日志文件(通常称为 ib_logfile*)中发生的事情,并立即将该更改“刷新”到磁盘。

“写入”和“刷新”之间存在差异——将文件写入磁盘意味着 MySQL 已告诉操作系统进行更改,但操作系统可能会选择等待,然后才实际将文件写入磁盘。“刷新”文件意味着 MySQL 将强制操作系统将其物理写入磁盘。

但是,可以通过 MySQL 变量innodb_flush_log_at_trx_commit修改此行为。

如果可能,我建议将其保留为默认值1 - 这是迄今为止 MySQL 最安全的设置。

如果值为2,则在提交事务时数据库将“写入”磁盘,但每秒“刷新”一次 - 使操作系统有更多时间将其写入批量写入 innodb 日志文件,并且通常会略微提高性能。

如果值为0,则数据库每秒只会“写入”和“刷新”到磁盘一次。

innodb 数据文件

令人惊讶的是,MySQL 通常会尽其所能延迟将数据写入 InnoDB 数据文件。根据innodb_max_dirty_pages_pct的值和您的 MySQL 版本,它可能会等到超过 75% 甚至 90% 的数据库发生更改,然后才担心将数据从内存推送到磁盘上的数据文件。

如果日志文件被轮换出来(innodb 日志文件大小影响日志文件应该有多大),InnoDB 也会强制将更改写入磁盘。为您的服务器设置正确的值需要反复试验 - 您可能需要较低的值,以便在文件过期时不会减慢服务器的速度,或者您可能需要较大的值,以便您可以处理您的数据导入而不需要 MySQL 将数据文件刷新到磁盘。