Mengopi folder data PostgreSQL dengan cp saat server sedang berjalan menghasilkan salinan yang rusak: halaman data berubah di tengah penyalinan, dan WAL yang dibutuhkan untuk menyatukan perubahan itu mungkin tidak ikut tersalin. PostgreSQL menyediakan satu alat resmi yang mengatasi masalah tersebut: pg_basebackup. Alat ini mengambil salinan menyeluruh satu cluster — semua database, role, dan konfigurasi di dalamnya — dalam keadaan konsisten lewat API backup internal server. Hasilnya disebut base backup, yaitu fondasi tempat pemulihan fisik dan point-in-time recovery dibangun. Chapter ini membedah cara kerja pg_basebackup, pilihan format plain versus tar, tiga strategi penanganan WAL, sampai verifikasi hasil backup memakai backup_manifest — melanjutkan konsep backup fisik dari chapter Physical Backup
.
Base Backup Menyeluruh dari Cluster #
pg_basebackup terhubung ke server lewat protokol replikasi, bukan lewat SQL biasa. Setelah tersambung, server menandai titik mulai backup di WAL, mengirim seluruh isi data directory dalam keadaan konsisten, lalu menandai titik selesai. Dua penanda itu ditulis ke file backup_label di dalam hasil backup, sehingga saat salinan ini dinyalakan ulang, server tahu dari titik WAL mana replay harus dimulai. Karena yang disalin adalah data directory, hasilnya mencakup seluruh cluster: semua database sekaligus, bukan satu database seperti pada pg_dump.
Sejak PostgreSQL 13, setiap base backup juga disertai backup_manifest: daftar seluruh file beserta checksum masing-masing. Manifest inilah yang membuat integritas backup bisa diverifikasi secara independen — dibahas di bagian akhir chapter ini.
Prasyarat di Sisi Server #
Dua parameter menentukan apakah koneksi protokol replikasi akan diterima. Query berikut membacanya dari server latihan:
-- pg_basebackup bekerja lewat protokol replikasi, bukan SQL biasa.
-- Tiga parameter ini menentukan apakah base backup bisa berjalan.
SHOW wal_level;
SHOW max_wal_senders;
SHOW wal_segment_size;Output yang Dihasilkan:
wal_level
-----------
replica
(1 row)
max_wal_senders
-----------------
10
(1 row)
wal_segment_size
------------------
16MB
(1 row)Mari kita bedah tiga nilai itu:
wal_level = replica: level penulisan WAL cukup untuk pengiriman data replikasi — syarat minimumpg_basebackup. Levelminimalakan menolak koneksi backup.max_wal_senders = 10: server mengizinkan maksimal sepuluh proses pengirim WAL secara bersamaan; satu slot dipakai oleh setiappg_basebackupyang berjalan, sisanya dipakai standby streaming.wal_segment_size = 16MB: ukuran satu segmen WAL bawaan — angka ini berperan saat kita memilih strategi penanganan WAL di bagian berikutnya.
Selain parameter, koneksi replikasi juga harus diizinkan pg_hba.conf melalui baris replication. Instalasi bawaan Debian dan PostgreSQL umumnya sudah menyediakannya untuk koneksi lokal — server latihan kita termasuk yang demikian, itulah mengapa contoh-contoh berikut berjalan tanpa penyetelan tambahan.
Format plain: Salinan Data Directory #
Opsi -Fp (format plain) menghasilkan struktur direktori yang persis mencerminkan data directory asli. Skrip berikut mengambil base backup lengkap ke /tmp/pgtutor-bb/plain, memeriksa strukturnya, lalu membersihkan hasilnya:
#!/usr/bin/env bash
# Base backup format plain dengan WAL yang di-stream sekaligus.
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/plain
# Selalu mulai dari direktori kosong: pg_basebackup menolak direktori berisi.
rm -rf "$TUJUAN"
# -Fp : format plain, struktur data directory disalin apa adanya
# -Xs : WAL yang dibutuhkan backup ikut di-stream, backup jadi mandiri
# --checkpoint=fast : checkpoint dijalankan segera supaya backup cepat dimulai
pg_basebackup -D "$TUJUAN" -Fp -Xs --checkpoint=fast --no-password
# Struktur level atas hasil backup harus mencerminkan data directory.
ls -1 "$TUJUAN"
# backup_label menandai backup sah dan mencatat posisi WAL awal.
if [ -f "$TUJUAN/backup_label" ]; then
echo "backup_label: ADA"
fi
# Versi mayor server yang dibackup.
cat "$TUJUAN/PG_VERSION"
# Selesai: hapus artefak lab.
rm -rf "$TUJUAN"Output yang Dihasilkan:
PG_VERSION
backup_label
backup_manifest
base
global
pg_commit_ts
pg_dynshmem
pg_hba.conf
pg_ident.conf
pg_logical
pg_multixact
pg_notify
pg_replslot
pg_serial
pg_snapshots
pg_stat
pg_stat_tmp
pg_subtrans
pg_tblspc
pg_twophase
pg_wal
pg_xact
postgresql.auto.conf
postgresql.conf
backup_label: ADA
17Kita bedah baris-baris penting skrip itu:
- Baris
pg_basebackup -D "$TUJUAN" -Fp -Xs ...:-Dmenentukan direktori tujuan (dibuat otomatis bila belum ada),-Fpmemilih format plain, dan--no-passwordmencegah prompt interaktif agar skrip aman dijalankan otomatis. Koneksi memakai variabel lingkunganPGHOST,PGPORT, danPGUSER— pola yang sama dengan psql. - Baris
ls -1 "$TUJUAN": daftar entri level atas hasil backup. Nama sepertibase,global,pg_wal, danpostgresql.confadalah anatomi data directory yang dikenalkan di chapter Physical Backup — semuanya kini ada di salinan kita, lengkap denganbackup_labeldanbackup_manifest. - Baris
if [ -f "$TUJUAN/backup_label" ]: keberadaanbackup_labeladalah penanda paling cepat bahwa salinan berasal dari backup yang sah, bukan daricpmanual. - Baris
cat "$TUJUAN/PG_VERSION": file ini memuat versi mayor server (17) — angka yang menentukan biner server mana yang boleh menjalankan salinan ini.
Format tar dengan Kompresi #
Format kedua, -Ft, membungkus hasil backup menjadi file arsip tar. Ditambah opsi -z, tiap arsip dikompresi dengan gzip. Skrip berikut membandingkan bentuk hasilnya dengan format plain:
#!/usr/bin/env bash
# Base backup format tar dengan kompresi gzip.
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/tar
rm -rf "$TUJUAN"
# -Ft : format tar, hasil berupa file arsip
# -z : kompresi gzip untuk setiap arsip
# -Xs : WAL dikemas sebagai arsip terpisah pg_wal.tar.gz
pg_basebackup -D "$TUJUAN" -Ft -z -Xs --checkpoint=fast --no-password
# Format tar selalu menghasilkan kombinasi file ini.
ls -1 "$TUJUAN"
# Pastikan ketiga arsip benar-benar berisi (ukuran lebih dari nol).
for berkas in backup_manifest base.tar.gz pg_wal.tar.gz; do
if [ -s "$TUJUAN/$berkas" ]; then
echo "$berkas: ADA"
else
echo "$berkas: HILANG ATAU KOSONG"
exit 1
fi
done
rm -rf "$TUJUAN"Output yang Dihasilkan:
backup_manifest
base.tar.gz
pg_wal.tar.gz
backup_manifest: ADA
base.tar.gz: ADA
pg_wal.tar.gz: ADAFormat tar memisahkan seluruh data directory ke dalam base.tar.gz, sementara WAL hasil -Xs dikemas sendiri sebagai pg_wal.tar.gz. Untuk memakai hasil ini, arsip harus diekstrak dulu (tar -xzf base.tar.gz ke direktori kosong, lalu tar -xzf pg_wal.tar.gz ke pg_wal/ di dalamnya) — satu langkah ekstra dibanding format plain yang langsung jadi data directory siap pakai. Kompresi -z menekan ukuran di disk, tetapi menambah beban CPU saat backup dibuat dan dipulihkan.
Ringkasan dua format dan implikasinya:
| Aspek | -Fp (plain) | -Ft (tar) |
|---|---|---|
| Bentuk hasil | struktur direktori seperti data directory | file arsip base.tar[.gz] |
| Langkah pemulihan | langsung dipakai sebagai PGDATA | ekstrak tar dulu |
| Kompresi | tidak ada (gunakan -Z/--compress saat streaming) | -z gzip, atau -Z dengan tingkat tertentu |
| Cocok untuk | restore cepat, disk cukup besar | arsip jangka panjang, transfer jarak jauh |
Strategi Penanganan WAL: -Xs, -Xf, -Xn #
Satu pertanyaan menentukan mutu base backup: bagaimana WAL yang dibutuhkan backup ikut terkumpul? Opsi -X/--wal-method menyediakan tiga jawaban:
| Metode | Cara kerja | Sifat hasil backup |
|---|---|---|
-Xs (stream) | WAL di-stream paralel sejak awal backup | mandiri — semua WAL yang dibutuhkan ada di dalamnya |
-Xf (fetch) | WAL dikumpulkan di akhir, setelah file data selesai disalin | bergantung WAL masih ada di server |
-Xn (none) | WAL tidak dikumpulkan sama sekali | hanya konsisten bila disatukan dengan arsip WAL terpisah |
Contoh-contoh chapter ini memakai -Xs karena hasilnya self-contained: salinan bisa dinyalakan langsung sebagai instance baru tanpa arsip WAL apa pun — sifat yang akan kita manfaatkan di chapter Menguji Prosedur Recovery
.
Metode -Xn hanya relevan bila Anda menjalankan pengarsipan WAL kontinu (lihat chapter Point-in-Time Recovery
) dan ingin backup sekecil mungkin — WAL akan dipasok dari arsip saat pemulihan, bukan dari dalam backup.
Checkpoint: fast atau spread #
Sesaat sebelum penyalinan dimulai, pg_basebackup memaksa server menjalankan checkpoint — titik di mana semua halaman kotor sudah ditulis ke file data. Dua moda tersedia lewat --checkpoint:
| Moda | Perilaku | Konsekuensi |
|---|---|---|
fast | checkpoint penuh dijalankan segera | beban I/O menumpuk sesaat; backup cepat dimulai dan selesai |
spread | checkpoint disebar selama beberapa saat | beban halus bagi query online; backup baru mulai setelah checkpoint tuntas |
Semua contoh kita memakai fast karena server latihan kecil dan durasi backup singkat. Di server produksi yang sibuk, spread sering dipilih supaya checkpoint dadakan tidak menambah lonjakan latensi bagi pengguna.
Menyiapkan Standby dengan -R #
Opsi -R mengubah base backup menjadi calon standby yang siap menyala: pg_basebackup menulis file standby.signal dan menambahkan primary_conninfo ke postgresql.auto.conf hasil backup. Skrip berikut memperlihatkan kedua artefak itu:
#!/usr/bin/env bash
# Base backup yang sekaligus siap dijadikan standby (-R).
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/standby
rm -rf "$TUJUAN"
# -R menulis standby.signal + primary_conninfo agar backup
# bisa langsung dinyalakan sebagai replika.
PGDATABASE=postgres pg_basebackup -D "$TUJUAN" -Fp -Xs --checkpoint=fast \
-R --no-password
# Artefak pertama: file sinyal standby.
if [ -f "$TUJUAN/standby.signal" ]; then
echo "standby.signal: ADA"
fi
# Artefak kedua: parameter koneksi ke server utama di postgresql.auto.conf.
grep primary_conninfo "$TUJUAN/postgresql.auto.conf"
rm -rf "$TUJUAN"Output yang Dihasilkan:
standby.signal: ADA
primary_conninfo = 'user=postgres passfile=''/home/z/.pgpass'' channel_binding=prefer host=''/home/z/my-project/pgrun'' port=54329 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable dbname=postgres'Baris primary_conninfo pada output berisi parameter koneksi lengkap ke server sumber — user, host (socket Unix server latihan), port, hingga sslmode — diambil dari koneksi yang dipakai pg_basebackup. Setelah backup seperti ini dinyalakan dengan pg_ctl, server baru langsung menjalankan mode standby dan menarik WAL dari server utama. Mekanisme streaming penuhnya dibahas di chapter Streaming Replication
.
Opsi satu keluarga yang bernilai diketahui: --slot=nama_slot memakai replication slot agar server utama menahan WAL sampai backup selesai mengambilnya — menghapus jendela kegagalan -Xf; sementara --create-slot membuat slot itu seperlunya. Detail slot dibahas di chapter Replication Slot
.
Verifikasi Backup dengan Manifest #
Base backup yang tersimpan berbulan-bulan bisa rusak diam-diam oleh sektor disk gagal atau transfer yang terputus. File backup_manifest memungkinkan pemeriksaan menyeluruh tanpa menyentuh server: pg_verifybackup membaca manifest, menghitung ulang checksum setiap file, dan memastikan manifest memuat WAL yang cukup untuk mencapai keadaan konsisten:
#!/usr/bin/env bash
# Verifikasi base backup memakai backup_manifest.
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/verifikasi
rm -rf "$TUJUAN"
pg_basebackup -D "$TUJUAN" -Fp -Xs --checkpoint=fast --no-password
# pg_verifybackup mencocokkan checksum setiap file dengan manifest,
# lalu memastikan manifest memuat WAL yang cukup untuk konsistensi.
pg_verifybackup "$TUJUAN"
rm -rf "$TUJUAN"Output yang Dihasilkan:
backup successfully verifiedSatu baris backup successfully verified berarti setiap byte cocok dengan manifest. Verifikasi seperti ini sebaiknya dijalankan segera setelah backup dibuat dan sekali lagi setelah backup dipindahkan ke lokasi penyimpanan jangka panjang — dua momen ketika kerusakan paling mungkin masuk.
Base backup memberi kita salinan utuh cluster pada satu momen. Pertanyaan berikutnya adalah bagaimana server menjamin setiap perubahan setelah momen itu tidak hilang — dan jawabannya adalah WAL, log tulis-dahulu yang menjadi bahan bakar seluruh pemulihan. Kita bedah mekanismenya di chapter Write-Ahead Logging .
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
backup-plain.sh
Unduh berkas#!/usr/bin/env bash
# Base backup format plain dengan WAL yang di-stream sekaligus.
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/plain
# Selalu mulai dari direktori kosong: pg_basebackup menolak direktori berisi.
rm -rf "$TUJUAN"
# -Fp : format plain, struktur data directory disalin apa adanya
# -Xs : WAL yang dibutuhkan backup ikut di-stream, backup jadi mandiri
# --checkpoint=fast : checkpoint dijalankan segera supaya backup cepat dimulai
pg_basebackup -D "$TUJUAN" -Fp -Xs --checkpoint=fast --no-password
# Struktur level atas hasil backup harus mencerminkan data directory.
ls -1 "$TUJUAN"
# backup_label menandai backup sah dan mencatat posisi WAL awal.
if [ -f "$TUJUAN/backup_label" ]; then
echo "backup_label: ADA"
fi
# Versi mayor server yang dibackup.
cat "$TUJUAN/PG_VERSION"
# Selesai: hapus artefak lab.
rm -rf "$TUJUAN"
backup-standby.sh
Unduh berkas#!/usr/bin/env bash
# Base backup yang sekaligus siap dijadikan standby (-R).
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/standby
rm -rf "$TUJUAN"
# -R menulis standby.signal + primary_conninfo agar backup
# bisa langsung dinyalakan sebagai replika.
PGDATABASE=postgres pg_basebackup -D "$TUJUAN" -Fp -Xs --checkpoint=fast \
-R --no-password
# Artefak pertama: file sinyal standby.
if [ -f "$TUJUAN/standby.signal" ]; then
echo "standby.signal: ADA"
fi
# Artefak kedua: parameter koneksi ke server utama di postgresql.auto.conf.
grep primary_conninfo "$TUJUAN/postgresql.auto.conf"
rm -rf "$TUJUAN"
backup-tar.sh
Unduh berkas#!/usr/bin/env bash
# Base backup format tar dengan kompresi gzip.
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/tar
rm -rf "$TUJUAN"
# -Ft : format tar, hasil berupa file arsip
# -z : kompresi gzip untuk setiap arsip
# -Xs : WAL dikemas sebagai arsip terpisah pg_wal.tar.gz
pg_basebackup -D "$TUJUAN" -Ft -z -Xs --checkpoint=fast --no-password
# Format tar selalu menghasilkan kombinasi file ini.
ls -1 "$TUJUAN"
# Pastikan ketiga arsip benar-benar berisi (ukuran lebih dari nol).
for berkas in backup_manifest base.tar.gz pg_wal.tar.gz; do
if [ -s "$TUJUAN/$berkas" ]; then
echo "$berkas: ADA"
else
echo "$berkas: HILANG ATAU KOSONG"
exit 1
fi
done
rm -rf "$TUJUAN"
prasyarat.sql
Unduh berkas-- pg_basebackup bekerja lewat protokol replikasi, bukan SQL biasa.
-- Tiga parameter ini menentukan apakah base backup bisa berjalan.
SHOW wal_level;
SHOW max_wal_senders;
SHOW wal_segment_size;
verifikasi-manifest.sh
Unduh berkas#!/usr/bin/env bash
# Verifikasi base backup memakai backup_manifest.
set -euo pipefail
TUJUAN=/tmp/pgtutor-bb/verifikasi
rm -rf "$TUJUAN"
pg_basebackup -D "$TUJUAN" -Fp -Xs --checkpoint=fast --no-password
# pg_verifybackup mencocokkan checksum setiap file dengan manifest,
# lalu memastikan manifest memuat WAL yang cukup untuk konsistensi.
pg_verifybackup "$TUJUAN"
rm -rf "$TUJUAN"