PostgreSQLを入れる作業そのものは短時間で終わります。厄介なのは、あとから変えられない設定がその数分のあいだに確定してしまうところです。文字コードと照合順序、データチェックサムの有無は、クラスタを作るinitdbの時点で決まり、取り違えたときの回収手段はクラスタごと作り直すか、対象データベースだけ別文字コードで作り直すかに絞られます。この記事ではWindowsとUbuntuの導入手順を追いつつ、initdbが何を根拠に文字コードを選ぶのか、初期ユーザとpg_hba.confをどこまで触れば接続が通るのかを扱いました。製品としての位置づけはデータベースとは?種類・DBMS・RDBとNoSQLの選び方、費用面の判断はPostgreSQLのライセンスと価格を先に押さえてください。
まとめ:インストール前に決めておく4つのこと
- 版は18系を既定に置く。2026-08-25時点で対応中のマイナーは18.6・17.11・16.15・15.19・14.24で、14系は2026-11-12に修正提供が終わります。
- 文字コードはロケール任せにしない。ロケールが
Cのままlibcプロバイダで走るとSQL_ASCIIのクラスタが出来上がります。 - 同じ条件でもWindowsとLinuxで結果が割れる。ロケール由来の文字コードが使えない値だったとき、Windowsは
UTF8へ読み替え、Linuxはエラー終了します。 - 接続不良の原因は3層に分かれる。プロセス、待ち受けアドレスとポート、
pg_hba.confの行。この順で切り分けます。
導入する版の決め方とWindows・Ubuntuで分かれる入れ方
PostgreSQL 18系を既定に置きサポート期限から版を決める
2026-08-25時点で公式サイトが対応中として並べているマイナーは、18.6・17.11・16.15・15.19・14.24の5系統で、いずれも2026-08-13に同時リリースされました。同じ日に19系のBeta 3も出ています。公式は14系について2026年11月12日で修正提供を終えると明記しており、これから入れる環境で14系を選ぶ理由はありません。すでに動いている環境がどの版なのかを読み取る手順は、PostgreSQLのバージョン確認方法とEOL判定で扱っています。
決め方の順番は単純です。まず載せるアプリケーションのドライバや拡張が18系に対応しているかを確かめ、読めなければ17系へ落とします。対応版が読みにくいのはベクトル検索まわりで、使う予定があるならpgvectorの基本概要とベクトル検索の側から確認しておくと手戻りが減ります。
Windowsはインストーラ、Ubuntuはaptリポジトリという分岐
Windowsでは公式ダウンロードページが案内するEDB製インストーラが実質の標準で、対応中のすべてのPostgreSQL版についてEDBが認定していると書かれています。同梱物はサーバ本体、管理ツールのpgAdmin、追加コンポーネントを取ってくるStackBuilderです。同ページがPostgreSQL 18の対象に挙げるのは64ビットのWindows Server 2025と2022です。
Ubuntuでは、標準パッケージではなくPGDG(PostgreSQL Global Development Group)のaptリポジトリを足すのが基本線です。標準リポジトリはUbuntuのリリースに紐付いた版しか持たないのに対し、PGDGは対応中の全系統を並行して提供します。18系と17系を同居させる使い方も、こちら側でしか成立しません。
WindowsへEDBインストーラで入れる手順と文字コードの落とし穴
Windowsのインストーラが聞いてくる項目と変えてよい既定値
EDBのドキュメントが示すウィザードは、導入先ディレクトリ、コンポーネント選択、データディレクトリ、パスワード、ポート、Advanced Optionsの順に進みます。押さえる点は次のとおりです。
| 画面 | 既定と扱い |
|---|---|
| コンポーネント | サーバ・pgAdmin・StackBuilder |
| データディレクトリ | 導入先配下。別ドライブへ移すならここ |
| パスワード | スーパーユーザ兼サービス実行者postgres分 |
| ポート | 既定は5432。既存と衝突するときだけ変更 |
| Advanced Options | ロケール選択。既定はOSのロケール |
コンポーネント欄のCommand Line Toolsにはpsqlやpg_isreadyが含まれます。管理端末側では、この項目だけを選んでクライアントを配れます。
ロケール選択で文字コードが決まるためUTF8を明示して入れる
問題はAdvanced Optionsのロケール欄です。既定のロケールはOSのロケールとされ、日本語Windowsでは日本語ロケールが入ります。公式ドキュメントの表現では、-Eまたは--encodingが与えられなければ、指定されたロケールまたは既定のロケールに基づいて適切な文字コードを判定しようとする、となっています。
日本語ロケールから導かれる文字コードはSJISですが、PostgreSQLはSJISをサーバ側文字コードとして受け付けません。ではインストールが失敗するのかというと、Windowsに限ってはそうなりません。initdbの実装には、認識はできたがサーバ文字コードとして正当ではない、WindowsではUTF8がどのロケールでも動くのでUTF8へ退避できる、という趣旨のコメントが置かれています。Windowsビルドでは文字コードをUTF8へ差し替え、ロケールが示す文字コードは許可されないため既定をUTF8とする、と表示して処理を続けます。
つまりWindowsでは、既定のまま進めても文字コードはUTF8に落ち着きます。ただしこれは救済であって設計ではありません。
インストールの直後にpsqlが通るかをコマンドラインで確かめる
完了画面を閉じたら、コマンドラインで疎通を見ます。pgAdminが開けたことは、アプリケーションが使う経路の確認にはなりません。
"C:\Program Files\PostgreSQL\18\bin\pg_isready.exe" -h localhost -p 5432
"C:\Program Files\PostgreSQL\18\bin\psql.exe" -U postgres -h localhost -c "SHOW server_encoding;"
2行目がUTF8を返せば想定どおりです。SQL_ASCIIだった場合は、この時点で作り直しを検討してください。
UbuntuへPGDGのaptリポジトリで入れる手順と自動で作られるクラスタ
リポジトリ登録は自動スクリプトとdeb822形式の2通りがある
公式が案内する手軽な経路は、postgresql-commonを入れてから同梱スクリプトを走らせるやり方です。コードネーム判定とGPG鍵の配置をスクリプト側が引き受けます。
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql-18
構成管理ツールから流し込むなら、対話を挟まない手動登録が扱いやすくなります。鍵をpgdgディレクトリへ置き、pgdg.sourcesをdeb822形式で書きます。旧来の1行形式の.listではない点に注意してください。
Types: deb deb-src
URIs: https://apt.postgresql.org/pub/repos/apt
Suites: noble-pgdg
Architectures: amd64
Components: main
Signed-By: /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc
Suitesのコードネーム部分は導入先のUbuntuに合わせて差し替えます。取り違えると、更新のたびに失敗する構成が残ります。
パッケージ導入で自動作成されるクラスタと設定ファイルの置き場
Debian系のパッケージは、入れた時点でクラスタを1つ作ります。pg_createclusterのマニュアルには、新しいpostgresql-NNサーバパッケージが導入されまだクラスタが存在しないときにmainクラスタを作る、と書かれています。配置は次の3点です。
- データ領域は
/var/lib/postgresql/18/main - 設定ファイルは
/etc/postgresql/18/main/配下 - 起動制御は同ディレクトリの
start.conf
start.confはauto・manual・disabledの3値を取り、既定のautoなら起動時にそのまま立ち上がります。待機系や手動制御したい検証用クラスタはmanualへ倒してください。製品としてどちらを選ぶか迷う段階なら、PostgreSQLとMySQLの違いを徹底比較で運用面の差も見ておくと判断が早まります。
SQL_ASCIIのクラスタが出来上がる条件と作り直しの手順
ここが最大の落とし穴です。pg_createclusterのロケールは、オプションが指定されなければ実行環境から引き継ぎます。そして文字コードは、ロケールから導出する、それで駄目ならSQL_ASCII、と定義されています。
クラウドのミニマルイメージや非対話で叩いたシェルでは、LANGがCのままであることが珍しくありません。initdbのドキュメントも、ロケールがCまたはPOSIXなら既定はICUプロバイダでUTF8・libcプロバイダでSQL_ASCIIと明記しています。既定のプロバイダはlibcですから、この条件がそろうとSQL_ASCIIのクラスタが黙って出来上がります。
SQL_ASCIIは文字コードの検証をせず、バイト列をそのまま格納する設定です。日本語を入れても最初は動いてしまい、別の文字コードのクライアントが混ざった時点で読めない行が生まれます。
pg_lsclusters
sudo -u postgres psql -c "SELECT datname, pg_encoding_to_char(encoding) FROM pg_database;"
データを入れる前なら、クラスタごと作り直すのが最短です。ロケール文字列がホストに無ければ先にlocale-genで生成し、ロケールを増やしたくない運用なら--locale C.UTF-8を選ぶ手もあります。
sudo pg_dropcluster --stop 18 main
sudo pg_createcluster -e UTF8 --locale ja_JP.UTF-8 --start 18 main
既存クラスタがあると5433番へずれるポート自動割り当ての規則
同じホストへ2つ目のクラスタを作ると、ポートは自動でずれます。マニュアルの表現では、5432から数えて既存クラスタにまだ使われていない最初のポートが割り当てられます。17系が入っているホストへ18系を足せば、18系は5433で立ち上がるということです。
接続文字列を5432固定で書いた構成では取り違えが起きます。pg_lsclustersの出力にポート列があるので、切り替えの前後で突き合わせてください。明示したいときは-pを渡します。
initdbで決まるロケール・文字コード・チェックサムの既定値
ロケールプロバイダの3択と組み込みプロバイダを選んでよい条件
18系のinitdbが受け付けるロケールプロバイダはbuiltin・libc・icuの3つで、既定はlibcです。builtinを選ぶ場合、ロケール名はC・C.UTF-8・PG_UNICODE_FASTのいずれかに限られます。
目安はこうです。辞書順が要るならICU、並び順に要求がないならbuiltinのC.UTF-8、既存環境との互換を優先するならlibcのまま。libcはOSの更新で照合順序が変わると索引の再構築が要る点が弱みです。
PostgreSQL 18系からデータチェックサムが既定でオンになった
18系のinitdbドキュメントには、データチェックサムは既定で有効・無効にするには--no-data-checksumsを使う、と書かれています。17系以前は明示的に付けなければ無効だったため、18系で既定が反転しました。
チェックサムはページ読み出し時に破損を検出する仕組みで、書き込み時に計算コストが乗ります。無効にしてよいのは、性能を実測して劣化が許容できないと判断できたときだけです。
あとから変えられる設定とクラスタの作り直しが必要な設定の線引き
| 設定 | あとからの変更 |
|---|---|
| 文字コード | DB単位で作り直せば可能 |
| 照合順序 | 同上。索引の再構築が要る |
| データチェックサム | 停止してpg_checksumsで切替 |
| ポート・待ち受け | 設定変更と再起動で可能 |
| 認証方式 | 設定変更と再読込で可能 |
実務上いちばん痛いのは照合順序です。文字コードだけならtemplate0から作り直して移し替えれば済みますが、照合順序を変えると既存の索引の前提が崩れます。導入時に決め切る価値があるのはこの2つです。
初期ユーザとpg_hba.confで接続を開けるときの最小の変更
postgresロールのパスワードとpeer認証がぶつかる場面
Windowsのインストーラは途中でpostgresのパスワードを設定させます。一方、Ubuntuのパッケージ導入ではパスワードが設定されません。OSユーザpostgresからUNIXドメインソケット経由で入る前提だからです。
この方式がpeerで、ドキュメントの定義では、クライアントのOSユーザ名を取得して要求されたデータベースユーザ名と一致するかを確認する、ローカル接続でのみ利用できる、となっています。だからsudo -u postgres psqlは通り、同じ端末からのpsql -h localhost -U postgresは弾かれます。
sudo -u postgres psql -c "ALTER USER postgres WITH ENCRYPTED PASSWORD 'set-your-own';"
pg_hba.confは先に一致した1行が勝ち不一致なら拒否になる
読み方は単純です。接続種別、クライアントアドレス、対象データベース、ユーザ名の4つが最初に一致した行が使われます。ドキュメントは、フォールスルーもバックアップもない、ある行が選ばれて認証に失敗しても後続の行は考慮されない、と明言しました。
この性質から、行の順序が意味を持ちます。広い範囲を許す行を上へ置くと、下の厳しい行は永久に評価されません。編集したらpg_hba_file_rulesビューで解釈を確認してください。error列が非NULLの行は該当行に問題があることを示します。
md5と書かれた行でもSCRAMで認証が通ってしまう理由と直し方
Debian系で作られたクラスタのpg_hba.confでは、TCP接続の行にmd5が並んでいることがあります。pg_createclusterのマニュアルに、既定ではinitdbが生成したpg_hba.confをローカル接続はpeer・TCP接続はmd5を使うよう更新する、と書かれているためです。
ところが保存側の既定であるpassword_encryptionはscram-sha-256で、記述と実態が食い違います。この矛盾は自動で吸収される仕組みです。ドキュメントの説明では、md5が指定されていてもサーバ上のパスワードがSCRAM用に保存されていればSCRAMベースの認証が自動的に選ばれる、となっています。
とはいえ放置してよい理由にはなりません。MD5で暗号化されたパスワードのサポートは非推奨であり将来のリリースで削除される、という警告が出ています。導入時にscram-sha-256へ書き換えておくほうが後々の手間を減らせます。
リモート接続を開けるときのlisten_addressesと反映の手順
別ホストから繋ぐにはpg_hba.confだけでは足りません。listen_addressesの既定はlocalhostで、ローカルのTCP/IPループバック接続のみを許可する状態です。まずpostgresql.conf側で待ち受けを広げ、次にpg_hba.confで許可範囲を絞ります。
listen_addresses = '10.0.1.20'
hostssl appdb appuser 10.0.1.0/24 scram-sha-256
アドレス欄の0.0.0.0/0は経路上の制御が別にある前提の書き方です。アプリケーションサーバのサブネットに限定しておけば、後日の棚卸しでも意図が読み取れます。listen_addressesの変更は再起動が要る一方、pg_hba.confはpg_ctl reloadやpg_reload_conf()による再読込で足ります。
接続確認からデータベース作成までを層ごとに切り分けて確かめる
pg_isreadyとpsqlで起動・ポート・認証のどこで落ちたか見る
pg_isreadyは認証を行わず、接続を受け付ける状態かどうかだけを返します。つまりプロセスとポートまでを切り分ける道具です。ここが通ってpsqlで落ちるなら、原因は認証か対象データベースの側にあります。GUIクライアントから同じ接続先を確かめたい場合は、DBeaverでの接続設定とテスト接続の手順が使えます。
pg_isready -h 10.0.1.20 -p 5432
psql "host=10.0.1.20 port=5432 dbname=appdb user=appuser" -c "\conninfo"
pg_isreadyで応答がなければ、見るのはlisten_addressesとポート、経路上のファイアウォールです。認証エラーが返るならpg_hba_file_rulesでどの行に当たったかを確かめます。ドライバまで含めて追う段では、Psycopg3の概要と主要な特徴と併読すると切り分けが進みます。
CREATE DATABASEで文字コードを変えるならtemplate0を使う
データベースの作成はcreatedbかCREATE DATABASEで行います。既定ではtemplate1を複製するため、文字コードとロケールは複製元と同じになります。変えたい場合は複製元をtemplate0へ切り替えてください。ドキュメントは、文字コードとロケールの設定は複製元と一致していなければならない、template0を使う場合を除く、と述べています。
CREATE DATABASE appdb
ENCODING 'UTF8'
LOCALE 'ja_JP.UTF-8'
TEMPLATE template0;
先ほどのSQL_ASCII問題も、クラスタを作り直せないならこの手で部分的に回収できます。ただし以後に作るDBが毎回この指定を要求されるため、恒久策にはなりません。
アプリ用のロールを分けて権限を絞るところまで初期設定に含める
締めはアプリケーションが使うロールの作成です。postgresのまま接続する構成は検証環境でも避けてください。スーパーユーザはどのデータベースにも触れてしまい、事故の範囲が読めなくなります。
CREATE ROLE appuser LOGIN PASSWORD 'set-your-own';
GRANT CONNECT ON DATABASE appdb TO appuser;
GRANT USAGE, CREATE ON SCHEMA public TO appuser;
15系以降はpublicスキーマへの作成権限が既定で外れているため、3行目の明示的な付与が要ります。索引設計まで進む段階では、PostgreSQLにおけるGINインデックスの特徴と役割を押さえておくと初期スキーマの見通しが立ちます。
初期スキーマを作り終えたら、どのオブジェクトが実際に出来ているかを確認しておくと安全です。確認手段ごとに見える範囲が変わる点はPostgreSQLのテーブル一覧を取得する方法で整理しました。
ネイティブ導入を選ぶ3条件とDockerやマネージドへ寄せる場面
ネイティブ導入のままで足りる3条件と手順を固定化しておく範囲
ホストへ直接入れてよいのは、次の3条件がそろうときです。第一に、そのホストでDBが長期に動き続ける前提であること。第二に、OSのパッケージ更新でセキュリティ修正を受け取れること。第三に、DBとアプリケーションが少数のホストで完結すること。
そのうえで手順は固定化してください。固めるのは、版、ロケール、文字コード、データチェックサムの有無、pg_hba.confの初期行、初期ロールの5点です。この5点を構成管理ツールへ落としておけば、環境差から生まれる不具合の大半が消えます。オンプレとクラウドで同じ構成を再現するところまで設計するなら、インフラ構築(AWS・Google Cloud・Azure)のような外部の手も検討に値します。
使い捨ての検証環境やCIならDockerへ寄せたほうが早い理由
逆に、寿命の短い環境ではネイティブ導入は割に合いません。試験ごとに作って壊す、複数の版を並べて互換を見る、CIのジョブ内でだけ立てる、といった用途ではコンテナのほうが手数が少なく済みます。ロケールや文字コードも、イメージ側の環境変数で固定できます。
分かれ目は、その環境が壊れたときに作り直すか直すかです。作り直すつもりならコンテナで組んだほうが速く済みます。コンテナでの構成は、Docker PostgreSQL構築の手順|18で変わったボリューム位置とcompose定義で公式イメージのタグ選定から初期化SQLの扱いまで扱っています。
運用の手離れを優先するならマネージドへ寄せるという判断の分かれ目
3つ目の選択肢がマネージドサービスです。バックアップ、マイナー更新、フェイルオーバーを自前で組む工数と月額の差額を突き合わせて決めます。導入自体は数分でも運用は年単位で続くため、総額での比較でなければ判断を誤ります。
利用が断続的なワークロードでは、停止中に課金が止まる形態のほうが総額で下回ります。この観点の具体例はNeonとは?サーバーレスPostgresの構成・料金と採用判断で扱いました。常時一定の負荷が乗る基幹系なら、差を決めるのは運用体制の有無です。夜間の対応要員を置けないなら、費用が上がってもマネージドへ寄せる判断が合理的になります。
よくある質問
インストール後に文字コードを変えることはできますか?
クラスタ全体の既定は変更できません。データベース単位なら、template0を複製元にして目的の文字コードで作り直し、データを移し替えることで実質的に変えられます。導入直後でデータが無いなら、クラスタごと作り直すほうが手早く済みます。
Ubuntu標準のパッケージとPGDGはどちらを使うべきですか?
版を選びたいならPGDGです。Ubuntu標準はリリースに紐付いた版しか持たず、複数版を同居させたいという要求に応えられません。両方のリポジトリからパッケージが入る状態は避け、PGDGへ統一してください。
postgresユーザのパスワードを設定しないままでも問題ありませんか?
ローカルのpeer認証だけで運用するなら、設定しない選択にも合理性があります。パスワードが無ければTCP経由の接続は成立しないためです。監視ツールからTCPで入るなら設定が要りますが、その場合も用途別のロールを作って権限を絞るほうが安全です。
データチェックサムを有効にすると性能はどれくらい落ちますか?
ワークロード次第で、一律の数値は出せません。読み出し主体なら体感できる差は出にくく、書き込みが集中する構成ほど影響が見えます。無効化を検討するなら実負荷に近い試験を回してから判断してください。pg_checksumsを使えば、クラスタを停止したうえで後から切り替えられます。
Windows 11の開発機に入れても本番と同じ挙動になりますか?
文字コードの決まり方が異なります。ロケール由来の文字コードがサーバ側で使えない値だった場合、WindowsはUTF8へ読み替えて続行しますが、Linuxは同じ条件でエラー終了します。ロケールと文字コードは両環境とも明示指定にそろえてください。