[聚合文章] [译]如何保护SQL Server免受Linux上的OOM-killer杀掉

SQL Server 2018-01-30 15 阅读

今天机缘巧合搜到一篇微软CSS团队的一篇案例分享,在本人学习SQL On Linux过程中,对很多知识点存在不理解,看了这篇文章之后,觉得很有必要存起来,不管有没有其他人看,对我自己还是很有用,所以决定翻译一下,我相信在不久的将来这篇文章会被重视,因为SQL On Linux已经出来了一段时间,并且部分客户已经在用,国内市场的改变也只是时间上的问题。

这是一篇关于SQL Server运行在Linux环境下的异常Failover场景的案例,下面是译文,读者如有兴趣可以阅读原文: How to safeguard SQL Server on Linux from OOM-Killer

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

  对于 SQL Server 所在的服务器, SQL Server 这种比其他进程消耗更多内存的进程很可能成为被优先杀掉的对象(oom-score记录了可能要被杀掉的进程的得分,从高到底进行kill)。本文将回顾一个客户场景,它强调了在 Linux 上安装 SQL Server 后,需要进行额外的配置调整。

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

  • Red hat 企业版(RHEL)上运行 SQL Server 2017
  • 服务器安装了12G 内存
  • 以默认配置安装 SQL S erver
  • 部分数据库已配置 AlwaysOn 可用性组。集群是 附加在 Pacemaker 之上的 Red hat 企业版 RHEL HA

 现状是: 当在一个大表(大概 25G )在进行索引重建时,重建操作被终止,同时可用性组 Failover 到其他副本。在进行深入研究后发现 SQL Server 进程在重建索引操作运行时被终止并导致 Failover

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

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

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

同时日志也包含了在 OOM- Killer 发起时所有系统进程的内存消耗快照。下面是整理过格式的结果:

Pid

Uid

Tgid

Total_vm

Rss

Nr_ptes

Swapents

Oom_score_adj

name

46206

0

46206

26370

247

54

0

-1000

Sshd

33492

992

33492

49412

3805

46

0

0

Sqlservr

33495

992

33495

3029788

2418852

5059

0

0

Sqlservr

注意:加粗部分的数值是在 4K 页, R ss 列(内存使用)的 SQL Server 进程接近 9448MB 2418852*4 /1024

此外还有:

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 代表着“ 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 的内存(译者注:索引重建理论上需要 1~1.2 倍左右的临时存储空间,而大部分处于内存的缓存当中, 25G 的表显然足够撑爆 9.5G 内存)。这时候就引起了 Linux 服务器只剩下很少内存可用,导致触发了 OOM-Killer 。作为当前最高内存使用进程( oom 分数最高)的 SQL Server 就被当作牺牲者杀掉,

为了减少 SQL S erver OOM 影响,建议使用下面的一个或者两个:

  1. 调整 memory.memorylimitmb 配置以便即使 SQL Server 使用了所有的配置内存也还有足够的内存供操作系统运行。
  2. 确保 swap 文件存在并大小合理。

在这个客户场景中,通过设置 memory.memorylimitmb 6GB 或者创建 swap 文件并调整大小来避免了 oom-killer 再次运行。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。