第3章 PostGIS 管理

目次

3.1. パフォーマンスチューニング

PostGISの性能向上のための調整はPostgreSQLの作業量の調整と非常に似ています。追加して留意すべき点は、ジオメトリとラスタは重大きいのでメモリ関連の最適化は他のPostgreSQLクエリと比べて影響が大きいことだけです。

PostgreSQLの最適化に関する一般的な詳細は、 Tuning your PostgreSQL Serverをご覧ください。

postgresql.confまたはpostgresql.auto.confを触らなくても、 ALTER SYSTEMコマンドでサーバーレベルのコンフィギュレーションが可能です。

work_mem を設定して、コンフィギュレーションの再読込みを実行すると、新しいコネクションでは変更が反映され、現在の値が表示されます。全ての設定を確認するには SHOW ALL を使います。

コード
ALTER SYSTEM SET work_mem = '256MB';
SELECT pg_reload_conf();
SHOW work_mem;

PostgreSQLの設定に加えて、PostGISには 「Grand Unified Custom 変数 (GUC)」で挙げる独自設定があります。

3.1.1. 起動時

次に示す設定はpostgresql.confにあります:

constraint_exclusion

  • デフォルト: partition

  • これは一般的にテーブルのパーティショニングに使われます。デフォルトの"partition"では、テーブルが継承階層の中にある場合にはプランナーに制約を考慮するテーブル解析だけを強制し、他の場合にはプランナーペナルティを払うのを避けるようにします。

shared_buffers

  • デフォルト: ~128MB

  • 利用可能なRAMの25%から40%を設定します。Windowsでは高く設定することができないかも知れません。

max_worker_processesで有効なバックグラウンドプロセス数の最大値をサーバーに対して制御できます。間接的にパラレルクエリーに参加するワーカーの上限値も設定できると言えます。

  • デフォルト: 8

  • システムが対応できるバックグラウンドプロセスの最大値を設定します。このパラメータはサーバ起動時のみ設定できます。

3.1.2. 実行時

work_mem - 並べ替えや複雑なクエリに使われるメモリのサイズの設定

  • デフォルト: 1-4MB

  • 大きなデータベースの場合や、複雑なクエリの場合、RAMが多い場合は値を大きくするように調整します。

  • 同時接続ユーザ数が多い場合や、RAMが少ない場合には値を小さくするように調整します。

  • たくさんのRAMを持ち、少数の開発者しかいない場合は次のようにします:

    コード
    SET work_mem TO '256MB';

maintenance_work_mem (訳注: 日本語訳) - VACUUM, CREATE INDEX等で使われるメモリのサイズ

  • デフォルト: 16-64MB

  • 一般的には低すぎます - メモリスワップの間、入出力が拘束され、オブジェクトがロックされます

  • たくさんのRAMを持つ本番サーバでは32MBから1GBが推奨ですが、同時接続ユーザ数に依存します。たくさんのRAMを持ち、少数の開発者しかいない場合は次のようにします:

    コード
    SET maintenance_work_mem TO '1GB';

max_parallel_workers_per_gather

最近の PostgreSQL と PostGIS のパラレルクエリー機能では、1回のプランで要求する可能性のあるワーカー数を決定するためにこの設定が使われます。0より大きい数を設定した場合には、これらの関係する ST_Intersects のような関係関数を含むクエリーが複数のプロセスを使うことができ、そうすると 2倍を超える速度になります。多数の予備プロセスがあるなら、この値を持っているプロセス数まで上げるべきです。ただし、これにあわせてmax_worker_processesを少なくともこの数と同じまで増やすのを忘れないでください。

  • デフォルト: 0

  • 単一のGatherノードが開始できるワーカの最大数を設定します。並列ワーカは、max_worker_processesで確立されたプロセスのプールから取得されます。要求したワーカ数は、実際には実行可能になっていない場合があることに注意して下さい。これが発生する場合には、想定より少ないワーカでプランが実行されることになり、場合によっては非効率になります。これの値を0 (デフォルト値)にすると、パラレルクエリ実行が無効になります。

3.2. ラスター機能の設定

ラスター機能を有効にしたら、下に示す確実な設定方法を読んだ方がいいです。

データベース外ラスターとすべてのラスタードライバーはデフォルトでは無効です。有効にするには、サーバー側で環境変数 POSTGIS_GDAL_ENABLED_DRIVERSPOSTGIS_ENABLE_OUTDB_RASTERS とを設定する必要があります。環境により依存しない方法として、対応する 「Grand Unified Custom 変数 (GUC)」 を設定することができます。

データベース外ラスタを有効にするには次のようにします:

コード
POSTGIS_ENABLE_OUTDB_RASTERS=1

他の値を入れたり、値を入れない場合には、データベース外ラスタは無効になります。

インストールしたGDALで利用可能なドライバーの全てを有効にするには、次の環境変数を設定します:

コード
POSTGIS_GDAL_ENABLED_DRIVERS=ENABLE_ALL

一部のドライバーのみ有効にしたい場合には、環境変数を次のように設定します:

コード
POSTGIS_GDAL_ENABLED_DRIVERS="GTiff PNG JPEG GIF XYZ"
[注記]

Windows環境の場合には、ドライバーリストに引用符をつけないで下さい

環境変数は OS によって変化します。Ubuntu や Debian 上で apt-postgresql を介してPostgreSQL をインストールした場合には、/etc/postgresql/MAJOR/CLUSTER/environment (MAJRO はメジャーバージョン、CLUSTER はクラスター名が入ります) を編集する方が良いです。

Windows でサービスとして実行している場合には、システム変数で設定します。Windows 7 では、コンピューターを右クリック -> プロパティをクリックするか、エクスプローラーの検索バーに コントロール パネル\すべてのコントロール パネル項目\システム を指定します。 それから、 システムの詳細設定 -> 詳細設定 -> 環境変数 を順にクリックして、新しいシステム環境変数を追加します。

環境変数を設定した後は、設定を反映させるために、PostgreSQLサービスの再起動が必要です。

3.3. 空間データベースの作成

3.3.1. エクステンションを使って空間データベースを有効にする

extensions/postgis モジュールをコンパイル、インストール済みの場合には、EXTENSION 機構を使うことでデータベースを空間データベースに切り替えることができます。

中核となる PostGIS エクステンションには、ジオメトリー、ジオグラフィ、spatial_ref_sys および全ての関数とコメントが含まれています。ラスターとトポロジーは別のエクステンションになっています。

空間データベースにしたいデータベース上で次のSQLを実行します:

コード
CREATE EXTENSION IF NOT EXISTS plpgsql;
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_raster; -- OPTIONAL
CREATE EXTENSION postgis_topology; -- OPTIONAL

3.3.2. エクステンションを使わずに空間データベースを有効にする (お勧めしません)

[注記]

これは、通常はPostgreSQLのエクステンションのディレクトリ内にPostGISをインストールできないか、したくない場合 (たとえばテスト中や開発中、または制限のある環境内)にのみ必要となります。

ビルドの際に指定した [prefix]/share/contrib 内にある様々な SQL ファイルをロードして PostGIS オブジェクトと関数の定義をデータベースに追加します。

中核の PostGIS オブジェクト (ジオメトリ型とジオグラフィ型、これらに対応する関数) は postgis.sql スクリプトにあります。ラスターオブジェクトは rtpostgis.sql スクリプトにあります。トポロジオーブジェクトは topology.sql スクリプトにあります。

EPSG座標系定義IDの完全なテーブルを得るには、spatial_ref_sys.sql 定義ファイルをロードして spatial_ref_sys テーブルを生成して下さい。これによりジオメトリー関数 ST_Transform() が実行できるようになります。

PostGIS 関数にコメントを追加したい場合には、postgis_comments.sql スクリプト内にコメントがあります。コメントは \dd [関数名]psql のターミナルウィンドウから打ち込むだけで見ることができます。

ターミナルで次のシェルコマンドを実行します:

コード
DB=[yourdatabase]
SCRIPTSDIR=`pg_config --sharedir`/contrib/postgis-3.6/

# Core objects
psql -d ${DB} -f ${SCRIPTSDIR}/postgis.sql
psql -d ${DB} -f ${SCRIPTSDIR}/spatial_ref_sys.sql
psql -d ${DB} -f ${SCRIPTSDIR}/postgis_comments.sql # OPTIONAL

# Raster support (OPTIONAL)
psql -d ${DB} -f ${SCRIPTSDIR}/rtpostgis.sql
psql -d ${DB} -f ${SCRIPTSDIR}/raster_comments.sql # OPTIONAL

# Topology support (OPTIONAL)
psql -d ${DB} -f ${SCRIPTSDIR}/topology.sql
psql -d ${DB} -f ${SCRIPTSDIR}/topology_comments.sql # OPTIONAL

3.4. 空間データベースのアップグレード

既存の空間データベースのアップグレードは、新しいPostGISオブジェクト定義の置き換えや導入を必要とするとき、慎重を要することがあります。

不幸なことに、定義の全てが実行中のデータベース内で簡単に置き換えられるわけではないので、ダンプ/リロードが最善策となることがあります。

PostGISには、マイナーバージョンアップやバグフィクスリリースの場合に使うソフトアップグレードと、メジャーアップグレードで使うハードアップグレードが用意されています。

PostGISをアップグレードしようとする前にデータのバックアップを取ることは、常に価値のあるものです。pg_dumpで -Fc フラグを使うと、ハードアップグレードでダンプを常にリストアすることができます。

3.4.1. ソフトアップグレード

エクステンションを使ってデータベースをインストールした場合には、エクステンションモデルでアップグレードしなければなりません。古い SQL スクリプトを使ってインストールした場合には、SQL スクリプトは既にサポートされていませんので、エクステンションに切り替えるべきです。

3.4.1.1. エクステンションを使ったソフトアップグレード

PostGIS をエクステンションとして入れている場合には、アップグレードmのエクステンションを使う必要があります。エクステンションでのマイナーアップグレードではほとんど痛みは伴いません。

インストール済みのバージョンのうち最新のものにアップグレードするには PostGIS_Extensions_Upgrade 関数を使います。

コード
SELECT postgis_extensions_upgrade();

PostGIS 2.5 をまだ使っているデータベースをアップグレードするときには、 ALTER EXTENSIONpostgis_extensions_upgrade() に先立って使います。 ラスターエクステンションが独立する前の postgis_raster オブジェクトを確実に主エクステンションに折り込むようにするためです。

コード
ALTER EXTENSION postgis UPDATE;
SELECT postgis_extensions_upgrade();

この二つ目の関数呼出は postgis_raster エクステンションの再同梱が必要です。

コード
SELECT postgis_extensions_upgrade();

複数のバージョンのPostGISがインストールされていて、最新版にはアップグレードしたくない場合には、明示的なバージョンの指定ができます。次のようにします:

コード
ALTER EXTENSION postgis UPDATE TO "3.7.0dev";
ALTER EXTENSION postgis_topology UPDATE TO "3.7.0dev";

次のようなエラー通知が表示されることがあります:

出力
No migration path defined for … to 3.7.0dev

この場合には、データベースをバックアップして、 「エクステンションを使って空間データベースを有効にする」 に記述されているように新しいデータベースを生成し、バックアップを新しいデータベースにリストアしなければなりません。

次のようなメッセージを得ることがあります:

出力
Version "3.7.0dev" of extension "postgis" is already installed

この場合には、全てアップデートされていて、安全に無視できます。開発版からその次のバージョン (新しいバージョン番号を得ていないもの) にアップグレードしようと しない限り、"next"をバージョン文字列に追加できますが、次回に "next" を削除する必要があります:

コード
ALTER EXTENSION postgis UPDATE TO "3.7.0devnext";
        ALTER EXTENSION postgis_topology UPDATE TO "3.7.0devnext";
[注記]

PostGI Sをバージョン指定なしにインストールした場合には、 しばしばリストア前の PostGIS エクステンションの再インストールをとばすことができます。 バックアップには CREATE EXTENSION postgis があって、リストアの間に最新版になります。

[注記]

PostGIS エクステンションを 3.0.0より前からアップグレードする場合には新しいエクステンションpostgis_raster が入ることになります。このエクステンションはラスター機能が不要な場合には安全に削除することができます。

コード
DROP EXTENSION postgis_raster;

3.4.1.2. エクステンションを使わないソフトアップグレード

エクステンションはこれまでの多数のリリースに対応したインストール手法です。今なおパッケージ化されていないものをインストールしているのなら、エクステンションで作られたデータベース内で HARD UPGRADE を実行して、保持データをそちらに移行させて下さい。

3.4.1.3. ハードアップグレード

ハードアップグレードとは、PostGIS で利用可能なデータベースの完全なダンプ/リロードを意味します。PostGIS オブジェクトの内部格納状態が変更される場合や、ソフトアップグレードができない場合に、ハードアップグレードが必要です。付録の リリースノート に、バージョンごとのダンプ/リロード (ハードアップグレード)の要否を記載しています。

ダンプ/リロード作業は postgis_restore スクリプトが補助します。このスクリプトを使うと、PostGIS (古いものを含む) に属する定義を全て飛ばしてダンプします。また、重複シンボルエラーや非推奨オブジェクトを得ることなく、スキーマとデータを PostGIS をインストールしたデータベースにリストアできます 。

Windows ユーザー向けの捕捉手順は PostGIS Windows installation guide にあります。

手続きは次の通りです:

  1. アップグレードしたデータベース (olddb と呼ぶことにしましょう) の「カスタム書式」のダンプを、バイナリ BLOB データを含めたダンプを指定して (-b)、verbose モード (-v) で生成します。ユーザはデータベースのオーナーになることができ、PostgreSQL のスーパーユーザである必要はありません。

    コード
    pg_dump -h localhost -p 5432 -U postgres -Fc -b -v -f "/somepath/olddb.backup" olddb
  2. 新しいデータベースに PostGIS を、PostGIS が無い状態からインストールします。このデータベースを newdb と呼ぶことにします。この作業に関する説明については 「エクステンションを使わずに空間データベースを有効にする (お勧めしません)」「エクステンションを使って空間データベースを有効にする」 とを参照して下さい。

    ダンプにあるspatial_ref_sysのエントリはリストアされますが、既にあるspatial_ref_sysのエントリを上書きしません。リストア対象のデータベースに公式データセットの訂正が確実に伝わるようにするためです。なんらかの理由で標準のエントリを上書きしたい場合には、newdbを生成する際にspaltial_ref_sys.sqlファイルをロードしないだけです。

    データベースが本当に古くて、ビューや関数の中に、非推奨になってから長い関数があるような場合には、それらの関数やビューを使えるようにするlegacy.sqlをロードする必要があるでしょう。ただし「本当に」必要な場合に限ります。可能なら、ビューや関数をダンプせずにアップグレードすることを検討して下さい。非推奨関数は、uninstall_legacy.sqlで後から削除することができます。

  3. バックアップを新しいnewdbデータベースにリストアするには、postgis_restoreを使います。psqlが予期せぬエラーを標準エラー出力に出すことがあります。このエラーのログは保存しておいて下さい。

    コード
    postgis_restore "/somepath/olddb.backup" | psql -h localhost -p 5432 -U postgres newdb 2> errors.txt

エラーは次の場合に起こりえます:

  1. ビューまたは関数の中に非推奨のPostGISオブジェクトを使っているものがある場合。これの訂正には、リストア前にlegacy.sqlスクリプトのロードを試してみることができます。非推奨オブジェクトをまだ持っているバージョンのPostGISに戻して、コードを作り替えた後に再移行を試みることもできます。legacy.sqlを利用する場合は、コードを非推奨関数を使わないように訂正し、またuninstall_legacy.sqlをロードして非推奨オブジェクトを削除するのを忘れないでください。

  2. ダンプファイル内のspatial_ref_sysにあるカスタムレコードが不正なSRIDになっている場合。妥当なSRID値は0より大きく999000より小さくなります。999000から999999の間は内部利用のための予約領域ですが、SRID値 > 999999 の場合は、その値は一切使用できません。全ての不正なSRIDを持つ独自レコードは、SRID値 > 999999 の場合はに、予約領域に入るようSRID値が変更されたうえで保持されます。しかし、値を保持するために設定されているspatial_ref_sysテーブルのチェック制約が外れます。場合によっては (複数の不正なSRIDが同じ予約領域のSRID値に変換されるとき)、主キーも外れます。

    これを修正するために、独自のSRSを妥当な値 (910000..910999の範囲)のSRIDに複写し、全てのテーブルを新しいSRIDに変更 (UpdateGeometrySRID)して、spatial_ref_sysから不正なエントリを削除します。そして、次のようにチェック制約を再構築します:

    コード
    ALTER TABLE spatial_ref_sys ADD CONSTRAINT spatial_ref_sys_srid_check check (srid 
    > 0 AND srid < 999000 );
    
    コード
    ALTER TABLE spatial_ref_sys ADD PRIMARY KEY(srid));
        

    フランスIGN地図を含む古いデータベースをアップグレードする場合には、おそらくSRIDが範囲外になり、データベースのインポート時に次のような問題に遭遇します:

    コード
    WARNING: SRID 310642222 converted to 999175 (in reserved zone)

    この場合には、次のステップを試すことができます。最初にpostgis_restoreから出たIGNをSQLから完全に破棄します。そのために次のコマンドを実行します:

    コード
    postgis_restore "/somepath/olddb.backup" > olddb.sql

    次のコマンドを実行します:

    コード
    grep -v IGNF olddb.sql > olddb-without-IGN.sql

    newdbを生成し、PostGIS エクステンションを有効にし、このスクリプトを使ってフランス IGN 空間参照系を挿入します。この処理の後、データをインポートします:

    コード
    psql -h localhost -p 5432 -U postgres -d newdb -f olddb-without-IGN.sql  2> errors.txt