AlmaLinux 10.1 セットアップメモ
Section 2.1 データベースサーバー構築編(PostgreSQL)
About
PostgreSQLのインストールと設定手順を残しています。
環境は、Section 1.1~Section 1.3で作成したvirtualboxの環境で実行しています。 そのため、SELinuxは有効な状態で作業を進めています。
なお、この手順では、OS側で管理しているパッケージを使った構築手順となります。 いろいろ付随するものを入れる場合や、dnf管理されていないものがある場合は、PostgreSQL公式パッケージからのインストールになります。
起動後、rootアカウントになって作業を進めます。
パッケージの確認
Almalinux 8/9 では、AppStream というものでいくつかのアプリケーションが管理されていましたが、10 で廃止して 7 のころに戻るようです。 なので、リポジトリに登録されているものからパッケージ名とバージョンを指定してインストールすることになります。 まずは、提供されているかどうかを調べます。
[root@localhost ~]# dnf search postgresql
========================================== Name & Summary Matched: postgresql ==========================================
postgresql.x86_64 : PostgreSQL client programs
(略)
[root@localhost ~]# dnf repoquery postgresql
postgresql-0:16.10-1.el10_1.x86_64
postgresql-0:16.11-1.el10_1.x86_64
[root@localhost ~]#
複数のバージョンが登録されていますが、この場合はパッケージの更新があったレベルでしょう。
インストール
パッケージがあるのでインストールしていきましょう。
[root@localhost ~]# dnf -y install postgresql postgresql-server
Dependencies resolved.
========================================================================================================================
Package Architecture Version Repository Size
========================================================================================================================
Installing:
postgresql x86_64 16.11-1.el10_1 appstream 1.9 M
postgresql-server x86_64 16.11-1.el10_1 appstream 6.9 M
Installing dependencies:
libicu x86_64 74.2-5.el10_0 baseos 10 M
postgresql-private-libs x86_64 16.11-1.el10_1 appstream 143 k
Transaction Summary
========================================================================================================================
Install 4 Packages
(略)
Complete!
[root@localhost ~]#
インストールが終わりました。
ついでに、言語パックをインストールします。
[root@localhost ~]# dnf -y install langpacks-ja
Dependencies resolved.
========================================================================================================================
Package Architecture Version Repository Size
========================================================================================================================
Installing:
langpacks-ja noarch 4.1-3.el10 appstream 11 k
Installing dependencies:
default-fonts-cjk-sans noarch 4.1-3.el10 appstream 13 k
fonts-filesystem noarch 1:2.0.5-18.el10 baseos 7.7 k
google-noto-sans-cjk-vf-fonts noarch 1:2.004-9.el10 appstream 14 M
google-noto-sans-mono-cjk-vf-fonts noarch 1:2.004-9.el10 appstream 14 M
google-noto-serif-cjk-vf-fonts noarch 1:2.002-6.el10 appstream 20 M
langpacks-core-ja noarch 4.1-3.el10 appstream 11 k
langpacks-fonts-ja noarch 4.1-3.el10 appstream 11 k
Installing weak dependencies:
glibc-langpack-ja x86_64 2.39-58.el10_1.2.alma.1 baseos 350 k
Transaction Summary
========================================================================================================================
Install 9 Packages
(略)
Complete!
[root@localhost ~]#
これは日本語のデータに対するソート順をデフォルトで変えたい場合に使用するので、インストールしておきます。
データベースの初期化
DBの実体を保存する場所や設定なども無いので、それらもまとめて初期化します。
[root@localhost ~]# PGSETUP_INITDB_OPTIONS="--encoding=ja_jp.UTF-8" /usr/bin/postgresql-setup --initdb --unit postgresql
* Initializing database in '/var/lib/pgsql/data'
* Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log
[root@localhost ~]$
これで初期化できたので、サービスを起動していきます。
なお、間違った作られたファイルを消したい……となったとしても、/var/lib/pgsql は削除しないでください。 SELinuxコンテキストが変わってしまいサービスが起動できないなどの不具合が出てしまいます。
SELinuxのラベル変更方法
/var/lib/pgsql のコンテキストはOSで登録済みなので、設定を復元すればよいということになります。 なので、restorecon を使用して復元すれば対応できます。
[root@localhost ~]# restorecon -v -r /var/lib/pgsql
サービス
systemd を通じてサービスの有効化を行い、起動します。
[root@localhost ~]# systemctl enable postgresql
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql.service → /usr/lib/syst//system/postgresql.service.
[root@localhost ~]# systemctl start postgresql
[root@localhost ~]#
別のサーバーからアクセスさせる場合の設定
初期設定では、外部からのアクセスが完全に禁止されています。 仮想マシンを動作させているホストマシンにインストールしている pgAdminから操作する場合、外部からのアクセス扱いになるので設定が必要です。 外部からのアクセスを許可するように設定を変更してみましょう。
設定ファイルをコピーする場合はなるべく --preserve=context をつけて SELinuxのコンテキストを維持するようにしましょう。
[root@localhost ~]# cp --preserve=context /var/lib/pgsql/data/postgresql.conf /var/lib/pgsql/data/postgresql.conf.org
[root@localhost ~]# cat /var/lib/pgsql/data/postgresql.conf.org \
| sed -E "/^#listen_addresses .*$/i listen_addresses = '*'" \
> /var/lib/pgsql/data/postgresql.conf
[root@localhost ~]# diff -cT /var/lib/pgsql/data/postgresql.conf.org /var/lib/pgsql/data/postgresql.conf
*** /var/lib/pgsql/data/postgresql.conf.org YYYY-mm-dd hh:ii:ss.000000000 +0900
--- /var/lib/pgsql/data/postgresql.conf YYYY-mm-dd hh:ii:ss.000000000 +0900
***************
*** 57,62 ****
--- 57,63 ----
# - Connection Settings -
+ listen_addresses = '*'
#listen_addresses = 'localhost' # what IP address(es) to listenon;
# comma-separated list of addresses;
# defaults to 'localhost'; use '*' for all
listen_adresses を書き換えることになりますが、* はすべてを許可になるため、接続元がわかっている場合は制限を掛けるなどしても良いでしょう。
次に接続するユーザーの認証方式などを変更します。local接続がpeerだと不便だったりあまりよくないこともあるのですがとりあえず……
[root@localhost ~]# cp --preserve=context /var/lib/pgsql/data/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf.org
[root@localhost ~]# cat /var/lib/pgsql/data/pg_hba.conf.org \
| sed -E "s/(^host[ ]+all[ ]+all[ ]+)127.0.0.1\/32/\\1all /" \
| sed -E "s/(^host[ ]+all[ ]+all[ ]+)::1\/128/\\1all /" \
| sed -E "s/ident$/scram-sha-256/" \
> /var/lib/pgsql/data/pg_hba.conf
[root@localhost ~]# diff -cT /var/lib/pgsql/data/pg_hba.conf.org /var/lib/pgsql/data/pg_hba.conf
*** /var/lib/pgsql/data/pg_hba.conf.org YYYY-mm-dd hh:ii:ss.000000000 +0900
--- /var/lib/pgsql/data/pg_hba.conf YYYY-mm-dd hh:ii:ss.000000000 +0900
***************
*** 112,122 ****
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
! host all all 127.0.0.1/32 ident
# IPv6 local connections:
! host all all ::1/128 ident
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
! host replication all 127.0.0.1/32 ident
! host replication all ::1/128 ident
--- 112,122 ----
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
! host all all all scram-sha-256
# IPv6 local connections:
! host all all all scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
! host replication all 127.0.0.1/32 scram-sha-256
! host replication all ::1/128 scram-sha-256
設定を変えたらサービスを再起動しましょう。
[root@localhost ~]# systemctl restart postgresql
[root@localhost ~]#
ロールとデータベースを作成する
データベースにアクセスするためのユーザーと権限(ロール)とデータベースを作成します。
vagrant ユーザーがいるのでそのユーザー用のロールとを作成します。オプションは下記の通り。
| オプション | 内容 |
|---|---|
| -S | posgtresロールと同じ権限を持つスーパーユーザーではない |
| -R | ロールは別のロールを作成不可 |
| -d | ロールは新しいデータベースを作成可 |
| -P | 新しいロールにパスワードを割り当てる |
データベースも作れないようにするのが正解ではあるけれど、何かと面倒なので作成可能にしています。
パスワードの入力を求められるので、vagrant と入力してください。
[root@localhost ~]# su - postgres -c "createuser -S -R -d -P vagrant"
新しいロールのためのパスワード:
もう一度入力してください:
[root@localhost ~]#
データベースを作成します。
文字列のソート順を変えるかどうかで指定するかどうかが変わります。
| オプション | 内容 |
|---|---|
| -O | Databaseのオーナーロールの指定 |
| -E | 文字列の Encoding。基本的に UTF-8 でよい |
| —locale-provider | libc(デフォルト) または icu |
| —lc-collate | locale-provider が libc の場合の文字列の並べ替え順(デフォルトは C.UTF-8) |
| —lc-ctype | locale-provider が libc の場合の文字の分類方法(大文字小文字のの区別など) |
| —icu-collate | locale-provider が icu の場合の文字列の並べ替え順 |
| -T | template指定。デフォルトと異なる場合は template0 からしか作れないので指定が必要 |
全半角などの文字種別毎にソートしたいならデフォルトのままでいいので、-O と -E だけ指定すればよいです。
全半角関係なく読み通りにソートしたい場合は、--locale-provider で icu 指定になると思います。
どう変わるかは、最後に説明するとして、今回は混ぜた状態で作成します。
[root@localhost ~]# su - postgres -c "createdb -O vagrant -E UTF-8 --locale-provider=icu --icu-locale=ja-JP -T template0 vagrant"
[root@localhost ~]#
なお、開発時は必ず本番で使う設定で作成するようにしましょう。
接続確認
psqlコマンドを使ってアクセスします。
vagrant ユーザーになってから実行してください。
[vagrant@localhost ~]$ psql
psql (16.11)
"help"でヘルプを表示します。
vagrant=> \q
[vagrant@localhost ~]$
locale-provider による違いについて
ここからはlocale-providerの指定の違いについての説明なので、実行する必要はありません。
まずは、検証用に Locale Provider が libc で C.UTF-8 と ja_JP.UTF-8 のものと、icu で ja-JP(ja-x-icuと同じ意味) のものを作成します。
vagrant ユーザーで作業していきます。
[vagrant@localhost ~]$ createdb -E UTF-8 libc-C
[vagrant@localhost ~]$ createdb -E UTF-8 --lc-collate=ja_JP.UTF-8 --lc-ctype=ja_JP.UTF-8 -T template0 libc-ja_JP
[vagrant@localhost ~]$ createdb -E UTF-8 --locale-provider=icu --icu-locale=ja-JP -T template0 icu-ja-JP
[vagrant@localhost ~]$ psql -l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
------------+----------+----------+-----------------+-------------+-------------+------------+-----------+-----------------------
icu-ja-JP | vagrant | UTF8 | icu | C.UTF-8 | C.UTF-8 | ja-JP | |
libc-C | vagrant | UTF8 | libc | C.UTF-8 | C.UTF-8 | | |
libc-ja_JP | vagrant | UTF8 | libc | ja_JP.UTF-8 | ja_JP.UTF-8 | | |
postgres | postgres | UTF8 | libc | C.UTF-8 | C.UTF-8 | | |
template0 | postgres | UTF8 | libc | C.UTF-8 | C.UTF-8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | C.UTF-8 | C.UTF-8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
vagrant | vagrant | UTF8 | icu | C.UTF-8 | C.UTF-8 | ja-JP | |
(7 rows)
[vagrant@localhost ~]$
テーブルとデータがないと始まらないので、それぞれに投入するためのテキストを作成してデータベースに投入します。 いろいろと適当ですが…………
[vagrant@localhost ~]$ cat << 'EOS' > table_order_test.sql
DROP TABLE IF EXISTS order_test;
CREATE TABLE order_test (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
name_ruby TEXT NOT NULL
);
INSERT INTO order_test (name, name_ruby)
VALUES
('1', 'いち'),('2', 'に'),
('A', 'あ'),('I', 'い'),
('a', 'あ'),('i', 'い'),
('あ', 'あ'),('い', 'い'),
('ぁ', 'あ'),('ぃ', 'い'),
('ア', 'あ'),('イ', 'い'),
('ァ', 'あ'),('ィ', 'い'),
('ア', 'あ'),('イ', 'い'),
('1', 'イチ'),('2', 'ニ'),
('A', 'あ'),('I', 'い'),
('a', 'あ'),('i', 'い')
EOS
[vagrant@localhost ~]$ psql libc-C < table_order_test.sql
NOTICE: table "order_test" does not exist, skipping
DROP TABLE
CREATE TABLE
INSERT 0 20
[vagrant@localhost ~]$ psql libc-ja_JP < table_order_test.sql
NOTICE: table "order_test" does not exist, skipping
DROP TABLE
CREATE TABLE
INSERT 0 20
[vagrant@localhost ~]$ psql icu-ja-JP < table_order_test.sql
NOTICE: table "order_test" does not exist, skipping
DROP TABLE
CREATE TABLE
INSERT 0 20
[vagrant@localhost ~]$
これで準備ができたので、次のようなSQLをそれぞれのデータベースで実行します。
SELECT name FROM order_test ORDER BY name;
結果を横並びにしてみました。すべてが微妙に異なります。
| libc-C | libc-ja_JP | icu-ja-JP |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| A | A | 2 |
| I | I | 2 |
| a | a | a |
| i | i | a |
| ぁ | ア | A |
| あ | イ | A |
| ぃ | 1 | i |
| い | 2 | i |
| ァ | A | I |
| ア | I | I |
| ィ | a | ぁ |
| イ | i | ァ |
| 1 | ぁ | あ |
| 2 | あ | ア |
| A | ぃ | ア |
| I | い | ぃ |
| a | ァ | ィ |
| i | ア | い |
| ア | ィ | イ |
| イ | イ | イ |
これだけだとどれがいいのか……と思ってしまいそうなので、ルビというか読みと併せたらどうなるかを見てみます。 name_ruby は「読み仮名」という意味合いで振ったので、それを基準にソートしつつ name で並べてみます。
SELECT name_ruby, name FROM order_test ORDER BY name_ruby, name;
icu-ja-JP の場合は、 name_ruby の並び順が異なるので間をあけて出しています。
| name_ruby | libc-C | libc-ja_JP | icu-ja-JP | name_ruby | name |
|---|---|---|---|---|---|
| あ | A | A | あ | a | |
| あ | a | a | あ | a | |
| あ | ぁ | ア | あ | A | |
| あ | あ | A | あ | A | |
| あ | ァ | a | あ | ぁ | |
| あ | ア | ぁ | あ | ァ | |
| あ | A | あ | あ | あ | |
| あ | a | ァ | あ | ア | |
| あ | ア | ア | あ | ア | |
| い | I | I | い | i | |
| い | i | i | い | i | |
| い | ぃ | イ | い | I | |
| い | い | I | い | I | |
| い | ィ | i | い | ぃ | |
| い | イ | ぃ | い | ィ | |
| い | I | い | い | い | |
| い | i | ィ | い | イ | |
| い | イ | イ | い | イ | |
| いち | 1 | 1 | いち | 1 | |
| に | 2 | 2 | イチ | 1 | |
| イチ | 1 | 1 | に | 2 | |
| ニ | 2 | 2 | ニ | 2 |
Database作成時の設定で変わってしまうのはいろいろ不便だし、読み仮名は、icu の ja-x-icu を適応して、name は C.UTF-8 がいいなぁ……という場合はSQLで指定できます。
SELECT name_ruby, name FROM order_test ORDER BY name_ruby COLLATE "ja-x-icu", name COLLATE "C";
まぁ、そもそも読み仮名の入力を統一しろという話ですが…… ちなみに、Where区の以上以下にも影響します。
例えば、「ぁ」「あ」「ァ」「ア」「ア」を探したい場合は、icuなら WHERE name >= 'ぁ' and name <='ア' で探せます。
[vagrant@localhost ~]$ psql icu-ja-JP -c "select id, name From order_test where name >= 'ぁ' and name <='ア';"
name_ruby | name | id
-----------+------+----
あ | あ | 7
あ | ぁ | 9
あ | ア | 11
あ | ァ | 13
あ | ア | 15
(5 rows)
libc の場合は、並べた時点で飛び飛びなので引っ掛かりませんし、Where句に無理やり指定してもうまくいきません。 (同じ結果を出すための方法はあるかもしれませんが……)
[vagrant@localhost ~]$ psql libc-ja_JP -c "select id, name From order_test where name >= 'あ' and name <='ア';"
id | name
----+------
(0 rows)
[vagrant@localhost ~]$ psql libc-ja_JP -c "select id, name From order_test where name COLLATE \"ja-x-icu\" >= 'あ' and name COLLATE \"ja-x-icu\" <='ア';"
name_ruby | name | id
-----------+------+----
あ | あ | 7
あ | ア | 11
あ | ア | 15
(3 rows)
[vagrant@localhost ~]$
というわけで、デフォルトのままにするのか、変えるのかは目的に応じて適応するようにしてください。