4GB VPSでMariaDBのswap使用量が増加したときの調査と設定見直し

物理メモリ約4GBのVPSでWordPressを運用していたところ、サーバー負荷が高くなり、MariaDBを再起動する事態になりました。サーバーの状態を見ると、約2GBのswap領域のうち、およそ1.1GBが使われていました。

swapが使われているだけで障害や設定ミスと決めつけることはできません。ただ、swapへの読み書きが続いている場合や、WordPressの応答が不安定な場合は、物理メモリに対してMariaDBの設定が大きすぎないか疑ってみる価値があります。

今回の環境では、innodb_buffer_pool_sizeに3GBを割り当てていました。しかし、4GBの物理メモリはMariaDBだけのものではありません。OS、Webサーバー、PHP、KUSANAGI、ファイルキャッシュにもメモリが要ります。現在のメモリ状況とswapの動きを確認したうえで、buffer poolを3GBから2GBへ見直しました。以下、確認した項目、設定変更の考え方、変更後に見ているポイントを、実際の流れに沿って書いていきます。

この記事の前提:swapの使用量だけを見て異常と決めつけず、メモリの空き状況、swapの入出力、MariaDBの処理状況、WordPressの応答を組み合わせて判断します。

今回使用していたサーバー環境

対象は、AlmaLinux 9とKUSANAGI 9を使ったWordPress環境です。物理メモリは約4GB、確認時点で約2GBのswap領域がありました。データベースはMariaDBで、WordPress、PHP、Webサーバー、OSと同じVPS上で動いています。

サーバーの主な構成

項目 構成
OS AlmaLinux 9
実行環境 KUSANAGI 9
CMS WordPress
データベース MariaDB
物理メモリ 約4GB
swap 約2GB

変更前のMariaDB設定

変更前は、InnoDBのデータやインデックスをキャッシュするinnodb_buffer_pool_sizeを3GBにしていました。約4GBの物理メモリに対して3GBなので、単純計算でもMariaDBのbuffer poolだけでメモリ全体の約8割を占めます。

[mysqld]
innodb_buffer_pool_size=3G

MariaDBが使うメモリはbuffer poolだけではありません。接続ごとのバッファ、ソート処理、一時テーブル、各種キャッシュにもメモリを使います。同じVPS上ではPHPやWebサーバーも動きます。4GB環境で3GBを割り当てる設定は、アクセス数やプラグインの処理内容によっては余裕が足りなくなります。

発生していた症状

確認を始めたきっかけは、WordPressの応答が不安定になり、サーバー負荷が高くなったことです。管理画面やWebページの表示が普段より遅くなり、MariaDBを再起動して状態を立て直しました。

データベースの再起動で一時的に良くなっても、原因が設定やメモリ不足なら、同じ症状がまた出ます。再起動だけで終わらせず、物理メモリとswapの使用状況を確認しました。

swapが約1.1GB使用されていた

当時の確認結果では、物理メモリの合計が約3919MB、swapの合計が約2047MBで、そのうち約1107MBが使われていました。

Mem:   total 3919MB
Swap:  total 2047MB
       used 1107MB

ここで気をつけたいのは、swapが1.1GB使われているという数値だけでは、今も深刻なメモリ不足が続いているか判断できないことです。Linuxでは、使用頻度が低いと判断されたメモリ領域がswapへ移され、その後もswap上に残ります。負荷が下がっていても、swapの使用量だけが多く見えることがあります。

ただ、WordPressの応答遅延やMariaDBの不安定化が同時に起きているなら、swapの読み書きで処理が遅くなっていないか調べます。使用量に加えて、現在もswapへの退避や読み戻しが続いているかどうか。ここが判断の分かれ目です。

注意:swapを使用しているだけで、直ちに障害とは限りません。応答速度、メモリのavailable、swapの入出力、ディスク待ち時間などを合わせて確認してください。

最初に確認した項目

MariaDBの設定を変える前に、まず現在の状態を見ます。設定値だけを見て変更すると、別の原因を見落としたり、必要なキャッシュまで削ったりします。今回は、freevmstat、MariaDBのSHOW FULL PROCESSLISTで状況を整理しました。

設定値を変える前に現状を測るという順番は、別の製品でも同じでした。AgileWorksのジョブマネージャーがGC overhead limit exceededで停止した件でも、ヒープを増やす前にjcmdで実際の使用状況を確認しています。

freeコマンドでメモリ使用量を確認する

free -m

free -mでは、メモリ容量をMB単位で確認できます。見るのは、usedfreebuff/cacheavailable、swapのusedです。

Linuxは、空いているメモリをファイルキャッシュとして積極的に使います。freeの値が少ないだけでメモリ不足と判断するのは適切ではありません。アプリケーションが追加で使えるメモリの目安として、availableも見ます。

vmstatでswapの入出力を確認する

vmstat 1 5

1秒間隔で5回、CPU、メモリ、swap、I/Oの状態を確認します。主に見るのは、swpdsisowaidです。

  • swpd:使用中のswap容量
  • si:swapから物理メモリへ読み戻した量
  • so:物理メモリからswapへ書き出した量
  • wa:CPUがI/O完了を待っている時間の割合
  • id:CPUが何も処理していない時間の割合

swpdが多くても、sisoが継続して0に近ければ、過去に退避されたデータがswapへ残っているだけです。アクセス中にsisoが繰り返し増え、waも高くなるようなら、swapの読み書きが応答速度に効いています。

実際の環境で実行した結果が次です。

[root@server ~]# vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0 1443044 267500  57512 2070540    4    7    79    25   52  107  5  2 93  0  0
 0  0 1443044 265752  57512 2070556    8    0     8     8  958  942  2  1 96  0  0
 0  0 1443044 266032  57520 2070552    0    0     0   124  551  499  0  0 100  0  0
 0  0 1443044 264080  57520 2070552    0    0     0     0  932  786  3  1 96  0  0
 0  0 1443044 263952  57520 2070556    0    0     0     0  978  809  1  1 98  0  0

読むときに気をつけたいのは、1行目は起動してからの平均値だという点です。ここに出る siso は累積の平均なので、いま起きていることを表していません。現在の状態は2行目以降で見ます。

2行目以降を見ると、si は1回だけ8が出て、あとは0。so は最初から最後まで0です。swpd は約1,443,000KB、つまり1.4GB程度がswapに置かれたままですが、そこへの読み書きはほとんど発生していません。

swapに「置かれている」ことと、swapを「使い続けている」ことは別です。前者は、過去に一度退避されたページがそのまま残っているだけで、性能には影響しません。問題になるのは後者、つまり siso が継続的に動いている状態です。

MariaDBで重い処理が動いていないか確認する

SHOW FULL PROCESSLIST;

MariaDBへ接続して、長時間実行されているSQL、ロック待ち、同じ処理の大量実行、Sleep状態の接続が増えていないかを見ます。WordPressでは、プラグインによる集計処理、検索処理、バックアップ、アクセス解析、定期実行が負荷になることがあります。

メモリ設定だけでなく処理内容にも問題があるなら、buffer poolを縮小しても解決しません。まず負荷の高いSQLや接続数の増加がないかを見て、そのうえでメモリ配分を決めます。

swap使用量が多くなった原因を考える

今回の環境で引っかかったのは、物理メモリ約4GBに対してinnodb_buffer_pool_sizeが3GBだった点です。buffer poolは、InnoDBのデータやインデックスをメモリ上へ保持して、ディスクアクセスを減らすためのものです。十分な容量があれば、データベースの処理速度は上がります。

ただ、buffer poolは大きければ大きいほどよいわけではありません。専用のデータベースサーバーなら、物理メモリの多くをMariaDBへ割り当てる設計もあります。今回のようにWordPress、PHP、Webサーバー、MariaDBを同じ4GB VPSで動かすなら、ほかのプロセスが使うメモリを残しておきます。

buffer pool以外にもメモリが必要になる

MariaDBは、buffer pool以外にも接続や処理内容に応じてメモリを使います。ソート処理用のバッファ、結合処理用のバッファ、一時テーブル、接続スレッドなどで、同時接続数や実行されるSQLによって増減します。

PHPの同時実行数が増えれば、PHPプロセスが使うメモリも増えます。WordPressの管理画面、画像処理、バックアップ、インポート、ページ生成では、1リクエストあたりの使用量が大きくなります。NginxまたはApache、KUSANAGIの関連プロセス、OSのファイルキャッシュにもメモリが要ります。

4GBをMariaDBだけで使えるわけではありません。

buffer poolを3GBにすると、残りの約1GBでOS、PHP、Webサーバー、MariaDBの追加領域をまかなう必要があります。アクセスの集中や重い処理が重なると、物理メモリが不足し、使用頻度の低い領域がswapへ移される可能性があります。

swap使用量の数値だけで原因を断定はできません。ただ、4GB環境に対して3GBのbuffer poolは余裕が少ないと判断して、OSやPHPなどが使える領域を増やす方向で設定を見直しました。

物理メモリ約4GBに対し、innodb_buffer_pool_sizeを3GBから2GBへ変更したときのメモリ配分の比較図

MariaDBの公式ドキュメントでも、buffer poolを大きくしすぎるとスワッピングを招き、大きくしたことによる恩恵をかえって打ち消してしまうと説明されています。あわせて、RAMの大部分をbuffer poolへ割り当てるという一般的な推奨は、同じサーバーで他のものも動かしている場合には当てはまらないとも書かれています。WordPressと同居している今回の環境は、まさに後者にあたります。

出典:InnoDB Buffer Pool – MariaDB Documentation

実施した対応

今回は、swap領域を保険として確保したうえで、innodb_buffer_pool_sizeを3GBから2GBへ縮小しました。swapを増やすこと自体を根本解決にしない、というのがここでの前提です。

swap領域を確認して必要な容量を確保する

swapは、物理メモリが一時的に足りなくなったときに、プロセスが強制終了されるリスクを下げる保険になります。swapが設定されていない場合や容量が極端に少ない場合は、サーバーの構成を確認したうえで、2GB程度を確保する方法があります。

ただし、swapはディスク上の領域なので、物理メモリよりアクセスは遅くなります。swapを追加して強制終了を回避できても、継続的に読み書きが発生すれば、WordPressやMariaDBの応答は遅くなります。swapの確保と同時に、物理メモリ内へ収まりやすい設定へ見直します。

innodb_buffer_pool_sizeを3GBから2GBへ変更する

[mysqld]
innodb_buffer_pool_size=2G

2GBへ下げたのは、MariaDB以外のプロセスが使えるメモリを確保するためです。buffer poolを1GB減らせば、OS、PHP、Webサーバー、MariaDBの接続処理が使える余地が増えます。メモリ不足によるプロセス終了や、swapへの頻繁な退避も抑えられます。

ただ、2GBがすべての4GB VPSに合うわけではありません。データベース容量、アクセス数、PHPの同時実行数、プラグイン、キャッシュ構成によって適正値は変わります。今回は、WordPressを運用する小規模な4GB環境で、3GBでは余裕が少ないと判断した事例です。

設定変更前の注意:設定ファイルの保存場所は環境によって異なります。変更前に設定ファイルをバックアップし、記述ミスがないことを確認してからMariaDBを再起動してください。

MariaDBを再起動する

設定ファイルを変更したら、MariaDBを再起動して設定を反映します。

sudo systemctl restart mariadb

再起動後は、サービスが正常に起動しているか確認します。

sudo systemctl status mariadb

サービスが起動していても、設定が意図した値になっているとは限りません。MariaDBへ接続して、現在の設定値を見ておきます。

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

設定値はバイト単位で表示されることがあります。変更後の値を記録して、再起動前後で比較できるようにしておくと、後から状況を追えます。

設定変更後に確認したこと

MariaDBが正常に再起動したのを確認したら、そこで終わりにせず、サーバー全体の状態を見続けます。目的は、swapの表示値をゼロにすることではなく、WordPressとMariaDBが安定して動くメモリ配分にすることです。

MariaDBが正常に起動しているか

まずsystemctl status mariadbでサービスの状態を確認します。起動に失敗しているなら、設定ファイルの記述ミス、単位の指定、同じ項目の重複を疑います。MariaDBのログにエラーが出ていないかも見ます。

メモリとswapの使用量

次にfree -mを実行して、availableが極端に少なくなっていないか、swapの使用量が急増していないかを確認します。MariaDBの再起動直後だけでなく、通常アクセス時、管理画面の操作時、バックアップ実行時など、負荷の違うタイミングで見ておきます。

変更からしばらく運用した時点で、あらためて確認しました。

[root@server ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           3919        1583         256           0        2078        2099
Swap:          2047        1409         638

正直に書くと、swapの使用量は減っていません。変更前は約1,107MBでしたが、この時点では1,409MBに増えています。数字だけを見れば、対応が失敗したように読めます。

それでも問題ないと判断したのは、前述の vmstatsiso がほぼ0だったからです。1.4GBがswapに置かれてはいますが、そこを読み書きしていないので、ディスクI/Oは発生していません。

Linuxは、しばらく使われていないページを積極的にswapへ退避し、空いた物理メモリをファイルキャッシュへ回します。上の出力でも buff/cache が2,078MBあり、available は2,099MBです。すぐに使える状態のメモリが約2GBある、ということで、変更前より余裕があります。

swap使用量を減らすことは、そもそも目的ではありませんでした。目的は、物理メモリの取り合いをなくして、swapへの読み書きが続く状態を避けることです。その意味では、使用量が増えていても siso が止まっているなら、狙いどおりということになります。「swapが減ったかどうか」で成否を判定していたら、この結果は失敗に見えたはずです。

継続的なswap入出力が発生していないか

vmstat 1 5で、sisoが継続して増えていないかを確認します。swapの使用済み容量が残っていても、入出力が落ち着いていて、WordPressの応答にも問題がなければ、無理にswapを解放しなくてかまいません。

WordPressの表示や管理画面に問題がないか

最後に、公開ページ、管理画面、投稿編集、画像アップロード、プラグインの処理を確認します。データベース設定を変えた後は、サービスが起動しているだけでなく、実際の操作に問題がないところまで見ておきます。

変更後に記録しておきたい項目

  • MariaDBの起動状態
  • 物理メモリのavailable
  • swapの使用量
  • vmstatsiso
  • WordPressの表示速度と管理画面の動作
  • 確認日時とアクセス状況

なお今回は、設定変更による改善率や処理時間の変化を厳密に測っていません。「何%高速化した」といった書き方は避けて、確認できた範囲の数値と動作状況を記録する形にしています。

swapの使用量だけで判断しない

サーバー監視では、swapの使用量が増えていると不安になります。でも、swapが使われていることと、今サーバーがメモリ不足で苦しんでいることは、必ずしも同じではありません。

過去に退避されたメモリが残る場合がある

Linuxでは、長時間使われていないメモリ領域がswapへ退避されます。その後で物理メモリに余裕ができても、すぐに全部が物理メモリへ戻るわけではありません。今の負荷が低くても、swapの使用済み容量は残ります。

この状態でswap使用量だけを見て、無理にswapを解放したり、何度もサーバーを再起動したりすると、かえって運用に響きます。見るべきなのは、現在の処理でswapへの読み書きが続いているかどうかです。

重要なのはsiとsoの継続発生

vmstatsisoが継続的に増えているなら、物理メモリとswapの間でデータ移動が繰り返されています。さらにwaが高く、WordPressの応答も遅いなら、ディスクI/O待ちが影響していると考えられます。

確認結果 考え方
swap使用量は多いが、si・soはほぼ0 過去に退避された領域が残っている可能性があります。応答やavailableも合わせて確認します。
si・soが継続して増える 物理メモリ不足やメモリ配分の偏りを疑います。
si・soとwaが高く、応答も遅い swapのI/Oが性能へ影響している可能性があります。
swapが少なくてもプロセスが終了する OOMやサービスログなど、別の原因も確認する必要があります。

「swapが1GB使われているから異常」と単純に決めるのではなく、現在の入出力、メモリのavailable、ディスク待ち、MariaDBの処理、WordPressの応答を合わせて判断します。

swap使用量だけで障害を決めつけず、実際に起きてほしくない状態を先に決めて監視します。ジョブ監視で同じことを考えた例が、異常終了の通知がなくても、予定した夜間処理が未実行だった件です。

今回の対応で分かったこと

今回の対応で分かったのは、MariaDBのbuffer poolは大きく設定すれば必ず安定する、というものではないことでした。データベース専用サーバーと、WordPressやPHPを同居させるサーバーでは、適切なメモリ配分が違います。

特に4GB程度の小規模VPSでは、MariaDBへ大部分を割り当てると、OSやPHPが使うメモリが足りなくなります。アクセスが少ない時間帯は問題なくても、バックアップ、管理画面の操作、プラグインの定期処理が重なると、急にメモリ使用量が増えます。

逆に、buffer poolを必要以上に小さくすると、データやインデックスを十分にキャッシュできず、ディスクアクセスが増えます。設定変更後は、メモリ使用量だけでなく、WordPressの応答やMariaDBの処理状況も見続けます。

今回のポイント

  • buffer poolは大きければよいわけではありません。
  • OS、PHP、Webサーバーが使用するメモリも考慮します。
  • swap使用量だけで異常と判断しません。
  • vmstatsisoを確認します。
  • 設定変更前後の数値と確認日時を記録します。
  • 小規模VPSでは、一定の余裕を持った設定が重要です。

それから、再起動で一時的に状態が良くなっても、原因の特定にはなりません。再発を防ぐには、再起動前後のメモリ使用量、swapの動き、実行中のSQL、アクセス状況を記録して、どの処理が重なったときに問題が出るかを見ておきます。

まとめ

4GBメモリのVPSでMariaDBのswap使用量が増えたときは、swapの使用済み容量だけを見て判断せず、サーバー全体の状態を確認します。

今回は、まずfree -mで物理メモリとswapの使用状況を確認し、vmstat 1 5でswapの入出力を見ました。さらにSHOW FULL PROCESSLISTで、長時間実行されているSQLやロック待ちがないかを調べています。

そのうえで、物理メモリ約4GBに対してinnodb_buffer_pool_sizeが3GBでは余裕が少ないと判断し、2GBへ縮小しました。OS、PHP、Webサーバー、MariaDBの追加処理が使えるメモリ領域を確保する方針です。

ただし、2GBという値がどの環境にも当てはまるわけではありません。データベース容量、アクセス数、同時接続数、PHPの構成、利用しているプラグインで適正値は変わります。設定変更後は、MariaDBの起動状態、メモリのavailable、swapの入出力、WordPressの動作を継続して確認してください。

小規模なVPSでは、性能を最大限に引き出す設定よりも、負荷の変動に耐えられる余裕を残すほうが安定します。設定値を一度決めて終わりにせず、実際の使用状況を記録しながら調整していくところです。

最後に、実測の結果をもう一度書いておきます。buffer poolを2GBへ下げた後も、swapの使用量は1.4GB程度で、変更前より増えていました。それでも siso はほぼ0で、available は約2GBを保っています。swapの使用量そのものは、チューニングの成否を測る指標になりません。見るべきなのは、swapへの読み書きが続いているかどうかです。

コメント

タイトルとURLをコピーしました