4

我们已经使用Percona OSC一段时间了,在不锁定表的情况下更改我们的 mysql 模式并且效果很好,通常在几个内向“大型”innodb 表(约 380 万行)添加新列或索引小时。

然而,我尝试的最后一次更新在运行 7 小时后仅完成了 40%(一夜之间,在我们最安静的时期),估计还需要 11 小时才能完成(不断增加)。RedHat 服务器上所有 4GB 的可用内存都被使用了 - 32GB,我们最近从 16GB 升级。

那么这里发生了什么?为什么花费的时间会突然跳得这么高?我们是不是刚刚达到了某种percona/mysql/服务器无法应对的阈值?我们可以调整任何配置以提高性能吗?

该表有 32 列和 12 个索引(包括主键和 2 个其他唯一索引)。我知道这很多,但正如我所说,直到最近它表现还不错。

该表还有几个指向它的外键,我们设置为使用 drop_swap 方法进行更新。

我使用的完整命令是:

pt-online-schema-change --execute --ask-pass --set-vars innodb_lock_wait_timeout=50 --alter-foreign-keys-method=drop_swap
--alter "ADD is_current TINYINT(1) DEFAULT '1' NOT NULL" u=admin,p=XXXXXXX,D=xxxxx_live,t=applicant

innodb_buffer_pool_size 当前设置为 2147483648 - 应该增加吗?如果是这样,多少?Web 服务器(apache/php/symfony)也在这个盒子上运行。

我对这个特定表所做的最后一次更改是将 1 个字段的排序规则更改为 utf8_bin(其他字段是 utf8_unicode_ci)——这会有所不同吗?

4

2 回答 2

1

以 MB/GB 计,这张表有多大?

InnoDB 将它的页面缓存在 innodb 缓冲池(innodb_buffer_pool_size)中,这对性能很重要。在具有 > 4GB RAM 的专用主机上,我们建议将大约 70-80% 的内存用于 InnoDB 缓冲池。

使用这篇文章中的 SQL 来收集表和索引的逻辑大小

https://www.percona.com/blog/2008/03/17/researching-your-mysql-table-sizes/

有了这些信息,您将能够立即判断 MySQL 实例(Innodb 引擎)是否内存不足。

如果您的工作数据集适合内存,那很好,但如果不是,那么您可能会导致缓存未命中,然后 MySQL 将需要执行 IO 来访问磁盘资源以将页面交换到缓冲池中。(IO 永远是 DB 领域的 PITA)

pt-osc 工作的本质是创建表的新修改副本,并用原始行中的行回填新版本。还使用工具设置的触发器插入/更新或删除新行。要执行此回填,它必须在某个时间点触及该表中的所有行,并且该表的大部分可能是冷的(不驻留在 RAM 的缓冲池中)。所以基本上你的机器上有少量的 RAM,但实际上 InnoDB 只看到 2GB。

您也有在服务器上运行的应用程序,因此您需要进行一些观察来调整,但我希望您可以显着提高分配给缓冲池的内存级别。我还希望您的大部分 RAM 未使用,但已分配给文件系统缓存。

如果您的表只有几百 mb(我怀疑有 4m 条记录和宽模式),那么可能还有更深层次的问题需要审查,但我相信通过更改缓冲池大小,您会看到更好的性能。

此外,还需要检查您innodb_log_file_size的工作负载是否已调整。这很重要,以便 MySQL 可以延迟 IO。它现在的尺寸是多少?

于 2016-04-20T08:46:55.693 回答
0

假设所有事情都是平等的,我会说某种阈值已被跨越或其他一些进程正在加载数据库。您使用的索引数量非常多。pt-osc 创建新的空更改表,然后开始复制“块”。每个块花费的时间动态调整为持续 0.5 秒(默认情况下)。您可以检查“显示进程列表”以查看谁在向数据库施加压力以及 pt-osc 使用什么块大小来获得更多信息。

于 2016-04-19T20:28:19.733 回答