rasterは、ラスターデータを格納、解析するための PostGIS 型です。
ラスターファイルからラスターをロードするには「ラスターのロードと生成」を参照して下さい。
このリファレンスで使うダミーデータのラスターテーブルの作り方は次の通りです:
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);
下に示す関数は PostGIS ラスターのユーザにとって必要そうなものです。他にも一般的なユーザにとって興味のないラスター対応関数があります。
本節では、ラスター機能をサポートするために作られた PostgreSQL データ型の一覧を挙げます。
exclude_nodata_valueが FALSE に設定された場合には、NODATA ピクセルを含む全てのピクセルがインタセクトするかが考慮され、値を返します。exclude_nodata_valueを渡さない場合には、ラスターのメタデータから読みます。
NODATAでない値を返します。
NODATAでない 2次元倍精度浮動小数点数配列を返します。
cropが指定されていなかったり TRUE となっている場合には、出力ラスターは切り取られます。touchedが TRUE の場合には、接触するピクセルは取り込まれ、TRUE でない場合には、中心がジオメトリー内にあるピクセルだけが取り込まれます。
TRUEを返します。
TRUEを返します。
TRUE を返します。
TRUEを返します。倍精度浮動小数点数のバウンディングボックスを使います。
TRUEを返します。倍精度浮動小数点数のバウンディングボックスを使います。
TRUEを返します。
TRUEを返します。倍精度浮動小数点数のバウンディングボックスを使います。
本節では、PostGIS ラスターに関連する様々な落とし穴や技法について説明します。
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