二、关键指标定义1、底层分配和释放内存
2、使用C标准库的malloc()或者mmap(),就可以在堆和文件映射段分配内存了,通过free()或者ummap()进行释放
3、top关注进程
- virt是虚拟内存占用量,即便没有使用,只要申请过,就会算进去,mysql申请的virt memory是不会释放的
- res 是实际占用内存,但是不包含共享内存和swap占用
- share 是共享内存大小
- mem% 是进程占用物理内存的百分比
4、free -m
- Buffer(缓冲区) 是对磁盘数据的缓存,用来合并多次小写成为一次大写
-
Cache(缓存) 是文件数据的缓存,用来进行文件的读写,数据库针对cache的使用率非常高,因为都是从文件读取数据到内存的
三、MySQL层
1、全局级别 innodb_buffer_pool,innodb_log_buffer_size
2、会话级别 session
-
查询相关变量 sort_buffer_size,join_buffer_size,tmp_table_size等
-
事务相关变量 binlog_cache_size
-
会话相关变量 thread_stack
四、常见问题场景
-
场景1
描述 linux使用了全部内存,并且占用了swap空间,甚至导致了oom-killer -
场景2
描述 linux使用了还有大量剩余内存,但是却使用了swap空间 -
场景3
描述 linux使用了全部内存,并且占用了swap空间,但是与场景1不同点在于,mysql的innodb_buffer_pool设置的非常少.但是通过top却发现大量的内存被mysql申请占用
五、通用解决方式
1、加大内存,innodb_buffer_pool,拆分数据库 应对场景1(内存使用不足)2、可能是由于numa导致的解决方式有以下几种,应对场景2(由于numa问题导致)- mysql配置文件添加 innodb_numa_interleave=on
-
mysql启动时候添加 numactl --interleave=all 参数
- Linux Kernel启动参数中加上numa=off
- pmap -d 看一下进程的内存情况,发现anoa的量很大(anoa代表进程主动申请内存)
- 打开mysql关于内存使用的统计
- 应该是由于thread导致的,所以根据thread进行分析具体占用(5.7),具体语句:
定位具体thread_idselect thread_id,event_name, SUM_NUMBER_OF_BYTES_ALLOC from memory_summary_by_thread_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc limit 20;定位具体线程select * from threads where thread_id=thread4、进行线程的具体分析
六、总结
内存问题一般深入都比较复杂,有些方面需要分析线程源码,希望借此为大家分析问题提供一个思路。
















