在单独部署的mysql数据库服务器中发现,在高并发的情况下发现内存不够用,进一步发现swap的利用率很高。公司的DBA提了两点建议:1、建议先减小数据库缓冲池(buffer pool)的大小;2、进行数据库内存扩容
1、首先,不是内存不够用吗?swap利用率为什么高呢?swap是什么呢?
swap space是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组合。简单点说,当系统物理内存吃紧时,Linux会将内存中不常访问的数据保存到swap上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问swap上存储的内容时,再将swap上的数据加载到内存中,这就是我们常说的swap out和swap in。
要回答这个问题,就需要回答swap给我们带来了哪些好处。
虽然大部分情况下,物理内存都是够用的,但是总有一些意想不到的状况,比如某个进程需要的内存超过了预期,或者有进程存在内存泄漏等,当内存不够的时候,就会触发内核的OOM killer,根据OOM killer的配置,某些进程会被kill掉或者系统直接重启(默认情况是优先kill耗内存最多的那个进程),不过有了swap后,可以拿swap当内存用,虽然速度慢了点,但至少给了我们一个去debug、kill进程或者保存当前工作进度的机会。
上面介绍了swap的优点,那swap的缺点呢?swap是存放在磁盘上的,磁盘的速度和内存比较起来慢了好几个数量级,如果不停的读写swap,那么对系统的性能肯定有影响,尤其是当系统内存很吃紧的时候,读写swap空间发生的频率会很高,导致系统运行很慢,像死了一样,这个时候添加物理内存是唯一的解决办法。
由于系统会自动将不常用的内存数据移到swap上,对桌面程序来说,有可能会导致最小化一个程序后,再打开时小卡一下,因为需要将swap上的数据重新加载到内存中来。
上面介绍了什么是swap以及它们的优缺点,那么到底要不要配置swap呢?答案是:看情况。
下面分别讨论内存不够用、内存勉强够用和内存很充裕这三种情况下服务器和桌面环境对swap的选择。
不管是桌面还是服务器,当物理内存明显不够用,而又想跑程序的话,添加swap是唯一的选择,慢点总比不能工作强。
建议配置swap,这样内核会将不常用的数据从内存移到swap上,从而有更多的物理内存供系统调用,提升系统性能,同时也避免因偶尔的物理内存不够造成进程异常退出,提升系统稳定性,但对服务器来说,一定要限制或者监控swap空间的使用情况,当出现swap空间使用超预期或者swap in/out频繁时,要及时采取措施,不然对性能影响很大
理论上来说,如果物理内存足够多并且不需要休眠功能,那swap就没什么用,可关键问题是我们很难保证物理内存在任何情况下都够用,因为总有意想不到的情况发生,比如某些进程耗内存超预期,服务器压力超预期,内存泄漏等。
目前,我们是明显内存不够用了,是什么导致内存不够用了呢?为什么mysql会直接导致服务器内存不够了
假设我们的物理内存是16G,swap是4G。如果MySQL本身已经占用了12G物理内存, 而同时其他程序或者系统模块又需要6G内存,这时候操作系统就可能把MySQL所拥有的一部分地址空间映射到swap上去。
说白了,就是系统认为你mysql占用的空间太大了,不允许你搞特殊,必须腾出空间让那个我的其它必要的进程区使用内存,所以你就去比较慢的swap去玩吧!而mysql中占内存最大的就是innodb_buffer_pool_size了,所以第一时间应考虑到这个值是不是设置的不合理?
MySQL的内存消耗分为:
1.会话级别的内存消耗:如sort_buffer_size等,每个会话都会开辟一个sort_buffer_size来进行排序操作
2.全局的内存消耗:例如:innodb_buffer_pool_size等,全局共享的内存段
这也是我觉得我们DBA不专业的地方,并没有考虑第一种情况,去查看回话级别的内存消耗情况,而是直接跟我说要调小innodb_buffer_pool_size
缓存表数据与索引数据,把磁盘上的数据加载到缓冲池,避免每次访问都进行磁盘IO,起到加速访问的作用。
给 Buffer Pool 分配越大的内存,MySQL 的并发性能就越好。那是不是都应该将百分之九十九的机器的内存都分配给 Buffe Pool 呢?
当然不是!先不说操作系统内核也需要几个G内存,MySQL 除了 Buffer Pool 还有很多别的内存数据结构呢,这些都是需要内存的,所以说,上面的想法是绝对不行的!
比较合理的比例,应该是 Buffer Pool 的内存大小占机器总内存的 50% ~ 60%。
可以通过show engine innodb status\G; 查看命中情况. 当命中没达到97%以上,都可以考虑加内存,当然这个和业务也有关例如对一个master的写入量大,读少就是特例. 其它情况如果没达到97%以上,对于读取多的情况,如果没达到98%以上,都说明buffer不够.可以扩. 再从另一方面来讲如果给分了20%的内存命中都能达到100%了,而且还有大量的free page那说明,那就够用了,另外也可以跟据free page去算一下可以再减少点内存. 把那些内存用到别用呢