systemdでmysqldのulimitとoom_score_adjを調整

typoしたら値が反映されてなかったので備忘録。
要はメモリ不足でmysqldが落ちる挙動の予防とファイルディスクリプタ不足の予防で上限緩和をしたい件。

```
# mkdir /etc/systemd/system/mysqld.service.d
# vi /etc/systemd/system/mysqld.service.d/override.conf
[Service]
OOMScoreAdjust=-1000
LimitNOFILE=65535

# systemctl daemon-reload
# systemctl restart mysqld.service
```
または`systemctl edit mysqld.service`で編集しても同じ。
Serviceセクションの先頭は大文字必須なのでtypoに注意。

```
# systemctl status mysqld.service
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/mysqld.service.d　#★追加したファイルが読まれてることがわかる
           └─override.conf
   Active: active (running) since 水 2018-06-06 14:57:06 JST; 6s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 25243 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 25225 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 25247 (mysqld)  #★プロセスIDを確認
   CGroup: /system.slice/mysqld.service
           └─25247 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.p...

 6月 06 14:57:05 myhost1 systemd[1]: Starting MySQL Server...
 6月 06 14:57:06 myhost1 systemd[1]: Started MySQL Server.

# cat /proc/25247/oom_score_adj #★プロセスIDのディレクトリのしたの状態ファイルを確認する
-1000

# dstat --top-oom　#★killされる優先度が高い順にでるのでmysqldが出てこなければOK
                   # 初期状態だとスコア256くらいで真っ先にkillされる高優先度。
--out-of-memory---
    kill score    
tuned          15 
tuned          15 
tuned          15 
tuned          15 
tuned          15

# cat /proc/25247/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             3863                 3863                 processes 
Max open files            65535                65535                files
  #★設定したとおりになってるか↑確認（初期値はsoft1024,hard4096 ）   
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       3863                 3863                 signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us        
```


http://www.matzblog.net/archives/574/index.html
https://chuckyz.wordpress.com/2016/12/28/centos-7-disabling-oomkiller-for-a-process/

taskさんこう

```yaml:task-file
- name: create mysqld(systemd)s custom directory
  file:
    path: /etc/systemd/system/mysqld.service.d/
    state: directory
    mode: '0755'
    owner: root
    group: root

- name: set mysqld(systemd)s custom unitfile
  template:
    src: mysqld.service.j2
    dest: /etc/systemd/system/mysqld.service.d/override.conf
  notify: run-daemon-reload

- meta: flush_handlers
```
```yaml:template-file
[Service]
OOMScoreAdjust=-1000
LimitNOFILE=65535
```
```yaml:handler-file
- name: run-daemon-reload
  command: systemctl daemon-reload
#  service:
#    daemon_reload: yes ##ansible2.4~
```
http://docs.ansible.com/ansible/latest/modules/systemd_module.html
metaでflush_handlers指定すると呼び出し済みで未実行のhandlersが実行される模様。
daemon-reloadしてからデーモンをrestartしないとsystemdのunitファイルに書いたやつは反映されないようなので注意。

まあoom_killerに狙われなくするのは単なる保険で搭載メモリより多くを割り当てないほうがだいじで[mysqltuner](https://github.com/major/MySQLTuner-perl)かなにかで診断して落ちないようにしといたほうが関係者全員が安眠できる確率があがりそう。
あとファイルディスクリプタは`table_open_cache*max_connections`より多いほうがよさそう。
https://dev.mysql.com/doc/refman/8.0/en/table-cache.html

ちなみにsystemdじゃなくてinitの起動スクリプトだとスタートセクションを以下のようにしてました。ulimitは/etc/security/limits.d/90-nproc.confあたりだったかな。

```shell:/etc/init.d/mysqldの一部
  'start')
    # Start daemon
####～略～
      # Make lock for RedHat / SuSE
      if test -w "$lockdir"
      then
        touch "$lock_file_path"
      fi

      if [ -f "$mysqld_pid_file_path" ]; then
          MYSQLPID=`cat "$mysqld_pid_file_path"`
          echo -17 > /proc/$MYSQLPID/oom_adj
          echo -1000 > /proc/$MYSQLPID/oom_score_adj
          SAFEPID=`ps aux|grep '[/]bin/sh /usr/bin/mysqld_safe'|awk '{print $2}'`
          /bin/kill -9 ${SAFEPID}
      fi

      exit $return_value
    else
      log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"
    fi
    ;;
```

今回コンテナは何の関係もないですが若干気になって調べたらコンテナではdockerのバージョンにもよるけどコンテナ起動時の--ulimit"や`--oom-kill-disable`というオプションで制御可能っぽいですね。へー。
https://qiita.com/irotoris/items/944aba5e448a8e723ff6
https://knowledge.sakura.ad.jp/5118/
https://qiita.com/minodisk/items/547741b73763f2bab6b8#oomkilled

ということで、ステートフルなバックエンド側は落ちたらデータ同期してる先に切り替えてとか冗長構成復旧に要する色々があるので落ちない方がいいという関連の設定の話でした。

最近みたmariadb10.4には設定が入っていたけど、ulimitはいいけどoomはコメント外したほうがよさそうでした。

```
# egrep -i -a 'oom|limitn' /usr/lib/systemd/system/mariadb.service
# OOMScoreAdjust=-600
LimitNOFILE=16384
```