Cadangan adalah bagian vital dan penting dari setiap rencana pemulihan bencana, mengambil cadangan dari basis data produksi juga merupakan bagian dasar dan penting dari administrasi PostgreSQL. Namun, DBA tidak sering memvalidasi bahwa cadangan tersebut dapat diandalkan.
Setiap organisasi mengambil cadangan database PostgreSQL dalam bentuk yang berbeda, beberapa mungkin mengambil cadangan sistem file (fisik) dari direktori data PostgreSQL (menggunakan alat seperti Barman, PGBackRest) sementara yang lain mungkin hanya mengambil cadangan logis (menggunakan pg_dump), dan bahkan orang lain dapat mengambil snapshot tingkat blok menggunakan alat seperti snapshot EBS atau VMWare.
Di blog ini, kami akan menunjukkan cara memvalidasi cadangan PostgreSQL Anda dengan memulihkan cadangan ke wadah Docker menggunakan alat pgBackRest untuk mengambil dan memulihkan cadangan. Kami berasumsi bahwa Anda sudah memiliki pengetahuan tentang cara menggunakan PostgreSQL, Docker, dan pgBackRest.
Mengapa Anda Harus Menggunakan Docker?
Docker membuat otomatisasi lebih sederhana, juga memudahkan pekerjaan mengintegrasikan tugas Validasi Cadangan PostgreSQL kami dalam alat CI/CD seperti CircleCI, Travis, GitLab, atau Jenkins. Menggunakan Docker menghindari waktu dan sumber daya yang harus kita habiskan untuk menghadirkan lingkungan baru untuk menguji cadangan.
Pengaturan Demo
Host | Peran | Terpasang Paket | Crontab |
node-1 192.168.0.111 CentOS-7 | Instans utama Posgresql-11. Membuat pengguna dan database “pgbench“ dan diinisialisasi dengan tabel pgbench. | postgresql-11, pgbackrest-2.15 | Menjalankan pgbench setiap 5 menit untuk mensimulasikan beban kerja. |
simpul-2 | Mesin Uji - kami akan menjalankan validasi Docker kami di host ini. | docker-ce-18.06, pgbackrest-2.15 | |
simpul-3 192.168.0.113 CentOS-7 | pgBackRest Repositori Host | pgbackrest-2.15 | Menjalankan pgbackrest untuk mengambil cadangan Inc setiap 4 jam Berbeda backup setiap hari Pencadangan penuh setiap minggu |
Agar pgbackrest berfungsi, saya telah menyiapkan akses SSH tanpa kata sandi di antara node-node ini.
Pengguna “postgres” pada node-1 dan node-2 dapat login tanpa kata sandi ke pengguna “pgbackrest” pada node-3.
[[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
Pengguna “pgbackrest” pada node-3 dapat login tanpa kata sandi ke pengguna “postgres” pada node-1 dan node-2.
[[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
Ikhtisar Validasi Cadangan
Di bawah ini adalah ikhtisar singkat tentang langkah-langkah yang akan kami ikuti untuk Validasi Cadangan PostgreSQL kami.
- Dengan menggunakan perintah pemulihan pgbackrest, kami akan mengambil cadangan terbaru dari Host Repositori pgBackRest (node-3) ke direktori Mesin Uji (node-2) /var/lib/pgsql/11/data
- Selama menjalankan buruh pelabuhan, kita memasang direktori mesin host (node-2) /var/lib/pgsql pada wadah buruh pelabuhan dan memulai daemon postgres/postmaster dari direktori yang dipasang. Kami juga akan mengekspos port 5432 dari container ke port mesin host 15432.
- Setelah wadah buruh pelabuhan mulai berjalan, kita akan terhubung ke database PostgreSQL melalui node-2:15432 dan memverifikasi bahwa semua tabel dan baris telah dipulihkan. Kami juga akan memeriksa log PostgreSQL untuk memastikan tidak ada pesan ERROR selama pemulihan dan instance juga telah mencapai status yang konsisten.
Sebagian besar langkah validasi pencadangan akan dilakukan pada host node-2.
Membangun Gambar Docker
Pada node-2, buat Dockerfile dan buat gambar buruh pelabuhan “postgresql:11”. Di Dockerfile di bawah ini, kami akan menerapkan perubahan berikut pada centos:7 gambar dasar.
- Menginstal postgresql-11, pgbackrest, dan openssh-clients. Openssh-clients diperlukan untuk pgbackrest.
- Mengonfigurasi pgbackrest - Kita memerlukan konfigurasi pgbackrest pada gambar untuk menguji PITR, tanpa konfigurasi pgbackrest restore_command akan gagal. Sebagai bagian dari konfigurasi pgbackrest
- Kami menambahkan ip host repositori pgbackrest (192.168.0.113) di file konfigurasi /etc/pgbackrest.conf.
- Kami juga membutuhkan akses SSH tanpa kata sandi antara wadah buruh pelabuhan dan host repositori pgbackrest. Untuk ini, saya menyalin SSH_PRIVATE_KEY yang telah saya buat dan saya juga telah menambahkan kunci publiknya ke host repositori pgbackrest ( [email protected] ).
- VOLUME ["${PGHOME_DIR}"] - Mendefinisikan direktori container /var/lib/pgsql sebagai titik pemasangan. Saat menjalankan perintah docker run, kami akan menentukan direktori host node-2 ke titik pemasangan ini.
- USER postgres - Setiap perintah yang dijalankan pada container akan dieksekusi sebagai pengguna 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
Sekarang kita memiliki dua file, Dockerfile yang digunakan oleh docker build dan SSH_PRIVATE_KEY yang akan kita salin ke image docker.
$ ls
Dockerfile SSH_PRIVATE_KEY
Jalankan perintah di bawah ini pada node-2 untuk membangun image buruh pelabuhan kita. Saya telah menyebutkan IP host repositori pgbackrest dalam perintah dan IP ini akan digunakan dalam parameter 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
Pastikan gambar berhasil dibuat, dan centang “postgresql:11” gambar baru saja dibuat seperti yang ditunjukkan di bawah ini.
$ docker image ls postgresql:11
REPOSITORY TAG IMAGE ID CREATED SIZE
postgresql 11 2e03ed2a5946 3 minutes ago 482MB
Memulihkan Cadangan PostgreSQL
Kami sekarang akan memulihkan cadangan PostgreSQL kami yang disimpan di pgbackrest cadangan repositori host node-3.
Di bawah ini adalah file konfigurasi pgbackrest yang ada di host node-2 dan saya telah menyebutkan node-3 sebagai host repositori pgbackrest. Direktori yang disebutkan dalam param pg1-path adalah tempat direktori data PostgreSQL akan dipulihkan.
[[email protected] ~]$ cat /etc/pgbackrest.conf
[global]
log-level-file=detail
repo1-host=node-3
[pgbench]
pg1-path=/var/lib/pgsql/11/data
Menggunakan perintah pemulihan pgbackrest di bawah ini, direktori data postgresql akan dipulihkan di node-2:/var/lib/pgsql/11/data.
Untuk memvalidasi PITR dengan cadangan pgbackrest, saya telah menetapkan --type=time --target='2019-07-30 06:24:50.241352+00', sehingga pemulihan WAL berhenti sebelum waktu yang disebutkan.
[[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"
Perintah di atas mungkin memerlukan waktu tergantung pada ukuran cadangan dan bandwidth jaringan. Setelah dipulihkan, verifikasi ukuran direktori data dan juga periksa 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'
Nonaktifkan mode arsip untuk wadah buruh pelabuhan PostgreSQL.
[[email protected] ~]$ sudo -u postgres bash -c "echo 'archive_mode = off' >> /var/lib/pgsql/11/data/postgresql.auto.conf"
Mulai wadah buruh pelabuhan dengan gambar “postgresql:11”. Dalam perintah kita adalah
-
Menyetel nama wadah sebagai “pgbench”
-
Memasang direktori docker host(node-2) /var/lib/psql ke direktori container docker /var/lib/psql
-
Memperlihatkan port container 5432 ke port 15432 pada node-2.
-
Memulai daemon postgres menggunakan perintah /usr/pgsql-11/bin/postmaster -D /var/lib/pgsql/11/data
[[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
Verifikasi penampung “pgbench” telah dibuat dan dijalankan.
[[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
Memvalidasi PostgreSQL
Karena direktori host /var/lib/pgsql dibagikan dengan wadah buruh pelabuhan, log yang dihasilkan oleh layanan PostgreSQL juga terlihat dari node-2. Verifikasi log hari ini untuk memastikan PostgreSQL telah dimulai dengan baik tanpa ERROR dan pastikan baris log di bawah ini ada.
[[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",,,,,,,,,""
Pesan "kondisi pemulihan yang konsisten tercapai pada E/CE000210", menunjukkan bahwa dengan direktori data cadangan pgbackrest kami dapat mencapai keadaan yang konsisten.
Pesan "pemulihan arsip selesai", menunjukkan bahwa kami dapat memutar ulang file WAL yang dicadangkan oleh pgbackrest dan dapat memulihkan tanpa masalah.
Hubungkan ke instance postgresql melalui port lokal 15432 dan verifikasi tabel dan jumlah baris.
[[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)
Kami sekarang telah memulihkan cadangan PostgreSQL kami di wadah buruh pelabuhan dan juga memverifikasi PITR. Setelah memvalidasi pencadangan, kami dapat menghentikan penampung dan menghapus direktori data.
[[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"
Kesimpulan
Di blog ini, saya mendemonstrasikan validasi cadangan menggunakan database kecil pada VM VirtualBox kecil. Karena itu, validasi pencadangan selesai hanya dalam beberapa menit. Penting untuk dicatat bahwa dalam produksi Anda harus memilih VM yang tepat dengan Memori, CPU, dan Disk yang cukup agar validasi pencadangan berhasil diselesaikan. Anda juga dapat mengotomatiskan seluruh proses validasi dalam skrip bash atau bahkan dengan mengintegrasikan dengan pipa CI/CD sehingga Anda dapat memvalidasi cadangan PostgreSQL kami secara teratur.