Greenplumのバックアップ(OSS版)(備忘録をかねて2)

##はじめに
[前回](https://qiita.com/potato-refrain/items/ae84eb20bba14d78c99a "Greenplumのご紹介(備忘録をかねて)")、Greenplumについてご紹介しました。今回はOSS版のバックアップ、リストア方法を記載します。

##概要
* Greenplumのバックアップおよびリストアはgpbackup/gprestoreで行います。
* gpbackupを利用すると、各セグメントインスタンス(primary)のディレクトリにバックアップファイルが作成されます。並列に処理を行うため、非常に高速です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568280/8744f5ce-a576-3535-be28-2fb40d78dc0c.png" width=70%>

gpbackupを実行すると、各データディレクトリには以下のようにバックアップデータが格納されます。(スタンバイマスター(vmgpsmdw)やMirrorセグメントにはバックアップデータが格納されないのが確認できます。また、マスター(vmgpmdw)にはyamlなどメタデータが格納されていることも確認できます。各セグメントインスタンスにはgz圧縮されたファイルが格納されていますね。)

```bash
# gpsshを使ってクラスタ内全ホストにコマンドを実行します
[gpadmin@vmgpmdw ~]$ gpssh -f list.txt -e "find /data*/*|grep backups"
[vmgpsmdw] find /data*/*|grep backups
[vmgpsdw1] find /data*/*|grep backups
[vmgpsdw1] /data1/primary/gpseg0/backups
[vmgpsdw1] /data1/primary/gpseg0/backups/20200624
[vmgpsdw1] /data1/primary/gpseg0/backups/20200624/20200624215519
[vmgpsdw1] /data1/primary/gpseg0/backups/20200624/20200624224704
[vmgpsdw1] /data1/primary/gpseg0/backups/20200624/20200624224704/gpbackup_0_20200624224704_16401.gz
[vmgpsdw1] /data2/primary/gpseg1/backups
[vmgpsdw1] /data2/primary/gpseg1/backups/20200624
[vmgpsdw1] /data2/primary/gpseg1/backups/20200624/20200624215519
[vmgpsdw1] /data2/primary/gpseg1/backups/20200624/20200624224704
[vmgpsdw1] /data2/primary/gpseg1/backups/20200624/20200624224704/gpbackup_1_20200624224704_16401.gz
[ vmgpmdw] find /data*/*|grep backups
[ vmgpmdw] /data1/master/gpseg-1/backups
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624215519
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624215519/gpbackup_20200624215519_metadata.sql
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624215519/gpbackup_20200624215519_toc.yaml
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624215519/gpbackup_20200624215519_config.yaml
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624215519/gpbackup_20200624215519_report
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624224704
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624224704/gpbackup_20200624224704_metadata.sql
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624224704/gpbackup_20200624224704_toc.yaml
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624224704/gpbackup_20200624224704_config.yaml
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624224704/gpbackup_20200624224704_report
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624224704/gprestore_20200624224704_20200624225038_report
[ vmgpmdw] /data1/master/gpseg-1/backups/20200624/20200624224704/gprestore_20200624224704_20200624225118_report
[vmgpsdw2] find /data*/*|grep backups
[vmgpsdw2] /data1/primary/gpseg2/backups
[vmgpsdw2] /data1/primary/gpseg2/backups/20200624
[vmgpsdw2] /data1/primary/gpseg2/backups/20200624/20200624215519
[vmgpsdw2] /data1/primary/gpseg2/backups/20200624/20200624224704
[vmgpsdw2] /data1/primary/gpseg2/backups/20200624/20200624224704/gpbackup_2_20200624224704_16401.gz
[vmgpsdw2] /data2/primary/gpseg3/backups
[vmgpsdw2] /data2/primary/gpseg3/backups/20200624
[vmgpsdw2] /data2/primary/gpseg3/backups/20200624/20200624215519
[vmgpsdw2] /data2/primary/gpseg3/backups/20200624/20200624224704
[vmgpsdw2] /data2/primary/gpseg3/backups/20200624/20200624224704/gpbackup_3_20200624224704_16401.gz

```

※尚、PostgreSQLのpg_dumpの利用可能ですが、バックアップ対象の全データをマスターインスタンスに保存するため非並列でありgpbackupと比べると遅いです。特別な事情がある場合を除き、非推奨となります。

* 以前の5.x系ではGreenplumをインストールすると、自動的にbackupのコマンド(gpcrondumpやgpbackup)も一緒に入っていたはずですが、6.x系からは別途インストールする必要があるようです。
* 各種インストール方法は以下になります。
 * [Pivotal版](https://gpdb.docs.pivotal.io/backup-restore/1-18/backup-restore-install.html "Installation Guide")
 * [OSS版](https://github.com/greenplum-db/gpbackup "gpbackup")
* 今回はOSS版のgpbackup(およびgprestore)をインストールします。goやgitをあらかじめインストールしておく必要がありました。

##インストール(全てマスターでの作業)
READMEの内容に沿って進めます

### epel-releaseのインストール(rootユーザーで実施)

```bash
yum install epel-release -y
```

### Gitのインストール(rootユーザーで実施)

```bash
yum -y install git
```

### GO言語のインストール(rootユーザーで実施)

```bash
yum -y install golang
```
### GitHubからgpbackupのソースを取得(gpadmin)

```bash
su - gpadmin
go get github.com/greenplum-db/gpbackup/...
```

### GO言語のパスを通す(gpadmin)

~/.bash_profileにGOPATHの指定、PATHへの\$GOPATH/binの設定をします。
後続の作業でGitから持ってきたGOのソースをコンパイルするのですが、gpbackupやgprestoreのバイナリファイルが\$GOPATH/bin配下に作成されるので、あらかじめパスを通しておく必要があります。

```bash:/home/gpadmin/.bash_profile
GOPATH=~/go
PATH=$PATH:$HOME/.local/bin:$HOME/bin:${GOPATH}/bin
export PATH
export GOPATH
```

再読み込みします

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

### GOのコンパイル

```bash
cd /home/gpadmin/go/src/github.com/greenplum-db/gpbackup
make depend
make build
```

成功すれば、$GOPATH/binにバイナリが配置されます。(gpbackup,gpbackup_helper,gprestore)

#バックアップ実行

早速、potato DBをバックアップをしてみたいと思います。バックアップは、gpbackupを実行します。コマンドオプションの詳細は[こちら](https://gpdb.docs.pivotal.io/backup-restore/1-18/utility_guide/ref/gpbackup.html "gpbackup")をご参照ください。

```bash
[gpadmin@vmgpmdw ~]$ gpbackup --dbname potato
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Starting backup of database potato
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Backup Timestamp = 20200624215519
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Backup Database = potato
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Gathering table state information
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Acquiring ACCESS SHARE locks on tables
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Gathering additional table metadata
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Getting partition definitions
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Getting storage information
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Getting child partitions with altered schema
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[WARNING]:-No tables in backup set contain data. Performing metadata-only backup instead.
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Metadata will be written to /data1/master/gpseg-1/backups/20200624/20200624215519/gpbackup_20200624215519_metadata.sql
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Writing global database metadata
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Global database metadata backup complete
20200624:21:55:20 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Writing pre-data metadata
20200624:21:55:21 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Pre-data metadata metadata backup complete
20200624:21:55:21 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Writing post-data metadata
20200624:21:55:21 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Post-data metadata backup complete
20200624:21:55:22 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Found neither /usr/local/greenplum-db/./bin/gp_email_contacts.yaml nor /home/gpadmin/gp_email_contacts.yaml
20200624:21:55:22 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Email containing gpbackup report /data1/master/gpseg-1/backups/20200624/20200624215519/gpbackup_20200624215519_report will not be sent
20200624:21:55:22 gpbackup:gpadmin:vmgpmdw.potato.com:001008-[INFO]:-Backup completed successfully
[gpadmin@vmgpmdw ~]$
```
OK、できました。

# リストア

リストアはgprestoreというコマンドを実行します。オプションの詳細は[こちら](https://gpdb.docs.pivotal.io/backup-restore/1-18/utility_guide/ref/gprestore.html "gprestore")をご参照ください。

### リストアをする前に、検証用データを作成したいと思います。

```sql:データ作成
[gpadmin@vmgpmdw ~]$ psql -d potato -h vmgpmdw  -U potatoman
Password for user potatoman:
psql (9.4.24)
Type "help" for help.

potato=> -- 明示的にidを分散キーに指定してテーブル作成
potato=> create table test (id int primary key , val varchar(1000)) distributed by (id);
CREATE TABLE
potato=> -- 100万件のデータを作成(この低スペッククラスタでも3秒程度で完了)
potato=> insert into test SELECT generate_series as id,'テストデータです。１２３４５６７' || generate_series as val FROM generate_series(1,1000000
);
INSERT 0 1000000
potato=> select count(id) from test;
  count
---------
 1000000
(1 row)

potato=>
potato=>\q
```

大量のデータをインサートしたので、統計情報も更新しておきます。greenplumでは、analyzeコマンド(psql)かanalyzedbコマンドで実行します。今回は、analyzedbコマンドを実行します。

```bash
[gpadmin@vmgpmdw ~]$ analyzedb -d potato
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-Starting analyzedb with args: -d potato
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-Getting and verifying input tables...
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-Checking for tables with stale stats...
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:----------------------------------------------------
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-Tables or partitions to be analyzed
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:----------------------------------------------------
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-fat.test
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-pg_catalog.pg_partition_encoding

・・・・・（省略）
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-pg_catalog.pg_default_acl
20200630:11:13:33:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:----------------------------------------------------

Continue with Analyze Yy|Nn (default=N):
> Y
・・・・・（省略）
file /data1/master/gpseg-1/db_analyze/potato/20200630111341/analyze_20200630111341_report
20200630:11:13:41:002026 analyzedb:vmgpmdw:gpadmin-[INFO]:-Done.
```

### 再度バックアップ

```bash
[gpadmin@vmgpmdw ~]$ gpbackup --dbname potato
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Starting backup of database potato
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Backup Timestamp = 20200630111712
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Backup Database = potato
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Gathering table state information
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Acquiring ACCESS SHARE locks on tables
Locks acquired:  1 / 1 [================================================================] 100.00% 0s
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Gathering additional table metadata
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Getting partition definitions
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Getting storage information
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Getting child partitions with altered schema
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Metadata will be written to /data1/master/gpseg-1/backups/20200630/20200630111712/gpbackup_20200630111712_metadata.sql
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Writing global database metadata
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Global database metadata backup complete
20200630:11:17:13 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Writing pre-data metadata
20200630:11:17:14 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Pre-data metadata metadata backup complete
20200630:11:17:14 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Writing post-data metadata
20200630:11:17:14 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Post-data metadata backup complete
20200630:11:17:14 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Writing data to file
Tables backed up:  1 / 1 [==============================================================] 100.00% 0s
20200630:11:17:15 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Data backup complete
20200630:11:17:16 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Found neither /usr/local/greenplum-db/./bin/gp_email_contacts.yaml nor /home/gpadmin/gp_email_contacts.yaml
20200630:11:17:16 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Email containing gpbackup report /data1/master/gpseg-1/backups/20200630/20200630111712/gpbackup_20200630111712_report will not be sent
20200630:11:17:16 gpbackup:gpadmin:vmgpmdw.potato.com:002277-[INFO]:-Backup completed successfully
```

### データ削除

```sql
potato=> -- 誤ってテーブルを消してしまった！
potato=> drop table test;
DROP TABLE
potato=>
potato=> select * from test;
ERROR:  relation "test" does not exist
LINE 1: select * from test;
                      ^
potato=>
```

### リストア実施

以下のように最新のtimestampを確認する。現時点の最新は20200630111712という事を確認。

```bash
# リストアポイントの確認
[gpadmin@vmgpmdw ~]$ gpssh -f list.txt -e "find /data*/*|grep backups"
[vmgpsdw2] find /data*/*|grep backups
・・・(省略)
[vmgpsdw2] /data1/primary/gpseg2/backups/20200630/20200630111712
[vmgpsdw2] /data1/primary/gpseg2/backups/20200630/20200630111712/gpbackup_2_20200630111712_16410.gz
・・・(省略)
```

リストア実行。大体、5秒くらいでした。

```bash
[gpadmin@vmgpmdw ~]$ gprestore --timestamp=20200630111712
20200630:11:22:51 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Restore Key = 20200630111712
20200630:11:22:52 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Restoring pre-data metadata
Pre-data objects restored:  0 / 7 [--------------------------------------------------------]   0.00%20200630:11:22:52 gprestore:gpadmin:vmgpmdw.potato.com:002456-[WARNING]:-Schema fat already exists
Pre-data objects restored:  7 / 7 [=====================================================] 100.00% 0s
20200630:11:22:53 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Pre-data metadata restore complete
Tables restored:  1 / 1 [===============================================================] 100.00% 5s
20200630:11:22:59 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Data restore complete
20200630:11:22:59 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Restoring post-data metadata
Post-data objects restored:  1 / 1 [====================================================] 100.00% 1s
20200630:11:23:00 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Post-data metadata restore complete
20200630:11:23:00 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Found neither /usr/local/greenplum-db/./bin/gp_email_contacts.yaml nor /home/gpadmin/gp_email_contacts.yaml
20200630:11:23:00 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Email containing gprestore report /data1/master/gpseg-1/backups/20200630/20200630111712/gprestore_20200630111712_20200630112251_report will not be sent
20200630:11:23:00 gprestore:gpadmin:vmgpmdw.potato.com:002456-[INFO]:-Restore completed successfully
[gpadmin@vmgpmdw ~]$
```

### リストア後データ確認

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

potato=> select count(id) from test;
  count
---------
 1000000
(1 row)

potato=>
```

OK、リストアできていますね！

# 補足
* Greenplumでは、ポイントインタイムリカバリ(PITR)はサポートしていませんのであらかじめご注意ください。
* 関係ないですが、Greenplumには様々な管理スキーマが用意されています。運用する際に役立つものが多くあると思いますので、気になった方はご確認ください。[(ご参考)](https://gpdb.docs.pivotal.io/6-8/ref_guide/gp_toolkit.html "The gp_toolkit Administrative Schema")

```sql
potato=# --例)テーブルサイズ確認
potato=# select * from gp_toolkit.gp_size_of_table_and_indexes_licensing ;
 sotailoid | sotailtablesizedisk | sotailtablesizeuncompressed | sotailindexessize | sotailschemaname | sotailtablename
-----------+---------------------+-----------------------------+-------------------+------------------+-----------------
     16401 |          2141224960 |                  2141224960 |                 0 | fat              | test
```

# 感想

* gpbackupが別途インストールするのが少し面倒ですが、使いやすいツールだと思います

* 次は、障害対応かMADLibかPostGISか何か別の事をやろうと思います。
* 関係ないですが、最近右目奥に水が溜まってしまい、中心がぼやけてきました。以前にも発症していて何とか治ったんですが、PCやスマホを見すぎるとダメ見たいです。皆様もご注意ください！