MySQL5.7 在线调整Innodb_Buffer_Pool_size不用重启mysql进程

本文介绍MySQL 5.7中InnoDB缓存池大小的动态调整方法及其应用场景,包括调整过程中的注意事项及监控方式。

在之前的版本,调整Innodb_Buffer_Pool_size大小必须重启mysql进程才可以生效,如今在MySQL5.7里,可以直接动态设置,方便了很多。

这个功能应用的场景:
一、机器增加内存,DBA粗心大意忘记调大Innodb_Buffer_Pool_size了
二、工作交接,新来的DBA发现前任DBA设置的Innodb_Buffer_Pool_size不合理

需要注意的地方,在调整Buffer_Pool期间,用户的请求将会阻塞,直到调整完毕,所以请勿在白天调整,在凌晨3-4点低峰期调整。

调整时,内部把数据页移动到一个新的位置,单位是块。如果想增加移动的速度,需要调整innodb_buffer_pool_chunk_size参数的大小,默认是128M。

例(把BP 128M增大为384M):

mysql> SELECT @@innodb_buffer_pool_size;

+---------------------------+

| @@innodb_buffer_pool_size |

+---------------------------+

|                134217728 |

+---------------------------+

1 row in set (0.00 sec)

mysql> SELECT @@innodb_buffer_pool_chunk_size;

+---------------------------------+

| @@innodb_buffer_pool_chunk_size |

+---------------------------------+

|                      134217728 |

+---------------------------------+

1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_buffer_pool_size=402653184;

Query OK, 0 rows affected (0.01 sec)

mysql> SELECT @@innodb_buffer_pool_size;

+---------------------------+

| @@innodb_buffer_pool_size |

+---------------------------+

|                402653184 |

+---------------------------+

1 row in set (0.00 sec)


innodb_buffer_pool_chunk_size的大小,计算公式是innodb_buffer_pool_size / innodb_buffer_pool_instances

比如现在初始化innodb_buffer_pool_size为2G,innodb_buffer_pool_instances实例为4,innodb_buffer_pool_chunk_size设置为1G,那么会自动把innodb_buffer_pool_chunk_size 1G调整为512M,例:
./mysqld --innodb_buffer_pool_size=2147483648 --innodb_buffer_pool_instances=4 
--innodb_buffer_pool_chunk_size=1073741824;

mysql> SELECT @@innodb_buffer_pool_size;

+---------------------------+

| @@innodb_buffer_pool_size |

+---------------------------+

|                2147483648 |

+---------------------------+

1 row in set (0.00 sec)

 

mysql> SELECT @@innodb_buffer_pool_instances;

+--------------------------------+

| @@innodb_buffer_pool_instances |

+--------------------------------+

|                              4 |

+--------------------------------+

1 row in set (0.00 sec)

 

# Chunk size was set to 1GB (1073741824 bytes) on startup but was

# truncated to innodb_buffer_pool_size / innodb_buffer_pool_instances

mysql> SELECT @@innodb_buffer_pool_chunk_size;

+---------------------------------+

| @@innodb_buffer_pool_chunk_size |

+---------------------------------+

|                      536870912 |

+---------------------------------+

1 row in set (0.00 sec)


监控Buffer Pool调整进程

mysql> SHOW STATUS WHERE Variable_name='InnoDB_buffer_pool_resize_status';

+----------------------------------+----------------------------------+

| Variable_name                    | Value                            |

+----------------------------------+----------------------------------+

| Innodb_buffer_pool_resize_status | Resizing also other hash tables. |

+----------------------------------+----------------------------------+

1 row in set (0.00 sec)


查看错误日志:
(增大)

[Note] InnoDB: Resizing buffer pool from 134217728 to 4294967296. (unit=134217728)

[Note] InnoDB: disabled adaptive hash index.

[Note] InnoDB: buffer pool 0 : 31 chunks (253952 blocks) was added.

[Note] InnoDB: buffer pool 0 : hash tables were resized.

[Note] InnoDB: Resized hash tables at lock_sys, adaptive hash index, dictionary.

[Note] InnoDB: completed to resize buffer pool from 134217728 to 4294967296.

[Note] InnoDB: re-enabled adaptive hash index.


(减少)

[Note] InnoDB: Resizing buffer pool from 4294967296 to 134217728. (unit=134217728)

[Note] InnoDB: disabled adaptive hash index.

[Note] InnoDB: buffer pool 0 : start to withdraw the last 253952 blocks.

[Note] InnoDB: buffer pool 0 : withdrew 253952 blocks from free list. tried to relocate 0 pages. (253952/253952)

[Note] InnoDB: buffer pool 0 : withdrawn target 253952 blocks.

[Note] InnoDB: buffer pool 0 : 31 chunks (253952 blocks) was freed.

[Note] InnoDB: buffer pool 0 : hash tables were resized.

[Note] InnoDB: Resized hash tables at lock_sys, adaptive hash index, dictionary.

[Note] InnoDB: completed to resize buffer pool from 4294967296 to 134217728.

[Note] InnoDB: re-enabled adaptive hash index.

--------------------------------------分割线 --------------------------------------

Ubuntu 14.04下安装MySQL http://www.linuxidc.com/Linux/2014-05/102366.htm

《MySQL权威指南(原书第2版)》清晰中文扫描版 PDF http://www.linuxidc.com/Linux/2014-03/98821.htm

Ubuntu 14.04 LTS 安装 LNMP Nginx\PHP5 (PHP-FPM)\MySQL http://www.linuxidc.com/Linux/2014-05/102351.htm

Ubuntu 14.04下搭建MySQL主从服务器 http://www.linuxidc.com/Linux/2014-05/101599.htm

Ubuntu 12.04 LTS 构建高可用分布式 MySQL 集群 http://www.linuxidc.com/Linux/2013-11/93019.htm

Ubuntu 12.04下源代码安装MySQL5.6以及Python-MySQLdb http://www.linuxidc.com/Linux/2013-08/89270.htm

MySQL-5.5.38通用二进制安装 http://www.linuxidc.com/Linux/2014-07/104509.htm

<think>好的,我现在需要帮助用户解决关于MySQL插入性能优化以及如何在线调整innodb_buffer_pool_size的问题。用户之前已经询问了插入465,617条数据耗时85秒是否正常,并得到了相关的优化建议。现在用户进一步希望了解如何在线修改innodb_buffer_pool_size以优化性能。 首先,我需要回顾之前的对话和用户提供的引用内容。用户给出的引用[1]到[4]都涉及innodb_buffer_pool_size的配置和优化,这些信息需要整合到当前的回答中。特别是用户提到在线动态调整这个参数,所以需要确认MySQL版本是否支持,以及具体操作步骤。 接下来,用户的问题可以分为两个部分:1)插入性能是否正常;2)如何在线调整innodb_buffer_pool_size。对于第一部分,之前的回答已经指出当前速度中等偏低,但用户可能希望更详细的基准分析。这里需要结合引用中的信息,比如缓冲池大小对性能的影响,以及如何通过公式计算合适的值。 关于在线调整,根据MySQL的文档,从5.7版本开始支持动态调整innodb_buffer_pool_size,但需要注意调整的步骤和可能的影响。需要确保用户了解调整时可能需要的内存分配时间,以及如何监控调整后的效果。引用中提到缓冲池实例数(innodb_buffer_pool_instances)的设置,需要结合缓冲池大小来配置,比如每个实例至少1GB,所以如果用户调整pool_size,可能需要相应调整实例数。 同时,用户提到的性能公式(Performance = innodb_buffer_pool_reads / innodb_buffer_pool_read_requests * 100)需要解释,让用户知道如何评估当前缓冲池是否足够,是否需要调整大小。此外,引用中提到的服务器内存占用建议(50%-75%)也需要强调,避免用户设置过大导致内存不足,影响其他服务。 在回答结构上,应该先确认当前性能状态,然后详细说明如何在线调整参数,包括具体步骤、注意事项和验证方法。同时,结合用户的实际应用场景,比如数据抽取时的单线程大事务,可能需要更大的缓冲池,但也要考虑服务器上其他服务的内存需求,如Redis和Kettle,因此需要平衡设置。 另外,用户可能希望在不重启数据库的情况下进行调整,所以需要明确说明动态调整的可行性,以及可能的限制,比如调整时可能会有短暂的性能波动,或者需要分阶段调整以避免内存不足的问题。同时,引用中的案例提到将pool_size设置为16G,但要根据服务器总内存来调整,比如64G的服务器,设置16G可能还有提升空间,但需留出足够内存给其他服务。 最后,需要生成相关问题,帮助用户进一步了解其他优化方法,比如缓冲池实例的配置、监控工具的使用,以及不同存储引擎的影响。这些问题应该与用户之前的提问和当前主题相关,提供连贯的学习路径。</think>#### MySQL插入性能评估与`innodb_buffer_pool_size`动态调整指南 --- ### 一、插入性能基准分析 **当前性能**:插入$465,617$条数据耗时$85$秒(约$5,480$条/秒),在以下场景中属于**中等偏低**水平: - **理想场景**:批量插入+优化配置可达$10,000-50,000$条/秒 - **瓶颈可能**:事务提交频率、索引维护、缓冲池命中率[^1] --- ### 二、`innodb_buffer_pool_size`在线调整方法 #### 1. **动态调整条件**(MySQL 5.7+) ```sql -- 查看当前缓冲池配置 SHOW VARIABLES LIKE 'innodb_buffer_pool%'; -- 在线调整缓冲池大小(需SUPER权限) SET GLOBAL innodb_buffer_pool_size = 16106127360; -- 15GB(单位:字节) ``` **关键限制**: - 调整耗时与内存分配速度相关(每GB约需$2-5$秒) - 需保证`innodb_buffer_pool_chunk_size`是总大小的公约数[^2] #### 2. **配置优化建议** | 服务器内存 | 推荐比例 | 计算公式(参考[^3]) | |------------|----------|----------------------| | ≤32GB | 50-75% | `256MB + 256 * log2(RAM_GB)` | | >32GB | 70-80% | 直接按比例分配 | **示例**:64GB内存服务器运行其他服务(Redis、Kettle): ```ini innodb_buffer_pool_size = 16G # 64GB的25%(留出其他服务内存) innodb_buffer_pool_instances = 8 # 每个实例2GB(需≥1GB/实例)[^4] ``` #### 3. **性能验证指标** ```sql -- 计算缓冲池命中率(目标:>99%) SELECT (1 - (Variable_value / (Variable_value + (SELECT Variable_value FROM information_schema.global_status WHERE Variable_name = 'Innodb_buffer_pool_read_requests')))) * 100 AS hit_rate FROM information_schema.global_status WHERE Variable_name = 'Innodb_buffer_pool_reads'; ``` **优化效果**:命中率若低于$95\%$,需增大缓冲池[^3] --- ### 三、插入性能综合优化方案 #### 1. **缓冲池协同优化** | 操作步骤 | 具体实现 | |---------------------------|--------------------------------------------------------------------------| | 1. 临时禁用双写缓冲 | `SET GLOBAL innodb_doublewrite = 0;`(仅限数据导入场景) | | 2. 调整日志刷新策略 | `SET GLOBAL innodb_flush_log_at_trx_commit = 2;` | | 3. 批量插入事务控制 | 每$1,000-10,000$条提交一次事务 | #### 2. **硬件与配置联动优化** ```ini # my.cnf配置文件优化(需重启innodb_io_capacity = 2000 # SSD建议值 innodb_thread_concurrency = 0 # 自动调整线程数 innodb_write_io_threads = 16 # 提升写入并行度 ``` --- ### 四、在线调整风险与规避 1. **内存碎片风险** - 调整后执行`ALTER TABLE ... ENGINE=InnoDB`重建表 2. **服务中断风险** - 选择业务低峰期操作 3. **性能抖动规避** - 分阶段调整(例如:8GB → 12GB → 16GB) --- ### 五、性能优化效果对比 | 优化措施 | 插入速度提升 | 适用场景 | |-------------------------|--------------|------------------------------| | 缓冲池从8GB调至16GB | 20-30% | 频繁数据更新的OLTP系统 | | 批量插入+事务合并 | 50-70% | 数据迁移或ETL作业 | | 禁用二级索引+文件导入 | 80-90% | 初始化数据装载 | --- ### 相关问题 1. 如何通过`SHOW ENGINE INNODB STATUS`分析缓冲池利用率? 2. `innodb_buffer_pool_instances`配置是否会影响并发写入性能? 3. 使用`LOAD DATA INFILE`时如何配置`bulk_insert_buffer_size`?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值