ここで挙げる関数は、PostGISラスタにとって必要と思われるもので、現在PostGISラスタで有効なものです。他に、一般的なユーザが利用しない、ラスタオブジェクトに対して求められるサポート関数があります。
raster
は、ラスタデータの格納と分析のための新しいPostGIS型です。
ラスタファイルからラスタをロードするにはSection 9.1, “ラスタのロードと生成”を参照して下さい。
このリファレンスにおける例ではダミーラスタのラスタテーブルを使っています。ラスタは次のようなコードで形成しています。
CREATE TABLE dummy_rast(rid integer, rast raster); INSERT INTO dummy_rast(rid, rast) VALUES (1, ('01' -- little endian (uint8 ndr) || '0000' -- version (uint16 0) || '0000' -- nBands (uint16 0) || '0000000000000040' -- scaleX (float64 2) || '0000000000000840' -- scaleY (float64 3) || '000000000000E03F' -- ipX (float64 0.5) || '000000000000E03F' -- ipY (float64 0.5) || '0000000000000000' -- skewX (float64 0) || '0000000000000000' -- skewY (float64 0) || '00000000' -- SRID (int32 0) || '0A00' -- width (uint16 10) || '1400' -- height (uint16 20) )::raster ), -- Raster: 5 x 5 pixels, 3 bands, PT_8BUI pixel type, NODATA = 0 (2, ('01000003009A9999999999A93F9A9999999999A9BF000000E02B274A' || '41000000007719564100000000000000000000000000000000FFFFFFFF050005000400FDFEFDFEFEFDFEFEFDF9FAFEF' || 'EFCF9FBFDFEFEFDFCFAFEFEFE04004E627AADD16076B4F9FE6370A9F5FE59637AB0E54F58617087040046566487A1506CA2E3FA5A6CAFFBFE4D566DA4CB3E454C5665')::raster);
exclude_nodata_value
がFALSEに設定された場合には、NODATA
ピクセルを含む全てのピクセルがインタセクトするかが考慮され、値を返します。exclude_nodata_value
を渡さない場合には、ラスタのメタデータから読みます。NODATA
でない値を返します。 NODATA
でない2次元倍精度浮動小数点数配列を返します。 crop
が指定されていない場合には、TRUEと仮定され、出力ラスタをクロップします。TRUE
を返します。TRUE
を返します。TRUE
を返します。TRUE
を返します。倍精度浮動小数点数のバウンディングボックスを使います。TRUE
を返します。倍精度浮動小数点数のバウンディングボックスを使います。TRUE
を返します。TRUE
を返します。倍精度浮動小数点数のバウンディングボックスを使います。GDALはファイルを開く時に、そのファイルのディレクトリを熱心にスキャンして、他のファイルのカタログを構築します。このディレクトリに多数のファイル (千とか万とか)あるとします。一つのファイルを開くと動作が非常に遅くなります (特にNFSのようなネットワークドライブの場合)。
この振る舞いを制御するために、GDALにはGDAL_DISABLE_READDIR_ON_OPENという環境変数があります。GDAL_DISABLE_READDIR_ON_OPEN
をTRUE
に設定すると、ディレクトリのスキャンを無効にします。
Ubuntuでは (Ubuntu用PostgreSQLのパッケージを使っていると仮定します)、GDAL_DISABLE_READDIR_ON_OPEN
が/etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/environment内で設定できます (POSTGRESQL_VERSIONは9.6等のPostgreSQLのバージョンで、CLUSTER_NAMEはmaindb等のクラスタ名です)。PostGIS環境変数もここで同じく設定できます。
# environment variables for postmaster process
# This file has the same syntax as postgresql.conf:
# VARIABLE = simple_value
# VARIABLE2 = 'any value!'
# I. e. you need to enclose any value which does not only consist of letters,
# numbers, and '-', '_', '.' in single quotes. Shell commands are not
# evaluated.
POSTGIS_GDAL_ENABLED_DRIVERS = 'ENABLE_ALL'
POSTGIS_ENABLE_OUTDB_RASTERS = 1
GDAL_DISABLE_READDIR_ON_OPEN = 'TRUE'
LinuxとPostgreSQLが許している、開くことができるファイルの最大数は、通常は増加していません (通常、プロセスあたり1024ファイルです)。システムは人間のユーザが使用するという仮定に立っているからです。データベース外ラスタは、一つの妥当なクエリで簡単に制限超過させることができます (例えば、10年分のラスタからなるデータセットで、個々のラスタは日別最低気温、最大気温を持っていて、データセット内の最大値と最小値を得たい場合などです)。
最も簡単な変更方法は、PostgreSQL設定max_files_per_processです。デフォルトとして1000が設定されていますが、データベース外ラスタとしては非常に低い値です。安全な開始値は65536でしょう。ただし、実際には、これはデータベースとデータベースに対して実行されるクエリに依存します。サーバ開始時のみ、かつPostgreSQLコンフィギュレーションファイル (例: Ubuntu環境では/etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/postgresql.conf)内のみで設定できます。
...
# - Kernel Resource Usage -
max_files_per_process = 65536 # min 25
# (change requires restart)
...
主な変更はLinuxカーネルのファイルを開く制限です。次の通り、二つに分かれます。
システム全体で開くことができるファイルの最大数
プロセスごとに開くことができるファイルの最大数
次の例で、システム全体の、現在の開くことができるファイルの最大値を調べることができます。
$ sysctl -a | grep fs.file-max fs.file-max = 131072
返された値が十分には大きくない場合には、次に示す例に従って、/etc/sysctl.d/にファイルを追加します。
$ echo "fs.file-max = 6145324" > > /etc/sysctl.d/fs.conf $ cat /etc/sysctl.d/fs.conf fs.file-max = 6145324 $ sysctl -p --system * Applying /etc/sysctl.d/fs.conf ... fs.file-max = 2097152 * Applying /etc/sysctl.conf ... $ sysctl -a | grep fs.file-max fs.file-max = 6145324
PostgreSQLのサーバプロセスごとに開けるファイルの最大数を増やす必要があります。
現在のPostgreSQLサービスのプロセスは開くことができるファイルの最大数を使っていて、次の例のようになっています (PostgreSQLが実行されていることを確認して下さい)。
$ ps aux | grep postgres
postgres 31713 0.0 0.4 179012 17564 pts/0 S Dec26 0:03 /home/dustymugs/devel/postgresql/sandbox/10/usr/local/bin/postgres -D /home/dustymugs/devel/postgresql/sandbox/10/pgdata
postgres 31716 0.0 0.8 179776 33632 ? Ss Dec26 0:01 postgres: checkpointer process
postgres 31717 0.0 0.2 179144 9416 ? Ss Dec26 0:05 postgres: writer process
postgres 31718 0.0 0.2 179012 8708 ? Ss Dec26 0:06 postgres: wal writer process
postgres 31719 0.0 0.1 179568 7252 ? Ss Dec26 0:03 postgres: autovacuum launcher process
postgres 31720 0.0 0.1 34228 4124 ? Ss Dec26 0:09 postgres: stats collector process
postgres 31721 0.0 0.1 179308 6052 ? Ss Dec26 0:00 postgres: bgworker: logical replication launcher
$ cat /proc/31718/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 15738 15738 processes
Max open files 1024 4096 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 15738 15738 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
上の例では、プロセスに対する開くことができるファイルの制限が31718になっています。どのプロセスがどうするかは問題ではありません。関心を持っている応答はMax open filesです。
Max open filesのSoft LimitとHard LimitをPostgreSQLの設定で指定したmax_files_per_process
よりも多くなるようにしたいと思っています。この例では、max_files_per_process
を65536にしています。
Ubuntu (かつ、Ubuntu用PostgreSQLパッケージを使用しているものとします)では、Soft LimitとHard Limitの変更については、/etc/init.d/postgresql (SysV)または/lib/systemd/system/postgresql*.service (systemd)を編集するのが簡単な方法です。
まず、SysV Ubuntuを扱います。ulimit -H -n 262144とulimit -n 131072を/etc/init.d/postgresqlに追加します。
...
case "$1" in
start|stop|restart|reload)
if [ "$1" = "start" ]; then
create_socket_directory
fi
if [ -z "`pg_lsclusters -h`" ]; then
log_warning_msg 'No PostgreSQL clusters exist; see "man pg_createcluster"'
exit 0
fi
ulimit -H -n 262144
ulimit -n 131072
for v in $versions; do
$1 $v || EXIT=$?
done
exit ${EXIT:-0}
;;
status)
...
Ubuntuのsystemdを扱います。LimitNOFILE=131072を/lib/systemd/system/postgresql*.serviceの各ファイルの[Service]セクション内に記述します。
...
[Service]
LimitNOFILE=131072
...
[Install]
WantedBy=multi-user.target
...
必要なシステムの変更を行った後、デーモンのリロードを必ず行ってください。
systemctl daemon-reload