3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Linux】スワップファイルでサーバのメモリ不足を補う

Last updated at Posted at 2024-10-28

はじめに

さくらVPSの最小プランでインフラを構築する際に、メモリ不足で色々と不具合が起こった際にスワップファイルを利用することで無理矢理解決したので、メモとして残します!

VPSの性能

  • OS: Debian 12
  • アーキテクチャ: amd64(64ビット版)
  • リージョン: 東京第2(データセンターの場所)
  • メモリ: 512MB

インフラ構成

すごくざっくりですが、こんなイメージです。

    さくらVPS
 ┌───────────────┐
 │               │
 │   ┌───────┐   │
 │   │ MySQL │   │
 │   └───────┘   │
 │               │
 │   Docker      │
 │ ┌───────────┐ │
 │ │           │ │
 │ │  Rails    │ │
 │ │ (API      │ │
 │ │  Server)  │ │
 │ └───────────┘ │
 └───────────────┘

接続:Rails (Docker) ⇔ MySQL (VPS上)

MySQLのインストール、起動時に問題発生

上記のインフラを構築するため
VPSを借りて、MySQLをaptでインストールし、起動する際に下記のエラーが発生しました。

sudo apt install mysql-server
dpkg: error processing package mysql-community-server (--configure): installed mysql-community-server package post-installation script subprocess returned error exit status 137

137のexit statusコードが吐き出されているので、まずこれが何か調べてみます。

137 exit statusコードとは?

Exit code 137 typically indicates that a process inside a container was killed by the system due to an out-of-memory (OOM) condition. When the operating system detects that it's running out of memory, it invokes the OOM killer, which terminates processes to free up memory. In the context of containers, this often results in the following error messages:

終了コード137は通常、コンテナ内のプロセスがメモリ不足(OOM)状態のためにシステムによって強制終了されたことを示す。

どうやらメモリ不足により、終了を表すコードのようです。

topコマンドで確認してみる

実行中のメモリの使用量をtopコマンドで見てみました

top
MiB Mem :    457.6 total,      6.2 free,    444.9 used,     16.6 buff/cache

6.2MBしか余裕がないですね笑
この後、137 exit codeが吐き出されるので、メモリ不足には間違いなさそうです。

解決方法

一番簡単な解決方法はスケールアップすることです。
ただ、当然料金が嵩みます。
利用者の限られるアプリに使用するため、できるだけコストは抑えたいです。
色々と調べた結果、処理速度等は物理メモリに比べて低下しますがスワップ領域を使用して、ハードディスクの一部をメモリのように扱うことで不足を補えるようなので、そのアプローチをとってみることにします。

Linux の スワップ領域 は、物理メモリー (RAM) が不足すると使用されます。システムに多くのメモリーリソースが必要で、RAM が不足すると、メモリーの非アクティブなページがスワップ領域に移動します。

使われていないメモリの内容を割り当てたハードディスクの領域(スワップ領域)に移動させることで、RAMの不足を補うといった仕組みのようですね。

スワップ領域の追加

さくらVPSの公式にやり方が記載されていたのでこちらを参照しました。

1.空き容量の確認

df -h /

いくつかファイルシステムが表示されますが/(ルート)がマウントされている/dev/vda2の空き容量を確認します。
Availが18Gなので十分な容量があることが確認できました。

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda2        25G  3.7G   18G  15% /

2.スワップファイルの作成

sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
  • sudo:管理者権限で実行
  • dd:指定したサイズのファイルを作成するコマンド
  • if=/dev/zero/dev/zeroはデバイスファイルで、ゼロ(0)が無限に出力される。これによりゼロで埋められたデータをスワップファイルに書き込む
  • of=/swapfile:出力ファイルにスワップファイルを指定しています
  • bs=1M:ブロックサイズを1MBに設定
  • count=2048:上記で指定した1Mのブロックの数を2048に設定し、合計2GB(1MB * 2048 = 2GB)のスワップファイルを作成

これで/直下にswapfileが作成されます。
0で埋めてスワップ領域を確保するイメージですね。

3. スワップファイルのアクセス権限の設定

sudo chmod 600 /swapfile

これで作成したswapfileに600の権限を設定します
600はファイルの所有者にのみ読み書き許可を付与する設定です
所有者以外はスワップファイルを読み書きできなくすることで、セキュリティを強化しています。

Linuxの権限については、下記の記事にまとめています!

4. スワップファイルの初期化

作成しただけでは、まだ使えません。
作成したファイルをスワップファイルとして認識させる必要があります
mkswapコマンドが指定したファイルをスワップ領域として初期化するコマンドになります
引数に先ほど作成したswapfileのパスを指定します。

sudo mkswap /swapfile

このコマンドでスワップファイルに必要なメタデータが設定され、システムがスワップ領域として認識できるようになります

5.swapファイルの有効化

次に認識させたswapファイルを有効化します

sudo swapon /swapfile

これでメモリが不足した際に、作成したswapfileを使用するようになります。

設定ができているか確認

free
Swap:        2097148           0     2097148

上記のように Swap領域が表示されるようになっていれば完了です!

6.バックアップの作成

sudo cp -p /etc/fstab /etc/fstab.org

7.swapの設定を永続化

echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab:

ehcoで出力した/swapfile none swap sw 0 0
設定ファイルに記載したい文字列をteeコマンドに渡して/etc/fstavファイルの末尾に追加しています。

設定の意味を下記の通り

  • /swapfile: スワップ領域として利用するファイル
  • none: デバイス名ではなくファイルを使用するため、none を指定
  • swap: スワップ領域であることを示す
  • sw: スワップ領域に適用するオプション
  • 0 0: ディスクのバックアップやチェックの設定(スワップ領域には適用しないため 0 を指定)

再度MySQLのインストール、起動に挑戦

念の為、一度アンインストールしてから行います。

関連するパッケージ、依存関係の削除

sudo apt-get remove --purge mysql-server mysql-client mysql-common
sudo apt-get autoremove
sudo apt-get autoclean

パッケージリストを更新

sudo apt-get update

再度インストール

sudo apt-get install mysql-server
sudo systemctl status mysql

起動状態の確認

● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-10-25 08:40:08 JST; 0 days ago
       Docs: man:mysqld(8)
             http://dev.mysql.com/doc/refman/en/using-systemd.html
    Process: 29759 ExecStartPre=/usr/share/mysql-8.0/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
   Main PID: 29795 (mysqld)
     Status: "Server is operational"
      Tasks: 41 (limit: 504)
     Memory: 50.4M
        CPU: 29min 27.873s
     CGroup: /system.slice/mysql.service
             └─29795 /usr/sbin/mysqld

無事インストールし、起動することができました!

まとめ

スワップファイルを作成して有効化することで、なんとかメモリ不足をカバーでき、MySQLも無事にインストール・起動できました。少し手間はかかりますが、物理メモリが増やせない環境での応急処置の一つの方法として勉強になりました!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?