ITPub博客

首页 > 数据库 > > 如何保护SQL Server免受Linux上的OOM-killer杀掉

如何保护SQL Server免受Linux上的OOM-killer杀掉

作者:浪花小雨滴 时间:2020-05-14 15:58:33 0 删除 编辑


本文来自微软CSS团队的一篇案例分享,经过翻译整理了出来,OOM-killer在Linux上是一个头疼的问题,特别对运行在Linux上的数据库,经常会因为OOM被操作系统杀进程导致各种故障。



这是一篇关于SQL Server的AlwaysOn集群运行在Linux环境下的集群异常Failover的案例


在Windows平台上,当所有可用内存包括页文件(page file)被消耗干净,那么服务器的性能就会严重下降同时在操作系统事件日志(event log)会记录OOM(out of memory)错误。在Linux平台,这种行为会有所不同,当服务器运行在低可用内存情况下,Linux内核会选择某个可被杀掉(kill)的进程进行强杀以便恢复系统的稳定运行。这个Linux上的机制被称为OOM-Killer。


SQL Server这种比其他进程消耗更多内存的进程很可能成为被优先杀掉的对象(oom-score分数记录了可能要被杀掉的进程得分,从高到低进行kill)。


SQLServer技术支持组最近收到一个客户案例,情景如下:

数据库版本:在Red hat企业版(RHEL)上的SQL Server 2017

内存配置:服务器配置了12GB 物理内存

安装方式:以默认配置安装SQL Server

集群:业务数据库已配置AlwaysOn可用性组。集群附加在Pacemaker之上的Red hat企业版(RHEL)HA


故障现象是:当一个大表(大概25GB大小)在进行索引重建时,重建操作被终止,同时AlwaysOn可用性组Failover到其他辅助副本。在进行深入研究后发现SQL Server进程在重建索引操作时被终止。


为了定位异常关闭的原因,我们检查了Linux系统日志(RHEL上/var/log/messages)和Pacemaker日志。从日志中可以看出oom-killer被调用,然后导致SQL Server进程被终止。


下面是pacemaker日志的部分内容,在/var/log/messages文件或dmesg命令中也能看到类似内容:

Sep 13 16:17:30 l99s0004kernel: [9264025.516359] sqlservr invoked oom-killer:gfp_mask=0x280da, order=0, oom_score_adj=0 

Sep 13 16:17:30 l99s0004kernel: [9264025.516555] 184007 total pagecache pages

Sep 13 16:17:30 l99s0004kernel: [9264025.516556] 0 pages in swap cache

Sep 13 16:17:30 l99s0004kernel: [9264025.516558] Swap cache stats: add 0, delete 0, find 0/0

Sep 13 16:17:30 l99s0004kernel: [9264025.516558] Free swap  = 0kB

Sep 13 16:17:30 l99s0004kernel: [9264025.516559] Total swap = 0kB

Sep 13 16:17:30 l99s0004kernel: [9264025.516560] 3145598 pages RAM

注意:加粗部分代表服务器没有配置swap file


此外还有以下日志:

Sep 13 16:17:30 l99s0004kernel: [9264025.516658] Out of memory: Kill process 33495 (sqlservr) score 799or sacrifice child

Sep 1316:17:30 l99s0004 kernel: [9264025.516709] Killed process 33495 (sqlservr)total-vm:12119152kB, anon-rss:9675408kB, file-rss:0kB, shmem-rss:0kB

Sep 13 16:17:30 l99s0004kernel: sqlservr invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0

上面加粗部分可以看到SQL Server有一个anon-rss值9675408kB(相当于9.2GB)代表着“resident set size”,这是当前分配给进程的RAM部分。File-rss是系统所有进程在swap file(交换文件)中的内存量,当时为0KB。


当SQL Server启动时,SQL Server可用的物理内存数由memory.memorylimitmb配置选项来控制,默认为物理内存的80%,基于这个设置,SQL Server的anon-rss值9675408KB(约为12GB的80%),因为物理内存只有12GB内存。


这个值在SQL Server启动时的错误日志信息中也能看到:

2017-09-1316:23:17.62 Server Detected 9478 MB of RAM. This is an informational message;no user action is required.



在默认配置中,SQL Server可以使用大约12GB的80%即9.5GB的内存。也就是预留了大概2.5GB内存用于Linux内核和其他进程运行。

首先,SQL Server仅用了9.5GB内存的一部分,在系统上保留了大量可用内存。但是在重建索引时,SQL Server使用了超出所有可用的9.5GB内存,25GB的表需要比较多内存缓存临时数据,这时候就引起了操作系统只剩下很少内存可用,导致触发了OOM-Killer。

作为当前最高内存使用进程(oom分数最高)的SQL Server就被当作牺牲者杀掉



为了减少SQL Server占用内存太多导致被操作系统杀掉,建议使用下面的建议:

1、调整memory.memorylimitmb配置选项以便SQL Server使用了所有的配置内存也还有足够的内存供操作系统运行。

2、设置swap。

3、增加服务器的物理内存大小,毕竟12GB内存对于吃内存大户的数据库来说太少



文章来源:

How to safeguard SQL Server on Linux from OOM-Killer

https://blogs.msdn.microsoft.com/psssql/2017/10/17/how-to-safeguard-sql-server-on-linux-from-oom-killer/


插个小投票

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3161400/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    39968