りゅうじの学習blog

学習したことをアウトプットしていきます。

7/14 PostgreSQLが接続できなくなった対処

どのタイミングで発生したか

  • 普段dockerで開発しており、dockerを使用せずに、npm run devで立ち上げて動作確認したいものがあったため、久しぶりにnpm run dev をしたところ、PostgreSQLに接続できないエラーで立ち上げられなかった

なぜ発生したか

  • PostgreSQLは「共有メモリ」を使用する
    • 共有メモリは複数のプロセス(ここではPostgreSQLの異なる部分や、別のソフトウェア)が同時にアクセスできるメモリ領域です
      • PostgreSQLは、データベースの操作を効率的に行うため、この共有メモリを必要とします。
        • 共有メモリの総量は限られており、その上限はオペレーティングシステムによって設定されます
          • その設定値を「SHMALL」パラメータと言います
            • 今回のエラーは、PostgreSQLが必要とする共有メモリの量が、オペレーティングシステムが設定しているSHMALLパラメータの上限を超えてしまったことを示しています
            • PostgreSQLが必要とするメモリがOSに割り当てられていないため、データベースの初期化ができていないということ

用語の整理

  1. カーネルパラメータ: カーネルとは、コンピュータのオペレーティングシステムの中心部分で、ハードウェアとソフトウェアの間で仲介役を果たします。カーネルパラメータは、このカーネルの動作を制御するための設定値のことを指します。
  2. 共有メモリ: コンピュータには、複数のプロセス(基本的には個々のプログラムの実行単位)があります。これらのプロセスがデータを共有するために使うメモリ領域のことを共有メモリと呼びます。共有メモリを使うと、プロセス間で大量のデータを効率的にやりとりできます。
  3. SHMALL: これは、システム全体で使用可能な共有メモリの最大値を制御するカーネルパラメータです。SHMALLの値は、通常はシステムの物理メモリの一部として設定されます。この値を増やすと、プロセスが共有メモリをより多く使えるようになります。しかし、その分、他のプロセスが使えるメモリは減少するため、この値を適切に設定することが重要です。

使用コマンド

現在のSHMALL値を確認

sysctl -a | grep shm

私の設定されていた値

kern.sysv.shmmax: 4194304
kern.sysv.shmmin: 1
kern.sysv.shmmni: 32
kern.sysv.shmseg: 8
kern.sysv.shmall: 1024
security.mac.posixshm_enforce: 1
security.mac.sysvshm_enforce: 1

このファイルはなければ新規作成する必要があります

sudo nano /etc/sysctl.conf

以下2行を設定します

kern.sysv.shmmax=設定したい値
kern.sysv.shmall=設定したい値
  • 値は自分の設定したい値を入力

編集が完了したら Ctrl+X を押し、 Y を押してファイルを保存し、最後に Enter を押して終了します

今回のセッション中のみ、こちらのコマンドで上記の設定を反映させられます

sudo sysctl -w kern.sysv.shmmax=1073741824
sudo sysctl -w kern.sysv.shmall=2097152

こちらのコマンドで反映されているかの確認

sysctl -a | grep kern.sysv.shm

再起動してもこの設定が反映されるようにする

なぜ反映されないか

セキュリティ上の制約から、macOS/etc/sysctl.conf の値を起動時に読み込むことが許されていないから

解決法

macOSのlaunchdを使用して、起動時にsysctlコマンドを実行する.plistファイルを作成する

手順

/Library/LaunchDaemons ディレクトリに sysctl.plist ファイルを作成

sudo nano /Library/LaunchDaemons/sysctl.plist

sysctl.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>local.sysctl</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/sbin/sysctl</string>
        <string>-w</string>
        <string>kern.sysv.shmmax=1073741824</string>
        <string>kern.sysv.shmall=2097152</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
</dict>
</plist>

このXMLファイルは、macOSの起動時に特定のコマンドを実行するための設定を持つ「プロパティリスト」(plist)ファイルです。具体的には次のような動作を指定しています

  • Labelキー: このジョブの一意の識別子を指定します。ここではlocal.sysctlとなっています。
  • ProgramArgumentsキー: 実行するコマンドとその引数を指定します。ここでは、/usr/sbin/sysctlコマンドを、w kern.sysv.shmmax=1073741824およびkern.sysv.shmall=2097152という引数で実行するように指定しています。これにより、システムの共有メモリに関する設定を変更しています。
  • RunAtLoadキー: このジョブをシステム起動時に実行するかどうかを指定します。trueと指定されているので、システム起動時に上述のコマンドが実行されます。
  • KeepAliveキー: ジョブが何らかの原因で終了した場合に自動的に再起動するかどうかを指定します。ここではfalseと指定されているので、一度実行されたジョブは再起動されません。

このplistファイルを/Library/LaunchDaemons/ディレクトリに保存し、適切な権限を設定することで、システム起動時にこれらの設定が自動的に適用されるようになります。

作成したファイルのパーミッションを設定

sudo chown root /Library/LaunchDaemons/sysctl.plist
sudo chmod 644 /Library/LaunchDaemons/sysctl.plist
  1. sudo chown root /Library/LaunchDaemons/sysctl.plist:このコマンドは/Library/LaunchDaemons/sysctl.plistファイルの所有者をrootに変更します。chownUNIX系OSでファイルの所有者やグループを変更するためのコマンドです。rootは最高権限を持つユーザーで、このファイルを安全に管理するためにはrootユーザーの所有とすることが一般的です。
  2. sudo chmod 644 /Library/LaunchDaemons/sysctl.plist:このコマンドは/Library/LaunchDaemons/sysctl.plistファイルのパーミッション(許可設定)を変更します。具体的には、所有者(この場合はroot)に対して読み書きのパーミッションを、それ以外のユーザーに対しては読み取りのみのパーミッションを与えます。chmodUNIX系OSでファイルのパーミッションを変更するためのコマンドで、644は一般的なパーミッション設定の一つです。

plistをロード

sudo launchctl load -w /Library/LaunchDaemons/sysctl.plist
  • このコマンドはlaunchctlツールを使用して、/Library/LaunchDaemons/sysctl.plistというLaunchDaemonをロード(起動)します。-wオプションは、plistファイルの設定に関わらず、このDaemonを永続的に有効化することを指示します。これにより、このDaemonはシステム起動時に自動的にロードされるようになります。

再起動して設定が反映されているか確認

 sysctl -a | grep kern.sysv.shm

解決しました