Docker 公式イメージで PostgreSQL

## 私と PostgresSQL

posgre との出会いは 1998 年頃だったと思います。
当時所属していた会社では 64kbps (!) の専用線でインターネットに常時接続する環境があり、DNSサーバ、webサーバ、メールサーバを社内で運用していました。

ある製薬会社からドクター (医師? 博士?) 向けのアンケートサイトを作りたいという依頼があって、そのお手伝いをしたことがありました。

- システムの利用者はIDとパスワード認証でログイン
- IDとパスワードは製薬会社から依頼された内容を運営会社 (弊社) で設定
- アンケートの設問は利用者が自由に設定できる
- 回答は単一選択、複数選択、数値入力、テキスト入力が可能
- 回答後はすぐに集計結果をグラフまたはテキスト表示
- 月末にアンケートの設問と回答を CSVファイルに出力して運営会社から製薬会社に提出

といった内容でした。

今では Google フォーム など様々なサービスが選択可能ですが、25年前、データベースというと solaris + oracle 全盛時代ですので、本来ならそのようなプラットフォームでアンケートサイトも構築されるはずだったと思います。ご予算的な制約から、弊社にて linux + apache + php + postgres という開発スタイルを選択されたものと思われます。

時代は変わり、25年を経てふたたび posgre を触ることになりました。
では、さっそくはじめてみたいと思います。

## データベース構築

25年前は AT互換機を購入、linux インストール、posgre インストール、posgre に接続可能な apache + php の環境を２日ほどでしょうか、思考錯誤しながら構築しました。
現在だと、postgreSQL公式の Dockerイメージがありますので、２、３のコマンドのポチポチすれば、環境構築が完了します。

- [Postgresドッカーの公式イメージの使用方法](https://www.docker.com/ja-jp/blog/how-to-use-the-postgres-docker-official-image/)

### docker image pull

```
(base) $ docker pull postgres:17
17: Pulling from library/postgres
83d624c4be2d: Pull complete
b0dd2bf7a180: Pull complete
5ecbc93de950: Pull complete
90646cadd7e6: Pull complete
e1dbef7dcaa1: Pull complete
f7fdac227b96: Pull complete
425a818d8223: Pull complete
c0a40d31bfac: Pull complete
e868621ffb41: Pull complete
f6ce5b6f352e: Pull complete
6b732c95d024: Pull complete
3dc01759541c: Pull complete
ba6e84deecdb: Pull complete
159c4494c279: Pull complete
Digest: sha256:8d3be35b184e70d81e54cbcbd3df3c0b47f37d06482c0dd1c140db5dbcc6a808
Status: Downloaded newer image for postgres:17
docker.io/library/postgres:17
(base) $ docker image ls
REPOSITORY   TAG            IMAGE ID       CREATED         SIZE
postgres     17             6c9aa6ecd71d   5 weeks ago     456MB
node         18             ad27b5c3226e   14 months ago   1.09GB
node         18-alpine      385311cb02d5   15 months ago   174MB
mysql        8              1732fe3340d5   16 months ago   587MB
mysql        latest         1732fe3340d5   16 months ago   587MB
node         18.3.0         7b00050087d7   2 years ago     944MB
node         latest         c5eff22fd5f2   2 years ago     941MB
node         current-slim   91437799119e   3 years ago     167MB
(base) $
```

### docker image run

```
(base) $ pwd
/Users/r/Dev/posgre
(base) $ docker run --name posgre -e POSTGRES_PASSWORD=posgre! -v $PWD/pgdata:/var/lib/postgresql/data -d postgres:17
e21fe94b4b7bd8941cd7f55979c4fdf231bd45edae06ea172d24bf58ee941b10
(base) $ ls
docker-compose.yml	pgdata
(base) $ cd pgdata
(base) $ ls
PG_VERSION		pg_dynshmem		pg_multixact		pg_snapshots		pg_tblspc		postgresql.auto.conf
base			pg_hba.conf		pg_notify		pg_stat			pg_twophase		postgresql.conf
global			pg_ident.conf		pg_replslot		pg_stat_tmp		pg_wal			postmaster.opts
pg_commit_ts		pg_logical		pg_serial		pg_subtrans		pg_xact			postmaster.pid
(base) $
```

２つのコマンドで posgre が起動できました。

### create database

```
(base) $ docker container exec -it e21fe94b4b7bd8941cd7f55979c4fdf231bd45edae06ea172d24bf58ee941b10 /bin/bash
root@e21fe94b4b7b:/# su - postgres
postgres@e21fe94b4b7b:~$ psql
psql (17.0 (Debian 17.0-1.pgdg120+1))
Type "help" for help.

postgres=# \l
                                                    List of databases
   Name    |  Owner   | Encoding | Locale Provider |  Collate   |   Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+------------+------------+--------+-----------+-----------------------
 postgres  | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           |
 template0 | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/postgres          +
           |          |          |                 |            |            |        |           | postgres=CTc/postgres
 template1 | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/postgres          +
           |          |          |                 |            |            |        |           | postgres=CTc/postgres
(3 rows)

postgres=# create database bkiban;
CREATE DATABASE
postgres=# \l
                                                    List of databases
   Name    |  Owner   | Encoding | Locale Provider |  Collate   |   Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+------------+------------+--------+-----------+-----------------------
 bkiban    | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           |
 postgres  | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           |
 template0 | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/postgres          +
           |          |          |                 |            |            |        |           | postgres=CTc/postgres
 template1 | postgres | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/postgres          +
           |          |          |                 |            |            |        |           | postgres=CTc/postgres
(4 rows)

postgres=#
```


### create table

```
postgres=# \c bkiban
You are now connected to database "bkiban" as user "postgres".
bkiban=# create table um (
bkiban(# userid varchar(16) not null
bkiban(# , madd varchar(128) not null
bkiban(# , primary key (userid)
bkiban(# , unique (madd));
CREATE TABLE
bkiban=# \dt;
        List of relations
 Schema | Name | Type  |  Owner
--------+------+-------+----------
 public | um   | table | postgres
(1 row)

bkiban=# \d um;
                        Table "public.um"
 Column |          Type          | Collation | Nullable | Default
--------+------------------------+-----------+----------+---------
 userid | character varying(16)  |           | not null |
 madd   | character varying(128) |           | not null |
Indexes:
    "um_pkey" PRIMARY KEY, btree (userid)
    "um_madd_key" UNIQUE CONSTRAINT, btree (madd)

bkiban=#
```

## ps コマンドが使えない

```
root@e21fe94b4b7b:/var/lib/postgresql/data# ps -ef | grep postgres
bash: ps: command not found
root@e21fe94b4b7b:/var/lib/postgresql/data#
```

なんということでしょう。軽量を極めているわけですね。linux ディストリビューションを確認します。

```
root@e21fe94b4b7b:/etc# cat os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@e21fe94b4b7b:/etc#
```

ps インストール

```
root@e21fe94b4b7b:/etc# apt update && apt install -y procps

(snip)

Setting up psmisc (23.6-1) ...
Setting up libproc2-0:arm64 (2:4.0.2-3) ...
Setting up procps (2:4.0.2-3) ...
Processing triggers for libc-bin (2.36-9+deb12u8) ...
root@e21fe94b4b7b:/etc#
```

あらためて posgre のプロセスを確認してみます。

```
root@e21fe94b4b7b:/etc# ps -ef | grep postgres
postgres     1     0  0 Nov15 ?        00:00:04 postgres
postgres    61     1  0 Nov15 ?        00:00:00 postgres: checkpointer
postgres    62     1  0 Nov15 ?        00:00:00 postgres: background writer
postgres    64     1  0 Nov15 ?        00:00:01 postgres: walwriter
postgres    65     1  0 Nov15 ?        00:00:01 postgres: autovacuum launcher
postgres    66     1  0 Nov15 ?        00:00:00 postgres: logical replication launcher
root        87    79  0 Nov15 pts/0    00:00:00 su - postgres
postgres    88    87  0 Nov15 pts/0    00:00:00 -bash
postgres   823    88  0 Nov15 pts/0    00:00:00 /usr/lib/postgresql/17/bin/psql bkiban
postgres   896     1  0 Nov15 ?        00:00:00 postgres: postgres bkiban [local] idle
root      1950   338  0 02:08 pts/1    00:00:00 grep postgres
root@e21fe94b4b7b:/etc#
```

- postgres: おそらくこれがマスタサーバプロセス
- background writer: writer プロセス
- walwriter: WAL (Write Ahead Logging) をディスクに書き出すプロセス
- checkpointer: チェックポインタプロセス
- autovacuum launcher: 自動 vacuum を制御するプロセス
- postgres bkiban [local] idle: バックエンドプロセスと呼ばれる、クライアント接続要求受付、クエリ実行、実行結果返却を行うプロセス
- logical replication launcher: バックグラウンドワーカと呼ばれる、ロジカルレプリケーション用のワーカプロセス

んー　status collector: 統計情報コレクタ　がありませんね、、、、

## pg_freespace が使えない

```
ERROR:  function pg_freespace(unknown) does not exist
LINE 1: SELECT * FROM pg_freespace('foo');
                      ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
bkiban=#
```