バックアップは、ディザスタリカバリ計画の重要かつ重要な部分です。本番データベースのバックアップを取ることも、PostgreSQL管理の基本的かつ重要な部分です。ただし、DBAは、これらのバックアップが信頼できることを検証しないことがよくあります。
すべての組織が異なる形式でPostgreSQLデータベースのバックアップを取ります。一部の組織はPostgreSQLデータディレクトリのファイルシステム(物理)バックアップを取り(Barman、PGBackRestなどのツールを使用)、他の組織は論理バックアップのみを取ります( pg_dump)、および他のユーザーでさえ、EBSやVMWareスナップショットなどのツールを使用してブロックレベルのスナップショットを作成する場合があります。
このブログでは、バックアップの作成と復元にツールpgBackRestを使用してDockerコンテナにバックアップを復元することにより、PostgreSQLバックアップを検証する方法を紹介します。 PostgreSQL、Docker、pgBackRestの使用方法に関する知識がすでにあることを前提としています。
Dockerを使用する理由
Dockerを使用すると、自動化が簡単になります。また、PostgreSQLバックアップ検証タスクをCircleCI、Travis、GitLab、JenkinsなどのCI/CDツールに統合する作業も簡単になります。 Dockerを使用すると、バックアップをテストするための新しい環境を導入するために費やす必要のある時間とリソースを回避できます。
| | | crontab |
node-1 192.168.0.111 CentOS-7 | Posgresql-11プライマリインスタンス。 ユーザーとデータベース「pgbench」を作成し、pgbenchテーブルで初期化しました。 | postgresql-11、pgbackrest-2.15 | 5分ごとにpgbenchを実行して、ワークロードをシミュレートします。 |
node-2 | テストマシン-このホストでDocker検証を実行します。 | docker-ce-18.06、pgbackrest-2.15 | |
node-3 192.168.0.113 CentOS-7 | pgBackRestリポジトリホスト | pgbackrest-2.15 | pgbackrestを実行して4時間ごとにIncrバックアップを作成 |
pgbackrestを機能させるために、これらのノード間にパスワードなしのSSHアクセスを設定しました。
[[email protected] ~]$ sudo -u postgres ssh [email protected] uptime
13:31:51 up 7:00, 1 user, load average: 0.00, 0.01, 0.05
[[email protected] ~]$ sudo -u postgres ssh [email protected] uptime
13:31:27 up 7:00, 1 user, load average: 0.00, 0.01, 0.05
[[email protected] ~]$ sudo -u pgbackrest ssh [email protected] uptime
13:32:29 up 7:02, 1 user, load average: 1.18, 0.83, 0.58
[[email protected] ~]$ sudo -u pgbackrest ssh [email protected] uptime
13:32:33 up 7:01, 1 user, load average: 0.00, 0.01, 0.05
以下は、PostgreSQLバックアップ検証のために実行する手順の概要です。
- pgbackrest restoreコマンドを使用して、最新のバックアップをpgBackRestリポジトリホスト(ノード3)からテストマシン(ノード2)ディレクトリ/ var / lib / pgsql / 11/dataにフェッチします
- dockerの実行中に、ホストマシン(ノード2)ディレクトリ/ var / lib / pgsqlをdockerコンテナにマウントし、マウントされたディレクトリからpostgres/postmasterデーモンを起動します。また、コンテナからホストマシンのポート15432にポート5432を公開します。
- Dockerコンテナの実行が開始されたら、node-2:15432を介してPostgreSQLデータベースに接続し、すべてのテーブルと行が復元されていることを確認します。また、PostgreSQLログをチェックして、リカバリ中にエラーメッセージがなく、インスタンスも一貫性のある状態になっていることを確認します。
Dockerイメージの構築
ノード2で、Dockerfileを作成し、Dockerイメージ「postgresql:11」をビルドします。以下のDockerfileでは、centos:7ベースイメージに次の変更を適用します。
- postgresql-11、pgbackrest、openssh-clientsをインストールします。 pgbackrestにはOpenssh-clientsが必要です。
- pgbackrestの構成-PITRをテストするには、イメージにpgbackrest構成が必要です。pgbackrest構成がないと、restore_commandは失敗します。 pgbackrest構成の一部として
- 構成ファイル/etc/pgbackrest.confにpgbackrestリポジトリホストIP(192.168.0.113)を追加します。
- Dockerコンテナとpgbackrestリポジトリホスト間のSSHアクセスをパスワードなしで行う必要もあります。このために、すでに生成したSSH_PRIVATE_KEYをコピーし、その公開鍵をpgbackrestリポジトリホスト([email protected])に追加しました。
- VOLUME["${PGHOME_DIR}"]-コンテナディレクトリ/var/ lib/pgsqlをマウントポイントとして定義します。 docker runコマンドの実行中に、このマウントポイントにノード2のホストディレクトリを指定します。
- USER postgres-コンテナで実行されるコマンドは、postgresユーザーとして実行されます。
$ cat Dockerfile
FROM centos:7
ARG PGBACKREST_REPO_HOST
ARG PGHOME_DIR=/var/lib/pgsql
## Adding Postgresql Repo for CentOS7
RUN yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
## Installing PostgreSQL
RUN yum -y install postgresql11 postgresql11-server postgresql11-devel postgresql11-contrib postgresql11-libs pgbackrest openssh-clients
## Adding configuration for pgbackrest, needed for WAL recovery and replication.
RUN echo -ne "[global]\nrepo1-host=${PGBACKREST_REPO_HOST}\n\n[pgbench]\npg1-path=/var/lib/pgsql/11/data\n" > /etc/pgbackrest.conf
## Adding Private Key to the Docker. Docker container would use this private key for pgbackrest wal recovery.
RUN mkdir -p ${PGHOME_DIR}/.ssh && chmod 0750 ${PGHOME_DIR}/.ssh
COPY --chown=postgres:postgres ./SSH_PRIVATE_KEY ${PGHOME_DIR}/.ssh/id_rsa
RUN chmod 0600 ${PGHOME_DIR}/.ssh/id_rsa
RUN echo -ne "Host ${PGBACKREST_REPO_HOST}\n\tStrictHostKeyChecking no\n" >> ${PGHOME_DIR}/.ssh/config
## Making "/var/lib/pgsql" as a mountable directory in the container
VOLUME ["${PGHOME_DIR}"]
## Setting postgres as the default user for any remaining commands
USER postgres
これで、docker buildで使用されるDockerfileと、dockerイメージにコピーされるSSH_PRIVATE_KEYの2つのファイルができました。
$ ls
Dockerfile SSH_PRIVATE_KEY
ノード2で以下のコマンドを実行して、Dockerイメージをビルドします。コマンドでpgbackrestリポジトリホストIPについて説明しましたが、このIPはpgbackrestパラメーター「repo-host」で使用されます。
$ docker build --no-cache -t postgresql:11 --build-arg PGBACKREST_REPO_HOST=192.168.0.113 .
Sending build context to Docker daemon 230.4kB
Step 1/12 : FROM centos:7
---> 9f38484d220f
Step 2/12 : ARG PGBACKREST_REPO_HOST
---> Running in 8b7b36c6f151
Removing intermediate container 8b7b36c6f151
---> 31510e46e286
Step 3/12 : ARG PGHOME_DIR=/var/lib/pgsql
...
Step 4/12 : RUN yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
...
...
Step 12/12 : USER postgres
---> Running in c91abcf46440
Removing intermediate container c91abcf46440
---> bebce78df5ae
Successfully built bebce78df5ae
Successfully tagged postgresql:11
イメージが正常にビルドされたことを確認し、以下に示すように「postgresql:11」イメージが最近作成されたことを確認します。
$ docker image ls postgresql:11
REPOSITORY TAG IMAGE ID CREATED SIZE
postgresql 11 2e03ed2a5946 3 minutes ago 482MB
PostgreSQLバックアップの復元
ここで、pgbackrestバックアップリポジトリホストノード-3に保持されているPostgreSQLバックアップを復元します。
以下は、ホストノード2に存在するpgbackrest構成ファイルであり、ノード3をpgbackrestリポジトリホストとして言及しました。 param pg1-pathに記載されているディレクトリは、PostgreSQLデータディレクトリが復元される場所です。
[[email protected] ~]$ cat /etc/pgbackrest.conf
[global]
log-level-file=detail
repo1-host=node-3
[pgbench]
pg1-path=/var/lib/pgsql/11/data
以下のpgbackrest復元コマンドを使用すると、postgresqlデータディレクトリがノード2:/ var / lib / pgsql / 11/dataに復元されます。
pgbackrestバックアップでPITRを検証するために、-type =time --target ='2019-07-30 06:24:50.241352 + 00'を設定しました。これにより、WALリカバリが停止する前に言及された時間。
[[email protected] ~]$ sudo -u postgres bash -c "/usr/bin/pgbackrest --type=time --target='2019-07-30 06:24:50.241352+00' --target-action=promote --recovery-option='standby_mode=on' --stanza=pgbench restore"
上記のコマンドは、バックアップのサイズとネットワーク帯域幅によっては時間がかかる場合があります。復元したら、データディレクトリのサイズを確認し、recovery.confも確認します。
[[email protected] ~]$ sudo -u postgres du -sh /var/lib/pgsql/11/data
2.1G /var/lib/pgsql/11/data
[[email protected] ~]$ sudo -u postgres cat /var/lib/pgsql/11/data/recovery.conf
standby_mode = 'on'
restore_command = '/usr/bin/pgbackrest --stanza=pgbench archive-get %f "%p"'
recovery_target_time = '2019-07-30 06:24:50.241352+00'
PostgreSQLDockerコンテナのアーカイブモードを無効にします。
[[email protected] ~]$ sudo -u postgres bash -c "echo 'archive_mode = off' >> /var/lib/pgsql/11/data/postgresql.auto.conf"
-
コンテナ名を「pgbench」として設定 -
docker host(node-2)ディレクトリ/ var / lib/psqlをdockerコンテナディレクトリ/var/ lib/psqlにマウントする
-
コンテナポート5432をノード2のポート15432に公開します。 -
コマンド/usr/ pgsql-11 / bin / postmaster -D / var / lib / pgsql / 11 / dataを使用してpostgresデーモンを起動します
[[email protected] ~]$ docker run --rm --name "pgbench" -v /var/lib/pgsql:/var/lib/pgsql -p 15432:5432 -d postgresql:11 /usr/pgsql-11/bin/postmaster -D /var/lib/pgsql/11/data
e54f2f65afa13b6a09236a476cb1de3d8e499310abcec2b121a6b35611dac276
[[email protected] ~]$ docker ps -f name=pgbench
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e54f2f65afa1 postgresql:11 "/usr/pgsql-11/bin/p…" 34 seconds ago Up 33 seconds 0.0.0.0:15432->5432/tcp pgbench
PostgreSQLの検証
[[email protected] ~]$ sudo -u postgres tailf /var/lib/pgsql/11/data/log/postgresql-Tue.csv
..
2019-07-30 06:38:34.633 UTC,,,7,,5d3fe5e9.7,5,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"consistent recovery state reached at E/CE000210",,,,,,,,,""
2019-07-30 06:38:34.633 UTC,,,1,,5d3fe5e9.1,2,,2019-07-30 06:38:33 UTC,,0,LOG,00000,"database system is ready to accept read only connections",,,,,,,,,""
2019-07-30 06:38:35.236 UTC,,,7,,5d3fe5e9.7,6,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"restored log file ""000000010000000E000000CF"" from archive",,,,,,,,,""
2019-07-30 06:38:36.210 UTC,,,7,,5d3fe5e9.7,7,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"restored log file ""000000010000000E000000D0"" from archive",,,,,,,,,""
...
2019-07-30 06:39:57.221 UTC,,,7,,5d3fe5e9.7,37,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"recovery stopping before commit of transaction 52181192, time 2019-07-30 06:25:01.576689+00",,,,,,,,,""
...
2019-07-30 06:40:00.682 UTC,,,7,,5d3fe5e9.7,47,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"archive recovery complete",,,,,,,,,""
ローカルポート15432を介してpostgresqlインスタンスに接続し、テーブルと行数を確認します。
[[email protected] ~]$ sudo -iu postgres /usr/pgsql-11/bin/psql -p 15432 -h localhost -U pgbench
Password for user pgbench:
psql (11.4)
Type "help" for help.
pgbench=> \dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+---------
public | pgbench_accounts | table | pgbench
public | pgbench_branches | table | pgbench
public | pgbench_history | table | pgbench
public | pgbench_tellers | table | pgbench
(4 rows)
pgbench=> select * from pgbench_history limit 1;
tid | bid | aid | delta | mtime | filler
-----+-----+---------+-------+----------------------------+--------
98 | 3 | 2584617 | 507 | 2019-07-30 06:20:01.412226 |
(1 row)
pgbench=> select max(mtime) from pgbench_history ;
max
----------------------------
2019-07-30 06:22:01.402245
(1 row)
pgbench=> select count(1) from pgbench_history ;
count
-------
90677
(1 row)
pgbench=> select count(1) from pgbench_accounts ;
count
----------
10000000
(1 row)
これで、PostgreSQLバックアップをDockerコンテナに復元し、PITRも検証しました。バックアップを検証したら、コンテナを停止してデータディレクトリを削除できます。
[[email protected] ~]$ docker stop pgbench
pgbench
[[email protected] ~]$ sudo -u postgres bash -c "rm -rf /var/lib/pgsql/11/data && mkdir -p /var/lib/pgsql/11/data && chmod 0700 /var/lib/pgsql/11/data"
このブログでは、小さなVirtualBoxVM上の小さなデータベースを使用したバックアップ検証のデモを行いました。このため、バックアップの検証はわずか数分で完了しました。本番環境では、バックアップの検証を正常に完了するために、十分なメモリ、CPU、ディスクを備えた適切なVMを選択する必要があることに注意してください。また、bashスクリプトで、またはCI / CDパイプラインと統合することで、検証プロセス全体を自動化して、PostgreSQLバックアップを定期的に検証することもできます。