可以让 MySQL 使用多个核心吗?

gbn*_*gbn 140 mysql innodb performance tuning mysql-5.5

我已经看到一些专用的 MySQL 服务器,它们只使用一个内核。我比 MySQL 的 DBA 更擅长开发,所以需要一些帮助

设置

服务器非常庞大,具有 OLAP/DataWarehouse (DW) 类型的负载:

  • 主要:96GB RAM,8 核 + 单个 RAID 10 阵列
  • 测试:32GB RAM,4核
  • 最大的 DB 是 540 GB,总共大约 1.1TB,主要是 InnoDB 表
  • Solaris 10 Intel-64
  • MySQL 5.5.x

注意:最大的 DB 是从 OLTP DR 服务器复制的 DB,DW 就是从这里加载的。它不是完整的 DW:仅持续 6 个月到 6 周,因此它比 OLTP DB 小。

对测试服务器的观察

  • 3 个独立的连接
  • 每个都有一个并发的(和不同的) ALTER TABLE...DROP KEY...ADD INDEX
  • 这 3 个表有 2.5、3.8 和 450 万行
  • CPU 使用率上升到 25%(一个核心被最大化)并且不会更高
  • 3 次 ALTER 需要 12-25 分钟(最小的一次需要 4.5 分钟)

问题

  1. 需要什么设置或补丁才能允许使用多个内核?
    也就是说,为什么 MySQL 不使用所有可用的内核?(与其他 RDBMS 一样)
  2. 这是复制的结果吗?

其他注意事项

  • 我了解 RDBMS“线程”和操作系统“线程”之间的区别
  • 我不是在问任何形式的并行性
  • InnoDB 和线程的一些系统变量是次优的
    (寻求快速获胜)
  • 短期内,我无法更改磁盘布局
  • 如果需要,可以调整操作系统
  • 最小表上的单个 ALTER TABLE 需要 4.5 分钟(令人震惊的 IMO)

编辑 1

  • innodb_thread_concurrency 在两者上都设置为 8。是的,这是错误的,但不会让 MySQL 使用多核
  • innodb_buffer_pool_size 在主数据库上为 80GB,在测试中为 10GB(另一个实例已关闭)。这暂时没问题。
  • innodb_file_per_table = ON

编辑 2

去测试

  • innodb_flush_method 在应该显示的时候没有显示为 O_DIRECT
  • 将遵循 RolandoMySQLDBA 的设置

如果我错过了什么重要的事情,请告诉我

干杯

更新

在 RolandoMySQLDBA 的回答中更改了 innodb_flush_method + 3 x 线程设置
结果:> 1 个用于测试的核心 = 阳性结果

Rol*_*DBA 138

实际上,我在 2011 年 5 月的 Percona Live NYC 会议上与 MySQL 专家讨论了 innodb_thread_concurrency

我学到了一些令人惊讶的东西:尽管有文档,但最好保留innodb_thread_concurrency0(无限并发)。这样,InnoDB 会决定innodb_concurrency_tickets为给定的 MySQL 实例设置打开的最佳数量。

设置innodb_thread_concurrency为 0 后,您可以将innodb_read_io_threadsinnodb_write_io_threads(从 MySQL 5.1.38 开始)设置为最大值 64。这应该会占用更多内核。

  • 无意冒犯,但是对于 MySQL 8 和 8 年后,几乎所有关于 InnoDB 性能的问题和答案都不再适用了吗? (2认同)

Der*_*ney 32

MySQL 将自动使用多个内核,因此您的 25% 负载要么是巧合1,要么是 Solaris 上的潜在配置错误。我不会假装知道如何调整solaris,但这里有一篇文章介绍了一些特定solaris 的调整信息

在 MySQL 5.5 中对 InnoDB 调优页面进行了大修,因此那里也有一些很好的信息。来自InnoDB 磁盘 IO 提示

如果 Unix top 工具或 Windows 任务管理器显示您的工作负载的 CPU 使用百分比低于 70%,则您的工作负载可能是磁盘受限的。也许您提交的事务太多,或者缓冲池太小。使得缓冲池更大会有所帮助,但不要将其设置为物理内存的80%以上。

要检查的其他一些事项:

  • innodb_flush_method切换为 O_DIRECT 值得测试。如果这有帮助,您可能需要使用forcedirectio选项挂载文件系统

  • innodb_flush_log_at_trx_commit从 1更改为 0(如果您不介意在 mysql 崩溃时丢失最后一秒)或 2(如果您不介意在操作系统崩溃时丢失最后一秒)。

  • 检查innodb_use_sys_malloc的值。这篇文章有更多关于变量的信息

    当时,还没有针对多核 CPU 调整的内存分配器库。因此,InnoDB 在 mem 子系统中实现了自己的内存分配器。此分配器由单个互斥锁保护,这可能会成为瓶颈。

    但是在本节末尾有一些关于打开变量意味着什么的警告(它在 5.5 中默认开启)。

    请注意,当 InnoDB 内存分配器被禁用时,InnoDB 将忽略参数 innodb_additional_mem_pool_size 的值。

  • 复制可能会导致某些问题。我意识到您对并行性不感兴趣,但是从这个工作日志的描述中可以看出

    目前,复制在多核机器上不能很好地扩展。单个从线程一个接一个地执行复制事件,并且可能无法应对由独立主服务器的 CPU 服务的并发多个客户端连接产生的负载。

最终,InnoDB 可能不是数据仓库的最佳引擎,因为会发生基于磁盘的操作。您可以考虑将数据仓库表更改为Compressed MyISAM

1巧合的是,我的意思是有一个瓶颈阻止您的负载增加到 25% 以上,但不一定是强制单核问题。


Ric*_*mes 20

注意:此答案是关于使用多个核心的单个连接。OP 的问题模棱两可;它错误地认为 MySQL 作为一个整体不能使用多个内核。其他答案正确地指出 3-Alter 测试用例确实受 I/O 限制,因此无法证明标题问题。

单个连接将仅使用单个核心。(好吧,InnoDB 使用其他线程,因此是内核,用于某些 I/O 处理,但这并不重要。)

你有 3 个 ALTER,所以你没有使用超过 3 个核心的价值。

唉,甚至 PARTITION 都不使用多核。

直到最近,在 4-8 个内核之后,多个连接才会最大化。Percona 的 Xtradb(包含在 MariaDB 中)更好地利用了多个内核,但每个线程仍然只有一个内核。它们最大约为 32 个内核。

(2015 年更新:)5.6 的多个连接在大约 48 个核心时最大。5.7 承诺会更好。(Oracle 基准测试是这么说的。)但仍然没有使用多个内核进行单个连接。

更新(去甲骨文的 OpenWorld 之后):新版本 8.x 将没有任何并行性。

进一步更新 - 8.0.17 有一些情况,它将在极少数选定的查询上使用多个内核。(也就是说,不要激动。)


小智 10

恕我直言,在描述的用例中,您永远不会使用多个核心。原因是您的工作负载受 IO 限制,而不是 CPU 限制。当您的 3 个连接正在创建一个新索引时,每个连接都需要从磁盘读取整个表:这需要时间,而不是计算索引。


小智 9

考虑您的瓶颈可能是您的文件系统的 IO 性能。

除了@RolandoMySQLDBA 建议的设置之外,我还为保存我的 mysql 数据目录的分区设置了noatime挂载设置/etc/fstab/data01/mysql在我的情况下,/dev/sdb1挂载到/data01)。

默认情况下,linux 会记录每个磁盘读取或写入的访问时间,这会对 IO 性能产生负面影响,尤其是对于数据库等高 IO 应用程序。这意味着即使从文件中读取数据也会触发写入磁盘......哇!

要禁用此功能,请为所需的挂载点添加noatime挂载选项,/etc/fstab如下所示(以我为例):

/dev/sdb1  /data01  ext4  defaults,noatime  0  2
Run Code Online (Sandbox Code Playgroud)

然后重新挂载分区:

mount -o,remount /data01
Run Code Online (Sandbox Code Playgroud)

这应该会提高使用该分区的应用程序的读/写性能。但是......没有什么比将所有数据保存在内存中更好了。