はじめに
これまで作成したrepmgr/pgpool postgresqlのバックアップ・リストアをやってみた。
事前に以下の手順でPostgresqlを構築していること。
ここでのバックアップ/リストアはDBの中だけのため、pg_hbaなどの設定は別途手動で設定すること。
バックアップ方式は全停止バックアップ/リストアで対応します。
1. pg_rman 導入
1.1. Ubuntu 24.04(repmgr側)に導入
hivepg1:
sudo apt update
sudo apt install -y \
git make gcc build-essential \
postgresql-server-dev-16 \
zlib1g-dev liblz4-dev libzstd-dev libreadline-dev \
libselinux1-dev libpam0g-dev libkrb5-dev
cd /tmp
git clone https://github.com/ossc-db/pg_rman.git
cd pg_rman
make USE_PGXS=1
sudo make USE_PGXS=1 install
ls -l /usr/lib/postgresql/16/bin/pg_rman
echo 'export PATH=/usr/lib/postgresql/16/bin:$PATH' | sudo tee /etc/profile.d/pgsql16.sh
sudo chmod 644 /etc/profile.d/pgsql16.sh
source /etc/profile.d/pgsql16.sh
pg_rman --version
1.2. AlmaLinux 9(pgpool側)に導入
pg1:
sudo dnf -y install \
git make gcc \
postgresql16-devel \
zlib-devel lz4-devel libzstd-devel readline-devel \
redhat-rpm-config rpm-build \
libselinux-devel pam-devel openssl-devel krb5-devel
cd /tmp
git clone https://github.com/ossc-db/pg_rman.git
cd pg_rman
export PATH=/usr/pgsql-16/bin:$PATH
make USE_PGXS=1
sudo env PATH="$PATH" make USE_PGXS=1 install
ls -l /usr/pgsql-16/bin/pg_rman
echo 'export PATH=/usr/pgsql-16/bin:$PATH' | sudo tee /etc/profile.d/pgsql16.sh
sudo chmod 644 /etc/profile.d/pgsql16.sh
source /etc/profile.d/pgsql16.sh
pg_rman --version
2. repmgr/Ubuntuで停止バックアップ
2.1. Primary確認
hivepg1:
sudo -u postgres psql -Atc "select pg_is_in_recovery();"
sudo -u postgres psql -Atc "show data_directory;"
期待:
f
/var/lib/postgresql/16/main
2.2. 自動切替停止(repmgrd / keepalived)
hivepg1/hivepg2:
sudo systemctl stop repmgrd || true
sudo systemctl stop keepalived || true
2.3. pg_rman フルバックアップ
hivepg1:
sudo mkdir -p /var/backups/pg_rman/backup /var/backups/pg_rman/arclog /var/backups/pg_rman/srvlog
sudo chown -R postgres:postgres /var/backups/pg_rman
sudo chmod 700 /var/backups/pg_rman /var/backups/pg_rman/backup /var/backups/pg_rman/arclog /var/backups/pg_rman/srvlog
sudo -u postgres psql -c "ALTER SYSTEM SET archive_mode = 'on';"
sudo -u postgres psql -c "ALTER SYSTEM SET archive_command = 'test ! -f /var/backups/pg_rman/arclog/%f && cp %p /var/backups/pg_rman/arclog/%f';"
sudo -u postgres psql -c "SELECT pg_reload_conf();"
sudo systemctl restart postgresql
sudo -u postgres bash -lc '
export PGDATA=/var/lib/postgresql/16/main
pg_rman backup -B /var/backups/pg_rman -A /var/backups/pg_rman/arclog -S /var/backups/pg_rman/srvlog --backup-mode=full --compress-data
pg_rman validate -B /var/backups/pg_rman -A /var/backups/pg_rman/arclog -S /var/backups/pg_rman/srvlog
pg_rman show -B /var/backups/pg_rman -A /var/backups/pg_rman/arclog -S /var/backups/pg_rman/srvlog
'
sudo -u postgres psql -c "ALTER SYSTEM RESET archive_command;"
sudo -u postgres psql -c "ALTER SYSTEM SET archive_mode = 'off';"
sudo -u postgres psql -c "SELECT pg_reload_conf();"
sudo systemctl restart postgresql
2.4. 自動切替稼働(repmgrd / keepalived)
hivepg1/hivepg2:
sudo systemctl start repmgrd || true
sudo systemctl start keepalived || true
2.5. repmgr(hivepg1) → pgpool(pg1)へ転送
pg1でのバックアップ受け入れフォルダ作成:
sudo mkdir -p /var/backups/pg_rman
sudo chown -R postgres:postgres /var/backups/pg_rman
sudo chmod 700 /var/backups/pg_rman
hivepg1にある以下のフォルダの内容をpg1へ転送する。
/var/backups/pg_rman
転送後、バックアップファイルはhivepg1から削除すること。
sudo rm -rf /var/backups/pg_rman
3. 新(pgpool/Alma)で restore(pg1を新Primaryに)
3.1. 新pg1/pg2/pg3で pgpool 停止(誤フェイルオーバー防止)
sudo systemctl stop pgpool-II
3.2. pg1リストア
3.2.1. postgresql停止
sudo systemctl stop postgresql-16
3.2.2. PGDATA退避
sudo -u postgres bash -lc '
export PGDATA=/var/lib/pgsql/16/data
mv "$PGDATA" "${PGDATA}.bak.$(date +%F_%H%M%S)" 2>/dev/null || true
mkdir -p "$PGDATA"
chmod 700 "$PGDATA"
'
sudo chown -R postgres:postgres /var/lib/pgsql/16/data
3.2.3. バックアップデータからのリストア
sudo chown -R postgres:postgres /var/backups/pg_rman
sudo find /var/backups/pg_rman -type d -exec chmod 700 {} \;
sudo find /var/backups/pg_rman -type f -exec chmod 600 {} \;
sudo find /var/backups/pg_rman -type f -name '*.sh' -exec chmod 700 {} \;
sudo -u postgres bash -lc '
export PGDATA=/var/lib/pgsql/16/data
pg_rman restore \
-B /var/backups/pg_rman \
-A /var/backups/pg_rman/arclog \
-S /var/backups/pg_rman/srvlog
'
"INFO: restore complete"とでること。
3.2.4. DB設定ファイルコピー
pg2で実施
sudo -u postgres scp -p \
-i /var/lib/pgsql/.ssh/id_rsa_pgpool \
-o IdentitiesOnly=yes \
-o StrictHostKeyChecking=no \
/var/lib/pgsql/16/data/postgresql.conf \
/var/lib/pgsql/16/data/pg_hba.conf \
/var/lib/pgsql/16/data/pg_ident.conf \
postgres@pg1:/var/lib/pgsql/16/data/
こちらについて、3.2.2.で退避したPGDATAから以下のファイルを戻してもよい。
sudo cp /var/lib/pgsql/16/data.back.$(date +%F_%H%M%S)/postgresql.conf /var/lib/pgsql/16/data/
sudo cp /var/lib/pgsql/16/data.back.$(date +%F_%H%M%S)/pg_hba.conf /var/lib/pgsql/16/data/
sudo cp /var/lib/pgsql/16/data.back.$(date +%F_%H%M%S)/pg_ident.conf /var/lib/pgsql/16/data/
3.2.5. DB稼働できる状態への設定
sudo -u postgres bash -lc '
set -e
PGDATA=/var/lib/pgsql/16/data
# 復旧シグナル
touch "$PGDATA/recovery.signal"
chmod 600 "$PGDATA/recovery.signal"
# restore_command を auto.conf に入れる(起動後に戻しやすい)
/usr/pgsql-16/bin/psql -Atc "select 1" >/dev/null 2>&1 || true
# 直接書く(psql不要)
cat >>"$PGDATA/postgresql.auto.conf" <<EOF
# added for pg_rman restore
restore_command = '\''test -f /var/backups/pg_rman/arclog/%f && cp /var/backups/pg_rman/arclog/%f %p'\''
EOF
chown postgres:postgres "$PGDATA/postgresql.auto.conf"
chmod 600 "$PGDATA/postgresql.auto.conf"
'
3.2.6. postgresql稼働
sudo systemctl start postgresql-16
確認:
sudo -u postgres psql -Atc "select pg_is_in_recovery();"
sudo -u postgres psql -Atc "show data_directory;"
以下の返答が出ること。
f
/var/lib/pgsql/16/data
pg1の対応後、バックアップファイルは削除すること。
sudo rm -rf /var/backups/pg_rman/
3.3. pg3 を pg1 の standby として作り直し
- pg3:basebackupで作り直す
sudo systemctl stop postgresql-16 || true
sudo mv /var/lib/pgsql/16/data /var/lib/pgsql/16/data.old.$(date +%F-%H%M%S)
sudo install -d -o postgres -g postgres -m 700 /var/lib/pgsql/16/data
sudo restorecon -RFv /var/lib/pgsql/16/data || true
sudo -u postgres /usr/pgsql-16/bin/pg_basebackup \
-h pg1 -p 5432 -U repl \
-D /var/lib/pgsql/16/data \
-R -X stream -C -S "pg3" \
--write-recovery-conf
sudo systemctl start postgresql-16
sudo -u postgres psql -c "select pg_is_in_recovery();"
期待結果
t(pg3 standby)
3.4. pg2 を pg1 の standby として作り直す
- pg2:basebackupで作り直す
sudo systemctl stop postgresql-16 || true
sudo mv /var/lib/pgsql/16/data /var/lib/pgsql/16/data.old.$(date +%F-%H%M%S)
sudo install -d -o postgres -g postgres -m 700 /var/lib/pgsql/16/data
sudo restorecon -RFv /var/lib/pgsql/16/data || true
sudo -u postgres /usr/pgsql-16/bin/pg_basebackup \
-h pg1 -p 5432 -U repl \
-D /var/lib/pgsql/16/data \
-R -X stream -C -S "pg2" \
--write-recovery-conf
sudo systemctl start postgresql-16
sudo -u postgres psql -c "select pg_is_in_recovery();"
期待結果
t(pg2 standby)
3.5. pg1でレプリケーション確認
pg1
sudo -u postgres psql -c "select client_addr,state,sync_state,application_name from pg_stat_replication;"
期待結果
pg2/pg3 が並ぶ(2行)
3.6. DB再設定
この状態ではpgpoolで使用するDBロールが存在していないため、
再設定を実施する。
pg1で実施
sudo -u postgres psql <<'SQL'
SET password_encryption = 'scram-sha-256';
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='pgpool') THEN
CREATE ROLE pgpool LOGIN;
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='repl') THEN
CREATE ROLE repl REPLICATION LOGIN;
END IF;
END $$;
GRANT pg_monitor TO pgpool;
SQL
sudo -u postgres psql -c "\password pgpool"
sudo -u postgres psql -c "\password repl"
sudo -u postgres psql -c "\password postgres"
→構築時に定めた、パスワードを入れる。
3.7. pgpool を全台起動
pg1/pg2/pg3:
sudo systemctl start pgpool-II
sudo systemctl is-active pgpool-II
3.8. VIP経由で最終確認
ope1:
psql -h 192.168.11.40 -p 9999 -U pgpool -d postgres -c "SHOW pool_nodes;"
期待結果
pg1 primary
pg2 standby
pg3 standby
status/pg_status: up
- statusでどこかdownのものがある場合、以下のコマンドで一括upにすること。
pg1で実施:
pcp_attach_node -h 127.0.0.1 -p 9898 -U pgpool -n 0
pcp_attach_node -h 127.0.0.1 -p 9898 -U pgpool -n 1
pcp_attach_node -h 127.0.0.1 -p 9898 -U pgpool -n 2
pgpoolパスワードを入力する。