sti*_*tiv 2 mysql innodb performance
我给了 MySQL 5GB 的内存(我使用 innodb),但是当我插入大量数据(转储文件是 1GB)时,硬盘驱动器 I/O 仍然是一个瓶颈(CPU 不忙,硬盘驱动器忙)。
是否可以强制 MySQL 不让硬盘成为瓶颈?
我有五(5)个方面要在这里讨论
您需要运行此查询
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 有32G
RAM,则最大的缓冲池将是 Machine 的 75%(即24G
)或BPSIZE
,以较小者为准。换句话说,对于32G
RAM,如果BPSIZE
是10G,则使用10G。如果BPSIZE
是30G
,使用24G
.
设置日志缓冲区的大小可能是梦想成真,也可能是最糟糕的噩梦。如何?
上的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
太高会产生两个不利影响:
看看默认的 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。
无论 MySQL 的版本如何,您都应该将其设置为 90。它越高,重写负载的刷新延迟越多。鉴于 MySQL 5.5/5.6 的性能提高,这可能没有必要。
运行此查询:
SHOW VARIABLES LIKE 'innodb_file_per_table';
Run Code Online (Sandbox Code Playgroud)
如果你得到OFF
了innodb_file_per_table,你需要清理InnoDB的基础设施。我在 2010 年 10 月 29 日写了一篇关于如何做到这一点的帖子。
关于将 InnoDB 数据放在不同的磁盘上,这可能会减少磁盘 I/O,但存在降低整体 InnoDB 性能的风险。为什么 ?回过头来Feb 06, 2012
,我写过为什么在不同的磁盘上传播 InnoDB 并不是那么高效。
另外值得注意的是这方面是系统表空间ibdata1
。每次访问 InnoDB 表时,都会查阅数据字典。因此,将表分散到其他磁盘上并不会否定ibdata1
在datadir 中的访问。访问两个磁盘总是有序的。
InnoDB 在 ibdata1 中有许多活动部分:
ibdata1
期望最高的 I/O 围绕ibdata1
. 有鉴于此,无论您进行什么磁盘调整,都要重视ibdata1
.
我不喜欢将innodb_flush_log_at_trx_commit设置 为 0 或 2,因为它执行以下操作:
请牢记这一点:您的目标应该是让 InnoDB 尽可能多地缓存事务更改并尽可能少地刷新到磁盘。这肯定会减少磁盘 I/O,而不会太快地在硬件上花费精力。只有在所需的尽职调查未能减少磁盘 I/O 之后,您才应该探索硬件。
简短的回答是你不能消除对磁盘的写入,因为 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 类型的操作系统,磁盘调度程序也将发挥重要作用。如果磁盘配置为使用调度程序(如noop或deadline)而不是默认的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 将数据文件刷新到磁盘。
归档时间: |
|
查看次数: |
8037 次 |
最近记录: |