我收到了一些专用的 MySQL 服务器,它们从不使用超过一个内核。我比 MySQL 的 DBA 更像开发人员,所以需要一些帮助
设置
这些服务器在 OLAP/DataWarehouse (DW) 类型的负载下非常庞大:
- 主要:96GB RAM,8 核 + 单个 RAID 10 阵列
- 测试:4 核 32GB RAM
- 最大的 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)
问题
- 需要什么设置或补丁才能允许使用多个内核?
也就是说,为什么 MySQL 不使用所有可用的内核?(与其他 RDBMS 一样) - 这是复制的结果吗?
其他注意事项
- 我了解 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_log_at_trx_commit = 2
- innodb_use_sys_malloc = ON
- innodb_flush_method 应该是 O_DIRECT (但是 SHOW VARIABLES 没有显示这个)
- innodb_doublewrite = 关闭
- 文件系统 = ZFS(我的系统管理员发现了这个:http: //blogs.oracle.com/realneel/entry/mysql_innodb_zfs_best_practices)
去测试
- innodb_flush_method 不应该显示为 O_DIRECT
- 将遵循 RolandoMySQLDBA 的设置
如果我错过了任何重要的事情,请告诉我
干杯
更新
在 RolandoMySQLDBA 的答案中更改了 innodb_flush_method + 3 x 线程设置
结果:> 1 个核心用于测试 = 阳性结果
实际上,我在 2011 年 5 月的 Percona Live NYC 会议上与一位 MySQL 专家讨论了 innodb_thread_concurrency。
我学到了一些令人惊讶的东西:尽管有文档,最好离开
innodb_thread_concurrency
0(无限并发)。这样,InnoDB 决定innodb_concurrency_tickets
为给定的 MySQL 实例设置打开的最佳数量。设置
innodb_thread_concurrency
为 0 后,您可以将innodb_read_io_threads
和innodb_write_io_threads
(从 MySQL 5.1.38 开始)设置为最大值 64。这应该会占用更多内核。MySQL 将自动使用多个内核,因此 25% 的负载是巧合1或 Solaris 上的潜在错误配置。我不会假装知道如何调整 solaris,但这里有一篇文章介绍了一些特定于 solaris 的调整信息。
InnoDB 调优页面在 MySQL 5.5 中进行了大修,因此那里也有一些很好的信息。来自InnoDB 磁盘 IO 提示:
其他一些需要检查的事情:
将innodb_flush_method切换为 O_DIRECT 值得测试。如果这有帮助,您可能需要使用
forcedirectio
选项挂载文件系统将innodb_flush_log_at_trx_commit从 1更改为 0(如果您不介意在 mysql 崩溃时丢失最后一秒)或 2(如果您不介意在操作系统崩溃时丢失最后一秒)。
检查innodb_use_sys_malloc的值。这篇文章有更多关于变量的信息。
但是在本节末尾有一些关于打开变量意味着什么的警告(在 5.5 中默认情况下是打开的)。
复制可能会导致一些问题。我意识到您对并行性不感兴趣,但从这个工作日志的描述中:
最终,InnoDB 可能不是数据仓库的最佳引擎,因为会发生基于磁盘的操作。您可以考虑将数据仓库表更改为Compressed MyISAM。
1巧合的是,我的意思是有一个瓶颈会阻止您的负载增加到 25% 以上,但不一定是强制的单核问题。
注意:此答案是关于使用多个核心的单个连接。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 承诺会更好。(甲骨文基准测试如此说。)但仍然没有为单个连接使用多个内核。
更新(在去甲骨文的 OpenWorld 之后):新版本 8.x 不会有任何并行性。
进一步更新——8.0.17 有一些情况,它将在极少数选定的查询上使用多个核心。(也就是说,不要激动。)
恕我直言,在所描述的用例中,您永远不会使用多个内核。原因是您的工作负载受 IO 限制,而不是 CPU 限制。由于您的 3 个连接正在创建一个新索引,因此每个连接都需要从磁盘读取整个表:这需要时间,而不是计算索引。
考虑到您的瓶颈可能是文件系统的 IO 性能。
除了@RolandoMySQLDBA 建议的设置之外,我还为保存我的 mysql 数据目录的分区设置了
noatime
挂载设置(在我的情况下,挂载到)。/etc/fstab
/data01/mysql
/dev/sdb1
/data01
默认情况下,Linux 会记录每个磁盘读取或写入的访问时间,这会对 IO 性能产生负面影响,尤其是对于数据库等高 IO 应用程序。这意味着即使从文件中读取数据也会触发写入磁盘... WAT!
要禁用此功能,请为所需的挂载点添加
noatime
挂载选项,/etc/fstab
如下所示(以我为例):然后重新挂载分区:
这应该会提高使用该分区的应用程序的读/写性能。但是......没有什么比将所有数据都保存在内存中更好的了。