Greenplumのご紹介(備忘録をかねて)

##はじめに
物忘れが激しく、以前勉強したGreenplumについて記憶が曖昧になってきたので、備忘録もかねてGreenplumのご紹介をしたいと思います。

##Greenplumの概要

* 大規模な分析処理をサポートする超並列処理データベースサーバー(MPP)です。
* DBランキングを見てみると、2020年6月25日現在、[39位](https://db-engines.com/en/ranking "DB Ranking")です。Azure SQLDWHに勝ってるんですね。
* ざっくりとしたイメージは以下のような感じです。マスター、スタンバイが1台ずつあり、セグメントサーバーが2台以上で構成されます。マスターで実行計画を作成して各セグメントに配布、各セグメントがデータ抽出や結合を行ってマスターに結果を返す・・といった流れです。
![greenplum_image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568280/b9255500-c14a-816e-b1a3-e4eca7a3af70.jpeg)
* 上の図のとおり、セグメントサーバーには複数のPostgreSQLがぶら下がってます。これらは「セグメントインスタンス」と呼ばれ、PrimaryとMirrorが存在します。PrimaryのMirror(※コピー)が別のホスト上に作られる事で、高い耐障害性を実現します(構成にもよりますが、ある程度であればノードがダウンしても継続して稼働できます)。ただしマスターがダウンしたら自動フェールオーバーしないので、手動でスタンバイに切り替える必要があります。(上の図ではPrimary、Mirrorの数が各ホスト毎に2個ずつになっていますが、4でも8でもリソースが許す限り増やすことが可能です)
* ユーザーデータはセグメントインスタンス上に作成されますが、メタデータについてはマスターに作成されます。スタンバイはマスターデータのコピーになっていて、定期的にwalを同期しています。

* 必要に応じてスケールアウトが可能です。最小構成でスタートして状況に応じたリソース拡張ができるため経済的です。
* データの登録時にはあらかじめテーブルに定義された分散キーで各セグメントインスタンスに分散格納されます。(因みに分散キーの指定はパフォーマンスに直結します。分散キーは一意となる項目を明示的に設定するか、randomlyを推奨します。何も指定しないとテーブルの最初の列が分散キーとなるのですが、一意ではない列の場合は不均一を生み、最もデータ量が多いインスタンスに引きずられて全体の処理が遅くなります)
* データ抽出時には各セグメントインスタンスが協調しあって並列でデータ取得するので高速です。
* テーブル毎に行指向や列指向の選択ができたりします。
* 圧縮形式も自由度が高く、テーブル単位はもちろん列単位でも圧縮可能。zlibやquicklz(※OSS版ではquicklzは使えません)など使えます。
* パーティション機能もあって、リスト形式、範囲形式が指定可能です。ネストも可能です。工夫すれば特定パーティションだけAzureのBLOBにするとか、圧縮するとか色々と自由度が高いです。
* 高速なデータロード、アンロードが可能です(ペタバイト級のデータも扱える)
* PostgreSQLをベースに作られているので、使用感はほぼPostgreSQLと同じです。従ってPosgreSQLユーザーは学習コストが低いといえると思います。(因みに、現在最新の6.8ではPostgreSQL9.4を採用しているようです)
* PostgreSQLベースなのでMADLibなどの機械学習ライブラリやPostGISといった地理情報など各種extensionが扱えます。MPP型のDBでこれらの機能を使えるのは良いですね。
* PL/Container、PL/Java、PL/Python、PL/Rなど自分に合った言語でユーザー定義関数を作成可能です。(もちろん、PL/pgSQLも使えます)プログラム得意な方はチャレンジしてみてはいかがでしょうか。
* その他PXF(Hadoopや他のDBを直接SQLで操作可能)、GPText(Apache Solrを利用した全文検索機能)などいろいろな機能が追加可能です(このあたりをOSS版でできるのかは今後調べますが、Pivotal版では簡単に使えました)。
* Kubernetesにも対応していて、GKEにデプロイできたりします(時間があれば試したい)。
* Pivotalが提供している【Greenplum】と、そのオープンソース版の【GreenplumDB】がありますが、Pivotal版はすべての機能が使えます。
* pgAdminから接続可能なのがうれしいです。

・・etc

* 今回はオープンソース版を使ってインストールまでやってみようと思います。頑張れ、自分！

##最小構成

以下をご参照ください
[最小構成](http://docs.greenplum.org/6-8/install_guide/platform-requirements.html "最小構成")

##今回私が試す環境
上記最小構成を書いておいて恐縮なのですが、自宅のサーバーのメモリが16GBまでしかないため、今回は最小構成を無視します(MicroServerは長年使っていて愛着があります。ESXiは早めに[脆弱性対応(VMSA-2020-0015)](https://www.vmware.com/security/advisories/VMSA-2020-0015.html "VMSA-2020-0015")したほうがよさそうですね・・)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568280/1bbd4965-099b-d82f-6f78-6ea5fa430c0c.png)

各サーバーのスペックは以下の通りです。[HDP-Hive-UDTF検証](https://qiita.com/potato-refrain/items/655a032910d85573c213 "HDP-Hive-UDTF検証")と同様、厳しいです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568280/c5f388c9-6aca-db86-2655-44048474dadb.png)

* 因みに、ホスト名はGreenplumの慣習にならって以下のようにしています。
 * マスター・・・・・・・mdw
 * スタンバイマスター・・smdw
 * セグメント・・・・・・sdw(n) 


## ホストの初期設定(全ノードで作業必要)

[ご参考]()

※真面目に1台ずつ設定すると大変なので、自分は最初に1台完成させてからOVFファイルおよびディスクをエクスポート→インポートの方式をとりました。

### SELINUXの無効化
```bash
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
```
### Firewallの無効化

```bash
systemctl stop firewalld.service
systemctl disable firewalld.service
```

### hostsの設定
以下の通り/etc/hostsを設定(リソースの関係でDNSサーバーは使いません)

* ::1→コメントアウト
* 以下を追記

```bash
192.168.0.51 vmgpmdw vmgpmdw.potato.com
192.168.0.52 vmgpmdw vmgpsmdw.potato.com
192.168.0.53 vmgpmdw vmgpsdw1.potato.com
192.168.0.54 vmgpmdw vmgpsdw2.potato.com
```

### カーネルパラメータの設定

/etc/sysctl.confを以下のように設定します。

```bash
kernel.shmall = 364325
kernel.shmmax = 1492275200
kernel.shmmni = 4096
vm.overcommit_memory = 2 # See Segment Host Memory
vm.overcommit_ratio = 95 # See Segment Host Memory

net.ipv4.ip_local_port_range = 10000 65535 # See Port Settings
kernel.sem = 500 2048000 200 4096
kernel.sysrq = 1
kernel.core_uses_pid = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.msgmni = 2048
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.conf.all.arp_filter = 1
net.core.netdev_max_backlog = 10000
net.core.rmem_max = 2097152
net.core.wmem_max = 2097152
vm.swappiness = 10
vm.zone_reclaim_mode = 0
vm.dirty_expire_centisecs = 500
vm.dirty_writeback_centisecs = 100
vm.dirty_background_ratio = 3 # See System Memory
vm.dirty_ratio = 10
#vm.dirty_background_bytes = 1610612736
#vm.dirty_bytes = 4294967296
```

* 補足

[※ご参考](http://docs.greenplum.org/6-8/install_guide/prep_os.html "システムメモリ")

kernel.shmall、kernel.shmmaxは以下のように値を算出しました。

```bash
#kernel.shmall(=364325)
echo $(expr $(getconf _PHYS_PAGES) / 2) 

#kernel.shmmax(=1492275200)
echo $(expr $(getconf _PHYS_PAGES) / 2 \* $(getconf PAGE_SIZE)) 
```
また、メモリが64GB以下のホストではvm.dirty_background_bytesやvm.dirty_bytesは設定せず、vm.dirty_background_ratio、vm.dirty_ratioに値を設定するとのことです。


```bash
vm.dirty_background_ratio = 3 # See System Memory
vm.dirty_ratio = 10
#vm.dirty_background_bytes = 1610612736
#vm.dirty_bytes = 4294967296
```

### システムリソースの制限
/etc/security/limits.confに下記を追記します。

```bash
* soft nofile 524288
* hard nofile 524288
* soft nproc 131072
* hard nproc 131072
```

### ディスクI/O設定

ディスク2,3用に以下のように設定します。

```bash
/sbin/blockdev --setra 16384 /dev/sdb
/sbin/blockdev --setra 16384 /dev/sdc
```

### systemdの権限設定
/etc/rc.d/rc.localに権限設定をします。

```bash
chmod +x /etc/rc.d/rc.local
```

### disk I/O schedulerの設定
"elevator=deadline"を追加します。

```bash
grubby --update-kernel=ALL --args="elevator=deadline"
```

### THPの無効化
"transparent_hugepage=never"を追加します。

```bash
grubby --update-kernel=ALL --args="transparent_hugepage=never"
```

### IPCオブジェクトの削除
/etc/systemd/logind.confで、RemoveIPC=noを有効化します。

```bash
sed -i 's/#RemoveIPC=no/RemoveIPC=no/g' /etc/systemd/logind.conf
```

### データディレクトリ準備
ファイルシステム作成→マウント先のディレクトリ作成→fstabに追記→マウントという流れで/data1,/data2を作っていきます。

```bash
# ファイルシステムを作る(xfs必須です)
mkfs -t xfs /dev/sdb
mkfs -t xfs /dev/sdc

# マウント先のディレクトリを作成する
mkdir -p /data1
mkdir -p /data2

# マウントできるよう、fstabに追記します
echo "/dev/sdb /data1 xfs nodev,noatime,nobarrier,inode64 0 0" >> /etc/fstab
echo "/dev/sdc /data2 xfs nodev,noatime,nobarrier,inode64 0 0" >> /etc/fstab

mount -a
df -lh
# これで/data1,data2がマウントされていればOK。
# /dev/sdb          50G  296M   50G    1% /data1
# /dev/sdc          50G   33M   50G    1% /data2
```

##Greenplumのインストール(全ノードで作業必要)
いよいよインストールです。

### 管理ユーザー作成
Greenplumでは、管理ユーザー・グループとしてgpadminを使います。
パスワードはgpadminにしました(商用では複雑なものにしてください！試したことはないですが、Kerberos化もできるようです。[(ご参考)](https://gpdb.docs.pivotal.io/6-8/admin_guide/kerberos.html "Kerberos"))。

```bash
groupadd gpadmin
useradd gpadmin -r -m -g gpadmin
passwd gpadmin
```

### 鍵作成
各ノード間では双方向にパスワードレスのssh接続が必須となります。その準備として、各ノードにパスワードレスの鍵を作っておく必要があります。

```bash:root、gpadminで実施
su - gpadmin # rootでの実施の場合は不要
ssh-keygen -t rsa -b 4096 # Enterを連打してパスワードなしの鍵作成
```

### インストール
インストーラは下記にあります。

[Pivotal版](https://network.pivotal.io/products/pivotal-gpdb "Pivotal版のインストーラ")
[OSS版](https://github.com/greenplum-db/gpdb/releases/download/6.8.1/greenplum-db-6.8.1-rhel7-x86_64.rpm "OSS版のインストーラ")

今回はOSS版を使ってインストールを進めます。

```bash
wget https://github.com/greenplum-db/gpdb/releases/download/6.8.1/greenplum-db-6.8.1-rhel7-x86_64.rpm

# install
yum -y install greenplum-db-6.8.1-rhel7-x86_64.rpm

# 権限設定
chown -R gpadmin:gpadmin /usr/local/greenplum*
```
※本来であればInternetに接続できない環境だと思うので、Repositoryサーバーを立てるなどしたほうが良いかなと思います

### 双方向パスワードレスssh接続の準備(マスターでの作業)

```bash
# sshpassをインストールします
yum -y install sshpass

# gpadminに切り替えます
su - gpadmin

# ~/.bash_profileに以下を追記します
echo "source /usr/local/greenplum-db/greenplum_path.sh" >> ~/.bash_profile
source ~/.bash_profile

# 公開鍵を各サーバーに送付します
ssh-copy-id vmgpmdw
ssh-copy-id vmgpsmdw
ssh-copy-id vmgpsdw1
ssh-copy-id vmgpsdw2

# sshpassを利用して、一度パスワードレスの接続をします。
SSHPASS=gpadmin sshpass -e ssh-copy-id vmgpmdw
SSHPASS=gpadmin sshpass -e ssh-copy-id vmgpsmdw
SSHPASS=gpadmin sshpass -e ssh-copy-id vmgpsdw1
SSHPASS=gpadmin sshpass -e ssh-copy-id vmgpsdw2

# 各ノード名を列挙したファイルを準備します
[gpadmin@vmgpmdw ~]$ cat list.txt
vmgpmdw
vmgpsmdw
vmgpsdw1
vmgpsdw2

# gpssh-exkeysを使って、双方向のパスワード無し接続の設定を完了させます
gpssh-exkeys -f list.txt

# 確認(マスター→セグメント1)
[gpadmin@vmgpmdw ~]$ ssh vmgpsdw1
Last login: Thu Jun 25 20:44:03 2020 from vmgpmdw
[gpadmin@vmgpsdw1 ~]$

# 確認(セグメント1→マスター)
[gpadmin@vmgpsdw1 ~]$ ssh vmgpmdw
Last login: Fri Jun 26 12:57:40 2020
[gpadmin@vmgpmdw ~]$

# OK!

```

同様に、rootについても設定しておきます。

```bash
su -

# Greenplum関連のパスを通します
source /usr/local/greenplum-db/greenplum_path.sh

# 公開鍵を各サーバーに送付します
ssh-copy-id vmgpsmdw
ssh-copy-id vmgpsdw1
ssh-copy-id vmgpsdw2

# sshpassを利用して、一度パスワードレスの接続をします。
SSHPASS=xxx sshpass -e ssh-copy-id vmgpmdw
SSHPASS=xxx sshpass -e ssh-copy-id vmgpsmdw
SSHPASS=xxx sshpass -e ssh-copy-id vmgpsdw1
SSHPASS=xxx sshpass -e ssh-copy-id vmgpsdw2

# 各ノード名を列挙したファイルを準備します
[gpadmin@vmgpmdw ~]$ cat list.txt
vmgpmdw
vmgpsmdw
vmgpsdw1
vmgpsdw2

# gpssh-exkeysを使って、双方向のパスワード無し接続の設定を完了させます
gpssh-exkeys -f list.txt


# OK!

```

### データディレクトリ準備(マスター&rootユーザーで作業)

データを格納するディレクトリを作成していきます。

### マスター用

```bash:master用/data1配下に作成
# マスターのデータストレージ作成
mkdir -p /data1/master
chown gpadmin:gpadmin /data1/master
```

以降は、gpsshというツールを利用してリモートでコマンドを実行していきます。
※gpsshはgreenplumに含まれます

### スタンバイマスター用

```bash:standby-master用/data1配下に作成
# スタンバイマスターのデータストレージ作成
source /usr/local/greenplum-db/greenplum_path.sh 
gpssh -h vmgpsmdw -e 'mkdir -p /data1/master'
gpssh -h vmgpsmdw -e 'chown gpadmin:gpadmin /data1/master'
```

### セグメント用

```bash:segment用/data1,/data2配下に作成
# セグメントのデータストレージ作成
# セグメントを列挙
[root@vmgpmdw ~]# cat hostfile_gpssh_segonly
vmgpsdw1
vmgpsdw2

# パスを通して・・
source /usr/local/greenplum-db/greenplum_path.sh 

# 各ディレクトリにprimary,mirror用ディレクトリを作成
gpssh -f hostfile_gpssh_segonly -e 'mkdir -p /data1/primary'
gpssh -f hostfile_gpssh_segonly -e 'mkdir -p /data1/mirror'
gpssh -f hostfile_gpssh_segonly -e 'mkdir -p /data2/primary'
gpssh -f hostfile_gpssh_segonly -e 'mkdir -p /data2/mirror'
gpssh -f hostfile_gpssh_segonly -e 'chown -R gpadmin /data1/*'
gpssh -f hostfile_gpssh_segonly -e 'chown -R gpadmin /data2/*'

```

## Greenplum初期化(マスターでgpadminユーザーで作業)
Greenplumは、インストールしただけでは使えず、初期化(=Greenplumクラスタ作成)してあげる必要があります(PostgreSQLと同様ですね)。
尚、今回初期化と同時に【potato】というDBも一緒に作ります。ロケールはja_JP.utf8を指定します。

ここで、もう一度これから作るクラスタのイメージを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568280/1bbd4965-099b-d82f-6f78-6ea5fa430c0c.png)

インスタンスレベルでは、以下のようにしたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568280/48d85905-c8f6-1ade-04ca-f8b92f84f6d3.png)

▼まとめると、以下のような構成です
マスターインスタンス：1
スタンバイマスターインスタンス：1
セグメントインスタンス(Primary)：2/1台あたり
セグメントインスタンス(Mirror)：2/1台あたり

では、初期化していきます！

### 初期化設定ファイルをテンプレートからコピー

```bash
cp -f $GPHOME/docs/cli_help/gpconfigs/gpinitsystem_config gpinitsystem_config
```

### 初期化設定ファイルの編集

上記の構成を元に以下のように編集しました。

```bash:~/gpinitsystem_config
# FILE NAME: gpinitsystem_config

# Configuration file needed by the gpinitsystem

################################################
#### REQUIRED PARAMETERS
################################################

#### Name of this Greenplum system enclosed in quotes.
ARRAY_NAME="Potato-Greenplum"

#### Naming convention for utility-generated data directories.
SEG_PREFIX=gpseg

#### Base number by which primary segment port numbers
#### are calculated.
PORT_BASE=6000

#### File system location(s) where primary segment data directories
#### will be created. The number of locations in the list dictate
#### the number of primary segments that will get created per
#### physical host (if multiple addresses for a host are listed in
#### the hostfile, the number of segments will be spread evenly across
#### the specified interface addresses).
declare -a DATA_DIRECTORY=(/data1/primary /data2/primary)

#### OS-configured hostname or IP address of the master host.
MASTER_HOSTNAME=vmgpmdw

#### File system location where the master data directory
#### will be created.
MASTER_DIRECTORY=/data1/master

#### Port number for the master instance.
MASTER_PORT=5432

#### Shell utility used to connect to remote hosts.
TRUSTED_SHELL=ssh

#### Maximum log file segments between automatic WAL checkpoints.
CHECK_POINT_SEGMENTS=8

#### Default server-side character set encoding.
ENCODING=UNICODE

################################################
#### OPTIONAL MIRROR PARAMETERS
################################################

#### Base number by which mirror segment port numbers
#### are calculated.
MIRROR_PORT_BASE=7000

#### File system location(s) where mirror segment data directories
#### will be created. The number of mirror locations must equal the
#### number of primary locations as specified in the
#### DATA_DIRECTORY parameter.
declare -a MIRROR_DATA_DIRECTORY=(/data1/mirror /data2/mirror)


################################################
#### OTHER OPTIONAL PARAMETERS
################################################

#### Create a database of this name after initialization.
DATABASE_NAME=potato

#### Specify the location of the host address file here instead of
#### with the -h option of gpinitsystem.
#MACHINE_LIST_FILE=/home/gpadmin/gpconfigs/hostfile_gpinitsystem
[gpadmin@vmgpmdw ~]$ cp -f $GPHOME/docs/cli_help/gpconfigs/gpinitsystem_config gpinitsystem_config
[gpadmin@vmgpmdw ~]$ cat gpinitsystem_config
# FILE NAME: gpinitsystem_config

# Configuration file needed by the gpinitsystem

################################################
#### REQUIRED PARAMETERS
################################################

#### Name of this Greenplum system enclosed in quotes.
ARRAY_NAME="Potato-Greenplum"

#### Naming convention for utility-generated data directories.
SEG_PREFIX=gpseg

#### Base number by which primary segment port numbers
#### are calculated.
PORT_BASE=6000

#### File system location(s) where primary segment data directories
#### will be created. The number of locations in the list dictate
#### the number of primary segments that will get created per
#### physical host (if multiple addresses for a host are listed in
#### the hostfile, the number of segments will be spread evenly across
#### the specified interface addresses).
declare -a DATA_DIRECTORY=(/data1/primary /data2/primary)

#### OS-configured hostname or IP address of the master host.
MASTER_HOSTNAME=vmgpmdw

#### File system location where the master data directory
#### will be created.
MASTER_DIRECTORY=/data1/master

#### Port number for the master instance.
MASTER_PORT=5432

#### Shell utility used to connect to remote hosts.
TRUSTED_SHELL=ssh

#### Maximum log file segments between automatic WAL checkpoints.
CHECK_POINT_SEGMENTS=8

#### Default server-side character set encoding.
ENCODING=UNICODE

################################################
#### OPTIONAL MIRROR PARAMETERS
################################################

#### Base number by which mirror segment port numbers
#### are calculated.
MIRROR_PORT_BASE=7000

#### File system location(s) where mirror segment data directories
#### will be created. The number of mirror locations must equal the
#### number of primary locations as specified in the
#### DATA_DIRECTORY parameter.
declare -a MIRROR_DATA_DIRECTORY=(/data1/mirror /data2/mirror)


################################################
#### OTHER OPTIONAL PARAMETERS
################################################

#### Create a database of this name after initialization.
DATABASE_NAME=potato

#### Specify the location of the host address file here instead of
#### with the -h option of gpinitsystem.
#MACHINE_LIST_FILE=/home/gpadmin/gpconfigs/hostfile_gpinitsystem
```

ポイントとしては、以下の通りです。

* ARRAY_NAME：任意のクラスタ名を指定します。
* DATA_DIRECTORY：プライマリのセグメントインスタンスのディレクトリと、インスタンス数を決定します。例えば以下のようにすると、/data1配下に1つ、/data2配下に1つのセグメントインスタンスが作成されます。

```bash:書き方
declare -a DATA_DIRECTORY=(/data1/primary /data2/primary)

# 下のように書くと、/data1配下に2つ、/data2配下に2つのセグメントインスタンスができます。
# declare -a DATA_DIRECTORY=(/data1/primary /data1/primary /data2/primary /data2/primary)

```

* MASTER_HOSTNAME：マスターのホスト名を指定します(今回はvmgpmdw)
* MASTER_DIRECTORY：マスターインスタンスのディレクトリを指定します。(今回は/data1/master)
* MASTER_PORT：Greenplumは、マスターインスタンスの接続ポートを指定します。(Greenplumはマスターインスタンス経由でクエリを実行します。今回はデフォルトの5432のままとします)
* MIRROR_PORT_BASE：ミラーセグメントのポート番号です。コメントアウトを外すと、ミラーが有効化されます。
* MIRROR_DATA_DIRECTORY：ミラーセグメントインスタンスの格納先ディレクトリです。書き方はDATA_DIRECTORYと同様です。
* DATABASE_NAME：初期化時に同時に作成するDB名を指定します。今回は「potato」を指定します。

### 初期化実施
以下のコマンドを実行して初期化を実施します。

```bash:初期化
su - gpadmin
gpinitsystem -c $(pwd)/gpinitsystem_config -h $(pwd)/hostfile_gpinitsystem -s vmgpsmdw -n ja_JP.utf8
```

仕上げとして、~/.bash_profileにマスターインスタンスのディレクトリを追記します。

```bash:~/.bash_profileに追記
export MASTER_DATA_DIRECTORY=/data1/master/gpseg-1
```
修正したら、再度読み込みます。

```bash
source ~/.bash_profile
```

### 確認
うまく初期化できていれば、psqlで接続可能です。

```bash:確認
[gpadmin@vmgpmdw ~]$ psql -d potato
psql (9.4.24)
Type "help" for help.

potato=#
```
問題なく接続できました！
また、DB一覧を確認すると正しくロケールも設定されていることがわかります。

```bash:DBリスト
                              List of databases
   Name    |  Owner  | Encoding |  Collate   |   Ctype    |  Access privileges
-----------+---------+----------+------------+------------+---------------------
 postgres  | gpadmin | UTF8     | ja_JP.utf8 | ja_JP.utf8 |
 potato    | gpadmin | UTF8     | ja_JP.utf8 | ja_JP.utf8 |

```

## 認証、認可など
せっかくなので、新たにロール【potatoman】を作成して、新規スキーマ【fat】にFULL権限を付与してみます。

```sql:スキーマ作成～権限付与～各種設定
[gpadmin@vmgpmdw ~]$ psql -d potato
psql (9.4.24)
Type "help" for help.

potato=# -- Schema作成
potato=# create schema fat;
CREATE SCHEMA

potato=# -- role作成(ログインする際にmd5方式を採用します)
potato=# create role potatoman login  encrypted password 'potato';
NOTICE:  resource queue required -- using default resource queue "pg_default"
CREATE ROLE

potato=--fatに対して全権限を付与
potato=grant all on schema fat to potatoman;
GRANT

-- # search_path変更(potatomanがログインしたときに参照するスキーマとしてfatを指定します)
potato=# ALTER ROLE potatoman SET search_path TO fat;
ALTER ROLE

-- # publicスキーマは削除します
potato=# drop schema public;
```

次に、postgresql.confのlisten_addressを変更・・と思いきや、すでにlisten_address='*'となっているので何もしません。

もう一つ、pg_hba.confを修正してpotatomanのクライアント認証を有効化します。(この辺りの手順も、PostgreSQLと同じですね)

```bash:$MASTER_DATA_DIR/pg_hba.confに追記
host    potato  potatoman       192.168.0.51/32 md5
host    potato  potatoman       192.168.0.52/32 md5
host    potato  potatoman       192.168.0.53/32 md5
host    potato  potatoman       192.168.0.54/32 md5
```
上記のようにすることで、各ノードからpsqlで接続できるようにします。

ここまでの修正をGreenplumに反映するには、gpstop -uを実行します。

```bash:再読み込み
gpstop -u
```

* 接続確認

```sql:接続確認
# 確認
[gpadmin@vmgpmdw ~]$ psql -d potato -h vmgpmdw -U potatoman
Password for user potatoman:
psql (9.4.24)
Type "help" for help.

potato=>

potato=> create table test(id int);
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
CREATE TABLE
potato=> insert into test values (1);
INSERT 0 1
potato=> insert into test values (2);
INSERT 0 1
potato=> select * from test;
 id
----
  2
  1
(2 rows)

potato=> update test set id = 3 where id =1;
UPDATE 1
potato=> delete from test;
DELETE 2
potato=> drop table test;
DROP TABLE
potato=> \q
[gpadmin@vmgpmdw ~]$
```
問題なく使えるようになりました！

今回はインストール、初期化まで実施しました。
次回はバックアップやデータロードなどを取り扱いたいと思います。

## 感想
久しぶりに触りましたが、やはり忘れている部分がかなりありました。
少しずつでも、記憶の定着のためにアウトプットしていきたいと思います。

Greenplumを気軽に試したいという方は、Sandobxやdockerイメージもあるのでお試しください。