CentOS7でSystemdがメモリリークしていて使用率がジワジワと上昇していた

ほとんどサービス動いてないサーバが急にメモリ使用率の警告出したので調べて見たら、1日に30MBくらい、1ヵ月で1GBくらいジワジワとSystemdがメモリリークしていたという話です。

事象

Systemdが異常にメモリを使っている。

$ ps aux | head
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.2 60.9 2327496 2207392 ?     Ss    1月15 191:31 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
root         2  0.0  0.0      0     0 ?        S     1月15   0:00 [kthreadd]
...

何も動いていないのに2GBも何に使っているの?となった。

原因

結論から言うと、こちらのバグが原因です。 1308780 – systemd Using 4GB RAM after 18 Days of Uptime

今回のマシンも完全にひっかかっている。

$ yum info installed systemd
Loaded plugins: auto-update-debuginfo, fastestmirror
Installed Packages
Name        : systemd
Arch        : x86_64
Version     : 219
Release     : 19.el7_2.7
Size        : 21 M
Repo        : installed
From repo   : updates
Summary     : A System and Service Manager
URL         : http://www.freedesktop.org/wiki/Software/systemd
License     : LGPLv2+ and MIT and GPLv2+
Description : systemd is a system and service manager for Linux, compatible with
            : SysV and LSB init scripts. systemd provides aggressive parallelization
            : capabilities, uses socket and D-Bus activation for starting services,
            : offers on-demand starting of daemons, keeps track of processes using
            : Linux cgroups, supports snapshotting and restoring of the system
            : state, maintains mount and automount points and implements an
            : elaborate transactional dependency-based service control logic. It can
            : work as a drop-in replacement for sysvinit.

暫定対応

上記の通り原因はメモリリークなのですが、以下のコマンドで不要メモリを解放できるので、一時しのぎはできます。

# systemctl daemon-reexec

このオプションの内容ですが以下の通り。内容読む限りでは大きな問題起こらなそうですが、できればサービス影響出ないタイミングで行いたいところです。

daemon-reexec
  Reexecute the systemd manager. This will serialize the manager state, 
  reexecute the process and deserialize the state again. This command is of
  little use except for debugging and package upgrades. Sometimes, 
  it might be helpful as a heavy-weight daemon-reload. While the daemon is being
  reexecuted, all sockets systemd listening on behalf of user configuration will stay accessible.

恒久対応

こちらのコミットでBugFixがマージされています。

github.com

BugFixがあたったパッケージへアップデートをすることで対応できます。 アップデート対象になるバージョンを確認して、

$ yum info installed systemd
<略>---
利用可能なパッケージ
名前                : systemd
アーキテクチャー    : x86_64
バージョン          : 219
リリース            : 30.el7_3.7
<略>---

影響等調べて問題無いならアップデート。これで恒久対応完了。

yum update systemd

追記

Sessionが大量に溜まりログオンなどの動作が不安定になる事象が発生するので、作業後はOSの再起動をすることをオススメします。

systemd-logind leaves thousands of session files - CentOS

0014278: systemd update causes /run tmpfs to fill up with sessions - CentOS Bug Tracker

参考URL

systemdのメモリリークについて – とあるサーバエンジニアの備忘録