7/14 PostgreSQLが接続できなくなった対処
どのタイミングで発生したか
- 普段dockerで開発しており、dockerを使用せずに、npm run devで立ち上げて動作確認したいものがあったため、久しぶりにnpm run dev をしたところ、PostgreSQLに接続できないエラーで立ち上げられなかった
なぜ発生したか
- PostgreSQLは「共有メモリ」を使用する
- 共有メモリは複数のプロセス(ここではPostgreSQLの異なる部分や、別のソフトウェア)が同時にアクセスできるメモリ領域です
- PostgreSQLは、データベースの操作を効率的に行うため、この共有メモリを必要とします。
- 共有メモリの総量は限られており、その上限はオペレーティングシステムによって設定されます
- その設定値を「SHMALL」パラメータと言います
- 今回のエラーは、PostgreSQLが必要とする共有メモリの量が、オペレーティングシステムが設定しているSHMALLパラメータの上限を超えてしまったことを示しています
- PostgreSQLが必要とするメモリがOSに割り当てられていないため、データベースの初期化ができていないということ
- その設定値を「SHMALL」パラメータと言います
- 共有メモリの総量は限られており、その上限はオペレーティングシステムによって設定されます
- PostgreSQLは、データベースの操作を効率的に行うため、この共有メモリを必要とします。
- 共有メモリは複数のプロセス(ここではPostgreSQLの異なる部分や、別のソフトウェア)が同時にアクセスできるメモリ領域です
用語の整理
- カーネルパラメータ: カーネルとは、コンピュータのオペレーティングシステムの中心部分で、ハードウェアとソフトウェアの間で仲介役を果たします。カーネルパラメータは、このカーネルの動作を制御するための設定値のことを指します。
- 共有メモリ: コンピュータには、複数のプロセス(基本的には個々のプログラムの実行単位)があります。これらのプロセスがデータを共有するために使うメモリ領域のことを共有メモリと呼びます。共有メモリを使うと、プロセス間で大量のデータを効率的にやりとりできます。
- 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
sudo chown root /Library/LaunchDaemons/sysctl.plist
:このコマンドは/Library/LaunchDaemons/sysctl.plist
ファイルの所有者をrootに変更します。chown
はUNIX系OSでファイルの所有者やグループを変更するためのコマンドです。root
は最高権限を持つユーザーで、このファイルを安全に管理するためにはrootユーザーの所有とすることが一般的です。sudo chmod 644 /Library/LaunchDaemons/sysctl.plist
:このコマンドは/Library/LaunchDaemons/sysctl.plist
ファイルのパーミッション(許可設定)を変更します。具体的には、所有者(この場合はroot)に対して読み書きのパーミッションを、それ以外のユーザーに対しては読み取りのみのパーミッションを与えます。chmod
はUNIX系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
解決しました