mysql innodb_buffer_pool_size应该多大?


169

我有一个仅包含InnoDB表的繁忙数据库,其大小约为5GB。该数据库在使用SSD磁盘的Debian服务器上运行,并且我已将max connections设置为800,这有时会饱和并使服务器停止运行。每秒平均查询量约为2.5K。因此,我需要优化内存使用量,以便为最大可能的连接空间。

我已经看到有关innodb_buffer_pool_size最多应占总内存的80%的建议。另一方面,我从Tuning-primer脚本收到此警告:

Max Memory Ever Allocated : 91.97 G
Configured Max Per-thread Buffers : 72.02 G
Configured Max Global Buffers : 19.86 G
Configured Max Memory Limit : 91.88 G
Physical Memory : 94.58 G

这是我当前的innodb变量:

| innodb_adaptive_flushing                          | ON                                                                                                                     |
| innodb_adaptive_hash_index                        | ON                                                                                                                     |
| innodb_additional_mem_pool_size                   | 20971520                                                                                                               |
| innodb_autoextend_increment                       | 8                                                                                                                      |
| innodb_autoinc_lock_mode                          | 1                                                                                                                      |
| innodb_buffer_pool_instances                      | 1                                                                                                                      |
| innodb_buffer_pool_size                           | 20971520000                                                                                                            |
| innodb_change_buffering                           | all                                                                                                                    |
| innodb_checksums                                  | ON                                                                                                                     |
| innodb_commit_concurrency                         | 0                                                                                                                      |
| innodb_concurrency_tickets                        | 500                                                                                                                    |
| innodb_data_file_path                             | ibdata1:10M:autoextend                                                                                                 |
| innodb_data_home_dir                              |                                                                                                                        |
| innodb_doublewrite                                | ON                                                                                                                     |
| innodb_fast_shutdown                              | 1                                                                                                                      |
| innodb_file_format                                | Antelope                                                                                                               |
| innodb_file_format_check                          | ON                                                                                                                     |
| innodb_file_format_max                            | Antelope                                                                                                               |
| innodb_file_per_table                             | ON                                                                                                                     |
| innodb_flush_log_at_trx_commit                    | 2                                                                                                                      |
| innodb_flush_method                               | O_DIRECT                                                                                                               |
| innodb_force_load_corrupted                       | OFF                                                                                                                    |
| innodb_force_recovery                             | 0                                                                                                                      |
| innodb_io_capacity                                | 200                                                                                                                    |
| innodb_large_prefix                               | OFF                                                                                                                    |
| innodb_lock_wait_timeout                          | 50                                                                                                                     |
| innodb_locks_unsafe_for_binlog                    | OFF                                                                                                                    |
| innodb_log_buffer_size                            | 4194304                                                                                                                |
| innodb_log_file_size                              | 524288000                                                                                                              |
| innodb_log_files_in_group                         | 2                                                                                                                      |
| innodb_log_group_home_dir                         | ./                                                                                                                     |
| innodb_max_dirty_pages_pct                        | 75                                                                                                                     |
| innodb_max_purge_lag                              | 0                                                                                                                      |
| innodb_mirrored_log_groups                        | 1                                                                                                                      |
| innodb_old_blocks_pct                             | 37                                                                                                                     |
| innodb_old_blocks_time                            | 0                                                                                                                      |
| innodb_open_files                                 | 300                                                                                                                    |
| innodb_purge_batch_size                           | 20                                                                                                                     |
| innodb_purge_threads                              | 0                                                                                                                      |
| innodb_random_read_ahead                          | OFF                                                                                                                    |
| innodb_read_ahead_threshold                       | 56                                                                                                                     |
| innodb_read_io_threads                            | 4                                                                                                                      |
| innodb_replication_delay                          | 0                                                                                                                      |
| innodb_rollback_on_timeout                        | OFF                                                                                                                    |
| innodb_rollback_segments                          | 128                                                                                                                    |
| innodb_spin_wait_delay                            | 6                                                                                                                      |
| innodb_stats_method                               | nulls_equal                                                                                                            |
| innodb_stats_on_metadata                          | ON                                                                                                                     |
| innodb_stats_sample_pages                         | 8                                                                                                                      |
| innodb_strict_mode                                | OFF                                                                                                                    |
| innodb_support_xa                                 | ON                                                                                                                     |
| innodb_sync_spin_loops                            | 30                                                                                                                     |
| innodb_table_locks                                | ON                                                                                                                     |
| innodb_thread_concurrency                         | 4                                                                                                                      |
| innodb_thread_sleep_delay                         | 10000                                                                                                                  |
| innodb_use_native_aio                             | ON                                                                                                                     |
| innodb_use_sys_malloc                             | ON                                                                                                                     |
| innodb_version                                    | 1.1.8                                                                                                                  |
| innodb_write_io_threads                           | 4                                                                                                                      |

可能需要注意的一个旁注:我看到当我尝试从Drupal(位于单独的Web服务器上)向数据库中插入较大的帖子(例如,超过10KB)时,它将永久保存,并且页面无法正确返回。

关于这些,我想知道我的innodb_buffer_pool_size应该如何获得最佳性能。感谢您提出的建议,以针对此方案最佳地设置此参数和其他参数。

Answers:


251

您的innodb_buffer_pool_size很大。您已将其设置为20971520000。那是19.5135 GB。如果您只有5GB的InnoDB数据和索引,那么您应该只有大约8GB。即使这可能太高。

这是您应该做的。首先运行此查询

SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
(SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
FROM information_schema.tables WHERE engine='InnoDB') A;

这将为您提供RIBPS,基于所有InnoDB数据和索引的建议InnoDB缓冲池大小以及额外的60%。

例如

mysql>     SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
    ->     (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
    ->     FROM information_schema.tables WHERE engine='InnoDB') A;
+-------+
| RIBPS |
+-------+
|     8 |
+-------+
1 row in set (4.31 sec)

mysql>

使用此输出,您可以在/etc/my.cnf中设置以下内容

[mysqld]
innodb_buffer_pool_size=8G

下一个, service mysql restart

重新启动后,运行mysql一两个星期。然后,运行以下查询:

SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM
(SELECT variable_value PagesData
FROM information_schema.global_status
WHERE variable_name='Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize
FROM information_schema.global_status
WHERE variable_name='Innodb_page_size') B;

这将为您提供此时InnoDB缓冲池中的InnoDB数据正在使用多少实际GB内存。

我之前写过有关此内容的内容:设置innodb_buffer_pool的内容,以及为什么..?

您可以立即运行此DataGB查询,而不必重新配置,重新启动和等待一周。

该值DataGB更类似于InnoDB缓冲池应为+的大小(在innodb_change_buffer_max_size中指定的百分比)。我敢肯定,这将远远少于您现在保留的20000M。节省的RAM可用于调整其他功能,例如

小穴#1

需要特别注意的是:有时,InnoDB可能需要比innodb_buffer_pool_size的值额外增加10%。这是MySQL文档对此的说明:

设置的值越大,访问表中的数据所需的磁盘I / O越少。在专用数据库服务器上,您可以将其设置为最多计算机物理内存大小的80%。如果发生以下其他问题,请准备缩减此值:

对物理内存的竞争可能会导致操作系统中的页面调度。

InnoDB为缓冲区和控制结构保留了额外的内存,因此分配的总空间比指定的大小大约大10%。

地址空间必须是连续的,这在带有在特定地址加载DLL的Windows系统上可能是一个问题。

初始化缓冲池的时间大致与其大小成正比。在大型安装中,此初始化时间可能很长。例如,在现代Linux x86_64服务器上,初始化10GB缓冲池大约需要6秒钟。请参见第8.9.1节“ InnoDB缓冲池”

小穴#2

我在您的帐户中看到以下值 my.cnf

| innodb_io_capacity                                | 200 |
| innodb_read_io_threads                            | 4   |
| innodb_thread_concurrency                         | 4   |
| innodb_write_io_threads                           | 4   |

这些数字将阻止InnoDB访问多个内核

请设置以下内容:

[mysqld]
innodb_io_capacity = 2000
innodb_read_io_threads = 64
innodb_thread_concurrency = 0
innodb_write_io_threads = 64

我之前在DBA StackExchange中已经写过有关此内容的文章。

我只是使用更简洁的公式在ServerFault中回答了这样的问题

SELECT CONCAT(CEILING(RIBPS/POWER(1024,pw)),SUBSTR(' KMGT',pw+1,1))
Recommended_InnoDB_Buffer_Pool_Size FROM
(
    SELECT RIBPS,FLOOR(LOG(RIBPS)/LOG(1024)) pw
    FROM
    (
        SELECT SUM(data_length+index_length)*1.1*growth RIBPS
        FROM information_schema.tables AAA,
        (SELECT 1.25 growth) BBB
        WHERE ENGINE='InnoDB'
    ) AA
) A;

1
感谢您的精彩文章!您的公式开头SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM...在MySQL 5.7上会产生以下错误:“ 'INFORMATION_SCHEMA.GLOBAL_STATUS'功能已禁用;请参阅'show_compatibility_56'文档。您会不会有更新的版本?
本杰明·

我得到307 RIBPS和264G。就是说我需要307GB的RAM?
E_Blue

更像264G。但是您应该有足够的RAM用于此,否则将上面提到的RAM的80%分配给mysql,这取决于系统上还运行了什么。
sjas

2
我读过的最棒的文章!我有一个大约3GB的大数据库。在阅读完您的答案/文章后,链接速度提高了2

4
@Benjamin:从MySQL 5.7.6开始,information_schema合并到performance_schema中。因此,只需在查询中将“ information_schema”更改为“ performance_schema”即可使其工作。资料来源:dev.mysql.com/doc/refman/5.7/en/status-table.html
拉尔夫·博尔顿

11

像这样吗 使用SHOW VARIABLESSHOW GLOBAL STATUS

表达式: innodb_buffer_pool_size / _ram
含义: 用于InnoDB buffer_pool的RAM的百分比
建议范围: 60〜80 %

表达式: Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
含义: 读取必须命中磁盘的请求
推荐范围: 0-2%
如果超出范围怎么办: 如果有足够的空间,请增加innodb_buffer_pool_size内存。

表达式: Innodb_pages_read / Innodb_buffer_pool_read_requests
含义: 读取必须打到磁盘的请求
建议范围: 0-2%
如果超出范围怎么办: 如果有足够的RAM,请增加innodb_buffer_pool_size。

表达式: Innodb_pages_written / Innodb_buffer_pool_write_requests
含义: 写入必须命中磁盘的请求
建议范围: 0-15%
如果超出范围怎么办: 检查innodb_buffer_pool_size

表达式: Innodb_buffer_pool_reads / Uptime
含义: 读取
建议的范围: 0-100 / sec。
如果超出范围怎么办: 增加innodb_buffer_pool_size?

表达式: (Innodb_buffer_pool_reads + Innodb_buffer_pool_pages_flushed) / Uptime
含义: InnoDB I / O
推荐范围: 0-100 / sec。
如果超出范围怎么办: 增加innodb_buffer_pool_size?

表达式: Innodb_buffer_pool_pages_flushed / Uptime
含义: 写入(刷新)
推荐范围: 0-100 / sec。
如果超出范围怎么办: 增加innodb_buffer_pool_size?

表达式: Innodb_buffer_pool_wait_free / Uptime
含义: buffer_pool中没有可用页时的计数器。也就是说,所有页面都是脏的。
推荐范围: 0-1 /秒。
如果超出范围,该怎么办: 首先确保innodb_buffer_pool_size设置合理;如果仍然有麻烦,请减少innodb_max_dirty_pages_pct


感谢@Rick的好评。什么innodb_buffer_pool_size值指定?实际大小还是配置一个?
Joker

1
@joker- innodb_buffer_pool_size表示最大大小。在典型的服务器中,“缓冲池”开始时很小,但很快就增长到最大大小并停留在那里。注意:如果它大于RAM(甚至接近RAM),则将导致交换,这对于性能而言是很糟糕的。
瑞克·詹姆斯

7

您的标题询问innodb_buffer_pool_size,但我怀疑这不是真正的问题。(罗兰多评论了为什么将它设置得足够大,甚至太大。)

我将最大连接数设置为800,有时这会饱和并磨碎服务器以使其停止。

还不清楚。“睡眠”模式下的800个用户对系统几乎没有任何影响。800个活动线程将是一场灾难。有多少个线程正在“运行”?

线程是否互相阻塞?有关死锁等的一些提示,请参见SHOW ENGINE INNODB STATUS。

慢日志中是否显示任何查询?让我们对其进行优化。

您使用什么版本?XtraDB(InnoDB的替代品)在使用多个内核方面做得更好。5.6.7做得更好。

innodb_buffer_pool_instances-更改为8(假设20G buffer_pool); 它将在Mutex争用上略微减少。

您是I / O绑定还是CPU绑定?解决方案完全不同,具体取决于您的答案。

SSD-如果所有日志文件都位于非SSD驱动器上可能会更好。


6

内存越大总越好,但是以我的经验,大多数时候缓冲池的大小都不适合您的数据大小。许多表在大多数情况下都是不活动的,例如周围有备用表,因此innodb缓冲池的大小应该适合您的活动数据大小。

您为活动页面指定的时间范围会影响性能,但是有一个最佳点,对于较大的缓冲区大小,您将不会获得更多的性能。您可以通过以下方式估算/计算/测量show engine innodb status

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.