Mysql5.7内存持续增高的解决方案及说明

背景

阿里云服务器搭建了主从服务器,近期发现mysql5.7占用了服务器71%的内存。并且每天仍然有不断扩充的趋势。为了避免内存爆炸,调查了一下内存增加的原因和解决方法。调研的过程学习了很多资料,这里只说结论供大家参考。

服务器:4cpu 8GB内存

解决方案

降低innodb_buffer_pool_size,并修改配置文件

## 修改前的值根据内存的80%来设定
mysql> SELECT @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                7516192768 |
+---------------------------+
1 row in set (0.00 sec)
## 修改后的值2048M,这台服务器是从库不是很重要,我不想给太多资源。大家要结合自身情况
mysql> SET GLOBAL innodb_buffer_pool_size=2048*1024*1024
    -> ;
Query OK, 0 rows affected (0.10 sec)

mysql> SELECT @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                2147483648 |
+---------------------------+
1 row in set (0.00 sec)

修改后内存占用量直接下降了40%
Mysql5.7内存持续增高的解决方案及说明_第1张图片

推荐工具innotop

安装过程可以参考其他博客。用这个工具连接mysql之后可以shift+b看到innodb buffer pool的使用状态。
我参考的是Memory 2.05G(修改后),这个值修改前是7G,相当于内存的90%都被innodb buffer pool占用了。单凭这个参数就足以判定,是buffer pool占用了内存。

[RO] InnoDB Buffers (? for help) server1, 5d, InnoDB 10s :-), 9.25 QPS, 6/3/2 con/run/cac thds, 5.7.24-l

_____________________________ Buffer Pool ______________________________
Size     Free Bufs  Pages   Dirty Pages  Hit Rate     Memory  Add'l Pool
128.00k       8192  122876          154  1000 / 1000   2.05G            

_____________________ Page Statistics _____________________
Reads   Writes  Created  Reads/Sec  Writes/Sec  Creates/Sec
141879  850350   157386       0.00        0.00         0.10

______________________ Insert Buffers ______________________
Inserts  Merged Recs  Merges  Size  Free List Len  Seg. Size
                   0       0     1              0          2

___________________ Adaptive Hash Index ___________________
Size     Cells Used  Node Heap Bufs  Hash/Sec  Non-Hash/Sec
540.29k                           1      3.80          3.90
------------------------------------------------------------------------------
Buffer Pool
Size : 某sql使用Buffer Pool的大小
Free Bufs : Innodb_buffer_pool_pages_free的值,空页数;
Pages: Innodb_buffer_pool_pages_data的值, 包含数据的页数(脏或干净)
Dirty Pages : Innodb_buffer_pool_pages_dirty的值,当前的脏页数
Hit Rate: 命中率
Memory : Innodb_buffer_pool_size 的值.
Add'l Pool : innodb_additional_mem_pool_size的值
Page Statistics
Reads :   Innodb_pages_read 的值,读取的页数
Writes :   Innodb_pages_written 的值,写入的页数
Created :   Innodb_pages_created 的值,创建的页数
Reads/Sec :   每秒读取的页数
Writes/Sec :   每秒写入的页数
Creates/Sec :   每秒创建的页数
Insert Buffers
Inserts :  表示执行insert 次数
Merged Recs :  表示执行 insert 索引树合并的次数
Merges:   insert 语句合并的次数
Size: 写缓冲的大小
Free List Len  :  空闲列表长度
Seg. Size:   段块大小
Adaptive Hash Index 自适应哈希索引
Size: 哈希索引占用大小
Cells Used:
Node Heap Bufs:
Hash/Sec:  每秒哈希索引量
Non-Hash/Sec: 每秒非哈希索引的量

推荐大家了解的知识

内存分为全局内存和线程内存。判断你的问题在哪里。

全局内存你需要了解

1,innodb_buffer_pool_size 。Innodb在mysql启动的时候一次性分配整个内存给bufferpool。占得比重很大,要重点关注。
这个内存和你数据库访问量connections无关。如果你的数据访问量不大,但内存占用很高的话,就要要重点关注buffer pool相关的参数
2,key_buffer_size。如果数据里面有很多myisam的表。这个参数就需要重点关注。所有相关表的请求都会占用到这块内存。

线程内存你需要了解

首先这些参数并不是固定的,max_connections * 参数的值 然后加起来就可能是线程占用的缓存大小。如果你的访问量很大,连接数很多。下面参数就可能影响内存的占用。

每个参数都对应一种数据操作,所以你需要思考业务场景和sql代码到底哪一种操作多一些。
read_buffer_size 顺序读rows
sort_buffer_size 对表排序 sort by
read_rnd_buffer_size 随机读rows where条件多的
join_buffer_size 表关联join多的
tmp_table_size 临时表,通常是单行数据大,而且table整体很大的

注意上面只是部分参数,要总体判断自己的原因大的方向在进入一点点找出根本原因。

不定期更新一些数据库的经验总结,可以翻翻其他博客,我可能对某一个细节展开讲解。

你可能感兴趣的:(Database)