未加星标

MySQL的内存和相关问题排查

字体大小 | |
[数据库(mysql) 所属分类 数据库(mysql) | 发布者 店小二04 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

我们都知道数据库是IO密集型一类应用,为了提高其性能大量使用内存代替文件(交换分区)的IO操作是保证数据库稳定、高效的基本原则。那么数据库是如何使用内存的,我们如何查看数据库内存的占用,如何通过通过数据库内存配置设置提高其性能?本文虫虫就以mysql数据库(InnoDB引擎)为例和大家一起了解下linux数据库和内存相关的主题。


MySQL的内存和相关问题排查

读取内存数据非常快,为了提高性能我们要尽最大可能把数据集都放到内存中以保证高效。但是Swap交换分区作为一个救命的稻草,我们还必须要给mysql设置,防止突发情况下内存不够,mysql服务直接被OOM杀掉的情况。同时mysql交换分区占用也是我们衡量一个数据是否健康与否的手段,如果一个数据库频繁的使用了swap则说明,我们需要人工干预优化数据库了。

内存占用

在Linux下,我们可以通过使用一些shell命令来了解MySQL的内存使用情况。

首先使用ps命令来查看mysqld进程的内存使用情况:

ps-eosize,pid,user,command--sort-size|grepmysqld |awk'{hr=$1/1024;printf("%13.2fMB",hr)}{for(x=4;x<=NF;x++){printf("%s",$x)}print""}' |cut-d""-f2|cut-d"-"-f1
MySQL的内存和相关问题排查
1990.88MB/usr/local/mariadb/bin/mysqld 0.49MB/bin/sh/usr/local/mariadb/bin/mysqld_safe

top命令也可以查看对应上面的结果也可以用top来得到:

top-b-o%MEM-n1-p$(pidofmysqld)|grepPID-A
MySQL的内存和相关问题排查
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND 2239mysql20021085363168367548S0.04.048:47.37mysqld

其中, VIRT(virtual memory usage) 表示mysql使用的虚拟内存总量。它包括所有代码,数据和共享库以及最终要被置换出的页面。

RES(resident memory usage) 常驻内存, 包括当前进程使用的内存,不包括置换出的内存。

SHR(shared memory) 共享内存, 进程使用的的共享内存,也包括其他进程的共享内存。

交换分区

我们再来检查检查mysqld是否正在使用交换分区,首先用free -m检查是否有用到交换分区。

free-m
MySQL的内存和相关问题排查
totalusedfreesharedbuff/cacheavailable Mem:782250911788325522290 Swap:399923997

上面结果了,系统使用少量的交换分区(2M),那怎么判断是不是MySQL用的呢?我们来验证:

cat/proc/$(pidofgitlab)/status|grepSwap
MySQL的内存和相关问题排查

VmSwap:0 kB

可见mysqld不没用用到交换区,说明我的mysqld在高效运行中。

这儿我们提供一个脚本,遍历每一个进程,找出那些进程使用了交换分区:

foriin$(ls-d/proc/[0-9]*) do out=$(grepSwap$i/status2>/dev/null) if["x$(echo$out|awk'{print$2}')"!="x0"]&&["x$(echo$out|awk'{print$2}')"!="x"] then echo"$(ps-p$(echo$i|cut-d'/'-f3) |tail-n1|awk'{print$4'}):$(echo$out|awk'{print$2$3}')" fi done
MySQL的内存和相关问题排查

当然,交换中的页面可能已经存在很长时间了,自从使用一次后,后面就没有在用过。为了获取实时交换分区情况,我们可以用 vmstat :

vmstat110
MySQL的内存和相关问题排查

在这个服务器上,我们可以看到mysqld没有使用交换,如果系统内存充足,但是mysqld还占用了部分交换分区,是怎么回事?怎么排查呢?

如果遇到这种情况,可能的直接原因有swappiness和Numa。

Swappiness

swappiness参数控制内核将进程移出物理内存并将其放入交换磁盘分区的趋势。我们之前也说过了磁盘IO操作要比RAM慢很多很多,因此如果进程过于频繁地从内存中置换出,这会导致系统和应用程序的响应时间变慢。高swappiness值意味着内核更容易取消内存页面。低swappiness相反,内核将不太容易取消内存页面。swappiness值越高,系统内存置换的越多。

linux下系统(CentOS、Red Hat、ubuntu)默认的swappiness值为60。如果内存较小则应适当调高这个值。对于内存足够的MySQL服务器,这个默认设置就有点太高了,应该减少。一般情况下,业界建议这个值可以设置到5.或者更小。设置swappiness方法是使用 sysctl 命令直接改变内核参数。

sysctl-wvn.swappinness=1 NUMA设置

还有一个方面就是NUMA设置。对于具有多个NUMA核心的服务器,建议将NUMA模式设置为交错,以平衡所有节点的内存分配。 在最新的MySQL 8.0中支持为InnoDB设置NUMA。可以在配置通过启动: innodb_numa_interleave = 1

要检查是否有多个NUMA节点,可以使用numactl -H

这是两种不同的输出:


MySQL的内存和相关问题排查
MySQL的内存和相关问题排查

我们可以看到,当有多个NUMA节点(下)时,默认情况下,内存不会在所有节点之间平均分配。这可以导致更多内存置换。

文件系统缓存

默认情况下,Linux将使用文件系统会对所有的I/O操作进行缓存(这是不建议使用MyISAM的原因之一,MyISAM存储引擎依赖于FS缓存,并且可能导致丢失数据)。Mysql InnoDB引擎中使用O_DIRECT作为innodb_flush_method,MySQL将绕过文件系统缓存,不会将任何FS Cache Memory用于数据文件(* .ibd)。

当然在MySQL中使用的其他非数据文件仍会使用FS Cache。我们来看个例子:

dbsakefincorebinlog.000017 binlog.000017:total_pages=120841cached=50556percent=41.84 ls-lhbinlog.000017 -rw-r-----1mysqlmysql473MSep1807:17binlog.000017 free-m totalusedfreesharedbufferscached Mem:5965460813561284352456 -/+buffers/cache:17164249 Swap:2045302015 dbsakeuncachebinlog.000017 Uncachedbinlog.000017 #free-m totalusedfreesharedbufferscached Mem:5965441315521284352259 -/+buffers/cache:17184247 Swap:2045302015

开始检查文件系统缓存中存在多少二进制日志(使用dbsake fincore),我们可以看到473M中有42%使用RAM作为FS缓存。然后我强制取消在缓存中使用这些页面(使用 fincore uncache ),结果,我们释放了+/- 195MB的RAM。

本文数据库(mysql)相关术语:navicat for mysql mysql workbench mysql数据库 mysql 存储过程 mysql安装图解 mysql教程 mysql 管理工具

代码区博客精选文章
分页:12
转载请注明
本文标题:MySQL的内存和相关问题排查
本站链接:https://www.codesec.net/view/610933.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 数据库(mysql) | 评论(0) | 阅读(118)