如何减慢 MySQL 转储速度以免影响服务器上的当前负载?

Posted

技术标签:

【中文标题】如何减慢 MySQL 转储速度以免影响服务器上的当前负载?【英文标题】:How can I slow down a MySQL dump as to not affect current load on the server? 【发布时间】:2011-08-05 17:23:26 【问题描述】:

虽然进行 mysql 转储很容易,但我有一个实时专用 MySQL 服务器,我想在其上设置复制。为此,我需要转储数据库以导入我的复制从属服务器。

当我进行转储时,问题就出现了,MySQL 全力以赴,并将资源绑定到连接到它的站点。我想知道是否有办法将转储查询限制为优先考虑实时连接的低优先级状态?这个想法是来自外部站点的负载不受 MySQL 进行完整转储的影响......

【问题讨论】:

你应该选择正确的答案。 您是否更担心磁盘 I/O?还是网络流量? 如果使用 mysqldump,请参阅下面的最佳答案。如果使用 MySQL Workbench,请转到高级选项,uncheck "lock-tables" [to not block] 和 check "compress" [使用较少的网络带宽,因此备份速度更快]。 OTOH,如果您有一个“复制从属”,而不是转储(作为一个操作)然后导入(作为第二个操作)到复制从属,请研究直接复制到从属的其他替代方案。 【参考方案1】:

您可以在 mysqldump 命令前加上以下内容:

ionice -c3 nice -n19 mysqldump ...

它将以低 IO 和 CPU 优先级运行它,因此应该限制它的影响。

注意,这只会延迟 MySQL 执行之间的时间。脚本本身仍会像以前一样密集,只是脚本之间的休息时间更长。

【讨论】:

此方法不会影响在实时服务器上执行 mysqldump 的结果。我尝试了对优先级设置等的各种更改。我还要补充一点,我正在处理一个 7GB 的数据库...... 暂时,我们不得不在深夜(午夜至凌晨 5 点)进行数据库锁定和转储。仍然需要更优雅的解决方案... 这只会降低 mysqldump 进程的优先级。然而,mysqldump 进程只是查询数据库,查询本身以通常的优先级在 mysql 服务器上运行,并对服务器造成(几乎)相同的影响。 mysqldump 不是瓶颈。【参考方案2】:

如果使用 InnoDB 表,请为 mysqldump 使用 --single-transaction 和 --quick 选项

【讨论】:

哇——在具有 1M 条目的 InnoDb 表上有何不同。无需将整个服务器阻塞 10 分钟,而是使用这些选项使一切都保持平稳运行。应该早点找到这个帖子~~~ 如果你有 innodb,这是正确的答案。默认情况下,innodb 在任何查询上开始/提交单个事务。在转储期间有很多查询。 对我们也有很大影响【参考方案3】:

我有非常大的数据库,其中包含数以万计的表,其中一些表在数以千万计的条目中具有高达 5GB 的数据。 (我运行一个流行的服务)...备份这些数据库时我一直很头疼。使用默认的 mysqldump 它会迅速使服务器负载失控并锁定所有内容……影响我的用户。尝试停止进程可能会导致表崩溃并在恢复这些表期间导致大量停机。

我现在用...

mysqldump -u USER -p --single-transaction --quick --lock-tables=false DATABASE | gzip > OUTPUT.gz

dev.mysql.com 上的mysqldump reference 甚至说...

要转储大型表,您应该结合 --single-transaction --quick 选项。

没有说明依赖数据库是 InnoDB,我的是 myISAM,这对我来说效果很好。服务器负载几乎完全不受影响,我的服务在整个过程中像劳力士一样运行。如果您有大型数据库并且备份它们会影响您的最终用户......这就是解决方案。 ;)

【讨论】:

这对我来说效果很好,并且在发生 mysqldumps 时将我的页面加载时间减半。 由于 MyISAM 不支持事务,我不确定您的备份是否一致,特别是如果您有一个大数据库。我会推荐它用于仅限 InnoDB 的数据库。 在 InnoDB 上测试。您可以使用SELECT TABLE_NAME, ENGINE FROM information_schema.TABLESSELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = '<your database name>' 来检查您的引擎 这个非常适合我的 20+ GB 数据库。正如作者所难过的那样,它只适用于 InnoDB 类型;) dev.mysql.com 说,“使用此选项时,您应该记住,只有 InnoDB 表以一致状态转储。”【参考方案4】:

使用 nice 和 gzip 命令以最低优先级执行命令。

nice -n 10 ionice -c2 -n 7 mysqldump db-name | gzip > db-name.sql.gz 

【讨论】:

这会使mysqldump客户端变慢,但是会影响从mysql服务器读取吗? 如果 I/O 比网络带宽更成问题,请在另一台服务器上运行所有(?)。【参考方案5】:

1) 首先您需要了解您的 MySQL 版本。至少使用 5.7,因此它支持多线程。旧版本仅使用 1 个线程,如果您有大型数据库,同时使用 DB 和执行 mysqldump 不是一个好主意。

2) 最好不要在同一个 DB 磁盘中构建备份,因为读/写的性能,或者您可能需要 RAID 10。

3) MySQL Enterprise 的 mysqlbackup 更好,但是是付费的,我不知道你是否可以选择。

4) 有时很多表不需要事务,所以只在需要的表上使用事务

5) 事务一般是必须的,使用 InnoDB 格式来获得更好的性能,不要使用锁表。

6) 某些情况下最好做一个程序,因此您可以创建事务仅用于读取表而不锁定任何人,并通过一些睡眠进行测试,而不是冻结您的服务。

【讨论】:

【参考方案6】:

除了已经提到的使用 --single-transaction--quick 的解决方案之外,我不会直接将结果通过管道传输到 gzip 中,而是先将其转储为 .sql 文件,然后再进行 gzip 压缩。 (使用 && 代替 | )

转储本身会更快,因此停机时间会更短。 (对于我的测试,它是 两倍的速度

所以我会选择“&& gzip”而不是“| gzip”

重要提示:首先使用df -h! 检查可用磁盘空间! 因为您需要的不仅仅是管道 |压缩包。

mysqldump --single-transaction --quick -u user -p my_db_name > dump_name.sql && gzip dump_name.sql

-> 这也会产生 1 个名为 dump_name.sql.gz 的文件

【讨论】:

以上是关于如何减慢 MySQL 转储速度以免影响服务器上的当前负载?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UNIX/Linux 中对生产应用程序进行核心转储分析?

如何防止低效的 SQL 查询减慢数据库服务器的速度

此页面上的脚本造成Web浏览器运行速度减慢。如果继续运行,您的计算机将可能停止响应。

ORDER BY 子句是不是会减慢查询速度?

MS Access 将链接表更改为 AWS MySQL Db 会减慢表单/报告的速度

磁盘读取减慢 MySQL 中的 INSERT