本文档风哥主要介绍MySQL 8.4的内存配置与优化,包括内存使用组成、内存参数配置、内存性能调优等内容。风哥教程参考MySQL官方文档Server Administration等。更多视频教程www.fgedu.net.cn
Part01-基础概念与理论知识
1.1 MySQL内存使用组成
MySQL的内存使用主要包括以下几个核心部分:
- InnoDB缓冲池:缓存数据和索引,是MySQL最主要的内存消耗部分
- MyISAM键缓存:缓存MyISAM表的索引数据
- 连接内存:每个客户端连接使用的内存,包括sort_buffer_size、read_buffer_size等
- 查询内存:用于处理查询的内存,如join_buffer_size、tmp_table_size等
- 系统内存:MySQL服务器进程本身使用的内存
1.2 内存配置的重要性
合理的内存配置对MySQL性能至关重要:
- 提高数据读写性能,减少磁盘I/O操作
- 加速查询响应,提升用户体验
- 优化系统资源利用率,降低硬件成本
- 避免内存不足导致的性能下降或崩溃
学习交流加群风哥微信: itpux-com
1.3 内存参数关系
mysql -u root -p -e “SHOW VARIABLES LIKE ‘%buffer%’; SHOW VARIABLES LIKE ‘%size%’;” | grep -E ‘buffer|size’
| head -20
Enter password: Fgedu123!
+————————————-+—————-+——+——–+———————-+——————————+
| Variable_name | Value | Type | Access | Context | Comment |
+————————————-+—————-+——+——–+———————-+——————————+
| bulk_insert_buffer_size | 8388608 | bigint | SYS_VAR | GLOBAL | Buffer size for bulk inserts |
| innodb_buffer_pool_chunk_size | 134217728 | bigint | SYS_VAR | GLOBAL | InnoDB buffer pool chunk size |
| innodb_buffer_pool_size | 1073741824 | bigint | SYS_VAR | GLOBAL | InnoDB buffer pool size in bytes |
| innodb_change_buffer_max_size | 25 | int | SYS_VAR | GLOBAL | Maximum size for InnoDB change buffer (in
percent) |
| innodb_log_buffer_size | 16777216 | bigint | SYS_VAR | GLOBAL | InnoDB log buffer size in bytes |
| join_buffer_size | 262144 | bigint | SYS_VAR | SESSION | Buffer size for ordinary index scans |
| key_buffer_size | 8388608 | bigint | SYS_VAR | GLOBAL | Index blocks buffer size |
| myisam_sort_buffer_size | 8388608 | bigint | SYS_VAR | GLOBAL | MyISAM sort buffer size |
| net_buffer_length | 16384 | int | SYS_VAR | SESSION | Buffer size for TCP/IP and socket communication |
| preload_buffer_size | 32768 | int | SYS_VAR | SESSION | Buffer size for preload operations |
| read_buffer_size | 131072 | bigint | SYS_VAR | SESSION | Buffer size for read operations |
| read_rnd_buffer_size | 262144 | bigint | SYS_VAR | SESSION | Buffer size for random read operations |
| sort_buffer_size | 262144 | bigint | SYS_VAR | SESSION | Buffer size for sorts |
| tmp_table_size | 16777216 | bigint | SYS_VAR | SESSION | Maximum size for temporary tables |
Part02-生产环境规划与建议
2.1 内存容量规划
根据服务器内存大小和业务需求,合理规划MySQL内存使用:
free -h
total used free shared buff/cache available
Mem: 16G 2.3G 11G 128M 2.7G 13G
Swap: 0B 0B 0B
# 内存分配建议比例
# – InnoDB缓冲池:50-70% of total memory
# – 连接内存:根据max_connections和每个连接的内存需求
# – 其他MySQL内存:10-15% of total memory
# – 操作系统预留:20-30% of total memory
2.2 操作系统内存预留
操作系统内存预留建议:
- 4GB服务器:预留1-2GB
- 8GB服务器:预留2-3GB
- 16GB服务器:预留4-6GB
- 32GB服务器:预留8-12GB
- 64GB+服务器:预留20-30%
2.3 内存配置策略
生产环境内存配置策略:
- 优先保证InnoDB缓冲池大小,这是影响性能的最关键因素
- 根据并发连接数合理设置连接相关内存参数
- 避免单个连接占用过多内存,导致内存耗尽
- 定期监控内存使用情况,及时调整配置
学习交流加群风哥QQ113257174
Part03-生产环境项目实施方案
3.1 缓冲池配置
vi /etc/my.cnf
[mysqld]
# 缓冲池大小(设置为物理内存的60%)
innodb_buffer_pool_size=10G
# 缓冲池实例数(建议与CPU核心数相同或为2的倍数)
innodb_buffer_pool_instances=8
# 缓冲池管理配置
innodb_buffer_pool_load_at_startup=1
innodb_buffer_pool_dump_at_shutdown=1
innodb_buffer_pool_dump_pct=50
# 保存并重启MySQL
systemctl restart mysqld
# 验证缓冲池配置
mysql -u root -p -e “SHOW VARIABLES LIKE ‘innodb_buffer_pool%’;”
Enter password: Fgedu123!
+————————————-+—————-+——+——–+———————-+——————————+
| Variable_name | Value | Type | Access | Context | Comment |
+————————————-+—————-+——+——–+———————-+——————————+
| innodb_buffer_pool_chunk_size | 134217728 | bigint | SYS_VAR | GLOBAL | InnoDB buffer pool chunk size |
| innodb_buffer_pool_dump_at_shutdown | ON | bool | SYS_VAR | GLOBAL | Dump buffer pool on shutdown. |
| innodb_buffer_pool_dump_now | OFF | bool | SYS_VAR | GLOBAL | Dump the buffer pool now. |
| innodb_buffer_pool_dump_pct | 50 | int | SYS_VAR | GLOBAL | Percentage of buffer pool to dump. |
| innodb_buffer_pool_load_abort | OFF | bool | SYS_VAR | GLOBAL | Abort buffer pool load. |
| innodb_buffer_pool_load_at_startup | ON | bool | SYS_VAR | GLOBAL | Load buffer pool at startup. |
| innodb_buffer_pool_load_now | OFF | bool | SYS_VAR | GLOBAL | Load the buffer pool now. |
| innodb_buffer_pool_size | 10737418240 | bigint | SYS_VAR | GLOBAL | InnoDB buffer pool size in bytes |
| innodb_buffer_pool_instances | 8 | int | SYS_VAR | GLOBAL | Number of buffer pool instances. |
+————————————-+—————-+——+——–+———————-+——————————+
3.2 连接相关内存配置
vi /etc/my.cnf
[mysqld]
# 最大连接数
max_connections=200
# 连接内存参数
sort_buffer_size=256K
read_buffer_size=128K
read_rnd_buffer_size=256K
join_buffer_size=256K
# 线程管理
thread_cache_size=32
thread_stack=256K
# 保存并重启MySQL
systemctl restart mysqld
# 验证连接内存配置
mysql -u root -p -e “SHOW VARIABLES LIKE ‘max_connections’; SHOW VARIABLES LIKE ‘%buffer_size%’; SHOW
VARIABLES LIKE ‘thread%’;”
Enter password: Fgedu123!
+—————–+——-+
| Variable_name | Value |
+—————–+——-+
| max_connections | 200 |
+—————–+——-+
+————————-+—————-+——+——–+———————-+——————————+
| Variable_name | Value | Type | Access | Context | Comment |
+————————-+—————-+——+——–+———————-+——————————+
| bulk_insert_buffer_size | 8388608 | bigint | SYS_VAR | GLOBAL | Buffer size for bulk inserts |
| innodb_buffer_pool_size | 10737418240 | bigint | SYS_VAR | GLOBAL | InnoDB buffer pool size in bytes |
| innodb_log_buffer_size | 16777216 | bigint | SYS_VAR | GLOBAL | InnoDB log buffer size in bytes |
| join_buffer_size | 262144 | bigint | SYS_VAR | SESSION | Buffer size for ordinary index scans |
| key_buffer_size | 8388608 | bigint | SYS_VAR | GLOBAL | Index blocks buffer size |
| myisam_sort_buffer_size | 8388608 | bigint | SYS_VAR | GLOBAL | MyISAM sort buffer size |
| net_buffer_length | 16384 | int | SYS_VAR | SESSION | Buffer size for TCP/IP and socket communication |
| preload_buffer_size | 32768 | int | SYS_VAR | SESSION | Buffer size for preload operations |
| read_buffer_size | 131072 | bigint | SYS_VAR | SESSION | Buffer size for read operations |
| read_rnd_buffer_size | 262144 | bigint | SYS_VAR | SESSION | Buffer size for random read operations |
| sort_buffer_size | 262144 | bigint | SYS_VAR | SESSION | Buffer size for sorts |
+————————-+—————-+——+——–+———————-+——————————+
+—————————+—————-+——+——–+———————-+——————————+
| Variable_name | Value | Type | Access | Context | Comment |
+—————————+—————-+——+——–+———————-+——————————+
| thread_cache_size | 32 | int | SYS_VAR | GLOBAL | How many threads we should keep in a cache for reuse. |
| thread_handling | one-thread-per-connection | string | SYS_VAR | GLOBAL | Thread handling mode. |
| thread_stack | 262144 | int | SYS_VAR | GLOBAL | Size of stack for each thread. |
+—————————+—————-+——+——–+———————-+——————————+
3.3 其他内存参数配置
vi /etc/my.cnf
[mysqld]
# 临时表配置
tmp_table_size=128M
max_heap_table_size=128M
# 表缓存配置
table_open_cache=4000
table_definition_cache=800
table_open_cache_instances=8
# 保存并重启MySQL
systemctl restart mysqld
# 验证配置
mysql -u root -p -e “SHOW VARIABLES LIKE ‘tmp_table_size’; SHOW VARIABLES LIKE ‘max_heap_table_size’; SHOW
VARIABLES LIKE ‘table%cache%’;”
Enter password: Fgedu123!
+—————-+————+
| Variable_name | Value |
+—————-+————+
| tmp_table_size | 134217728 |
+—————-+————+
+———————+————+
| Variable_name | Value |
+———————+————+
| max_heap_table_size | 134217728 |
+———————+————+
+—————————-+——-+——+——–+———————-+——————————+
| Variable_name | Value | Type | Access | Context | Comment |
+—————————-+——-+——+——–+———————-+——————————+
| table_definition_cache | 800 | int | SYS_VAR | GLOBAL | Number of table definitions that can be cached. |
| table_open_cache | 4000 | int | SYS_VAR | GLOBAL | How many open tables MySQL can keep in cache. |
| table_open_cache_instances | 8 | int | SYS_VAR | GLOBAL | Number of open table cache instances. |
+—————————-+——-+——+——–+———————-+——————————+
风哥提示:临时表大小设置应根据业务需求调整,避免过大导致内存不足。更多学习教程公众号风哥教程itpux_com
Part04-生产案例与实战讲解
4.1 内存配置案例
[mysqld]
# 核心内存配置
innodb_buffer_pool_size=10G
innodb_buffer_pool_instances=8
# 连接配置
max_connections=200
thread_cache_size=32
# 查询内存配置
sort_buffer_size=256K
read_buffer_size=128K
read_rnd_buffer_size=256K
join_buffer_size=256K
# 临时表配置
tmp_table_size=128M
max_heap_table_size=128M
# 表缓存配置
table_open_cache=4000
table_definition_cache=800
table_open_cache_instances=8
# 其他配置
key_buffer_size=128M
innodb_log_buffer_size=32M
4.2 内存使用监控
iostat -x 5
top -p $(pgrep -f mysqld)
# 监控MySQL内存相关状态
mysql -u root -p -e “SHOW GLOBAL STATUS LIKE ‘Innodb_buffer_pool%’; SHOW GLOBAL STATUS LIKE ‘Threads%’; SHOW
GLOBAL STATUS LIKE ‘Created_tmp%’;”
Enter password: Fgedu123!
# 计算缓冲池命中率
mysql -u root -p -e “SELECT \
(1 – (VARIABLE_VALUE / ( \
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME =
‘Innodb_buffer_pool_read_requests’) + \
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME =
‘Innodb_buffer_pool_reads’) \
))) * 100 AS hit_rate \
FROM performance_schema.global_status \
WHERE VARIABLE_NAME = ‘Innodb_buffer_pool_reads’;”
Enter password: Fgedu123!
+———-+——+——–+———————-+——————+
| hit_rate | Type | Access | Context | Comment |
+———-+——+——–+———————-+——————+
| 99.85 | real | SYS_VAR | GLOBAL | Hit rate in percent |
+———-+——+——–+———————-+——————+
# 使用Performance Schema监控内存分配
mysql -u root -p -e “SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE
current_alloc > 0 ORDER BY current_alloc DESC LIMIT 10;”
Enter password: Fgedu123!
4.3 内存优化实战
# 1. 检查当前命中率
mysql -u root -p -e “SELECT \
(1 – (VARIABLE_VALUE / ( \
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME =
‘Innodb_buffer_pool_read_requests’) + \
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME =
‘Innodb_buffer_pool_reads’) \
))) * 100 AS hit_rate \
FROM performance_schema.global_status \
WHERE VARIABLE_NAME = ‘Innodb_buffer_pool_reads’;”
Enter password: Fgedu123!
# 2. 增加缓冲池大小
vi /etc/my.cnf
innodb_buffer_pool_size=16G # 从10G增加到16G
# 3. 重启MySQL并验证
systemctl restart mysqld
mysql -u root -p -e “SHOW VARIABLES LIKE ‘innodb_buffer_pool_size’;”
Enter password: Fgedu123!
# 案例2:临时表使用过多的优化
# 1. 检查临时表使用情况
mysql -u root -p -e “SHOW GLOBAL STATUS LIKE ‘Created_tmp%’;”
Enter password: Fgedu123!
# 2. 优化查询或增加临时表大小
vi /etc/my.cnf
tmp_table_size=256M
max_heap_table_size=256M
# 3. 重启MySQL并验证
systemctl restart mysqld
Part05-风哥经验总结与分享
5.1 内存配置最佳实践
- 缓冲池配置:设置为物理内存的50-70%,实例数与CPU核心数匹配
- 连接内存:根据并发连接数合理设置,避免单个连接占用过多内存
- 临时表:设置合理大小,避免频繁创建磁盘临时表
- 表缓存:根据数据库大小和表数量调整,避免设置过大
- 操作系统预留:必须预留足够内存给操作系统和其他进程
5.2 常见问题与解决方案
# 解决方案:
1. 减少innodb_buffer_pool_size大小
2. 限制max_connections数量
3. 减少每个连接的内存分配(如sort_buffer_size等)
4. 增加服务器物理内存
# 问题2:缓冲池命中率低
# 解决方案:
1. 增加innodb_buffer_pool_size
2. 优化查询,减少全表扫描
3. 增加索引,提高缓存利用率
4. 考虑数据分片或分区
# 问题3:连接数达到上限
# 解决方案:
1. 增加max_connections
2. 优化应用程序连接池配置
3. 检查是否有连接泄漏
4. 考虑使用连接池中间件
# 问题4:临时表使用过多
# 解决方案:
1. 优化查询,减少临时表使用
2. 增加tmp_table_size和max_heap_table_size
3. 使用索引覆盖查询
4. 考虑分区表
5.3 内存性能调优
内存性能调优步骤:
mysql -u root -p -e “SHOW GLOBAL VARIABLES LIKE ‘%buffer%’; SHOW GLOBAL VARIABLES LIKE ‘%cache%’; SHOW
GLOBAL STATUS LIKE ‘%Innodb_buffer_pool%’;”
Enter password: Fgedu123!
# 2. 分析内存使用瓶颈
# – 缓冲池命中率是否低于95%
# – 连接数是否经常达到max_connections
# – 是否频繁创建磁盘临时表
# – 表缓存命中率是否合理
# 3. 调整内存配置参数
# 根据分析结果调整相应参数
# 4. 测试验证性能
# 使用sysbench等工具测试性能变化
sysbench –test=oltp_read_write –db-driver=mysql –mysql-host=127.0.0.1 –mysql-user=root
–mysql-password=Fgedu123! –mysql-db=fgedudb –tables=10 –table-size=1000000 –threads=16 –time=60 run
# 5. 持续监控优化
# 建立长期监控机制,定期分析内存使用情况
from MySQL:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
