PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Cadangkan PostgreSQL Menggunakan pg_dump dan pg_dumpall

Bisnis dan layanan memberikan nilai berdasarkan data. Ketersediaan, status yang konsisten, dan daya tahan adalah prioritas utama untuk menjaga kepuasan pelanggan dan pengguna akhir. Data yang hilang atau tidak dapat diakses mungkin sama dengan kehilangan pelanggan.

Pencadangan basis data harus menjadi yang terdepan dalam operasi dan tugas sehari-hari.

Kita harus siap jika data kita rusak atau hilang.

Saya sangat percaya pada pepatah lama yang pernah saya dengar:"Lebih baik memilikinya dan tidak membutuhkannya daripada membutuhkannya dan tidak memilikinya . "

Itu berlaku untuk backup database juga. Mari kita hadapi itu, tanpa mereka, pada dasarnya Anda tidak punya apa-apa. Beroperasi dengan anggapan bahwa tidak ada yang bisa terjadi pada data Anda adalah sebuah kekeliruan.

Sebagian besar DBMS menyediakan beberapa sarana utilitas cadangan bawaan. PostgreSQL memiliki pg_dump dan pg_dumpall di luar kotak.

Keduanya menghadirkan banyak opsi penyesuaian dan penataan. Meliputi semuanya satu per satu dalam satu posting blog hampir tidak mungkin. Sebagai gantinya, saya akan melihat contoh-contoh yang paling bisa saya terapkan, pada lingkungan pengembangan/pembelajaran pribadi saya.

Meskipun demikian, posting blog ini tidak ditargetkan pada lingkungan produksi. Kemungkinan besar, satu lingkungan kerja/pengembangan akan paling diuntungkan.

Apa itu pg_dump dan pg_dumpall?

Dokumentasi menjelaskan pg_dump sebagai:“pg_dump adalah utilitas untuk mencadangkan database PostgreSQL”

Dan dokumentasi pg_dumpall:“pg_dumpall adalah utilitas untuk menulis (“dumping”) semua database PostgreSQL dari sebuah cluster ke dalam satu file skrip.”

Mencadangkan Database dan/atau Tabel

Untuk memulai, saya akan membuat database latihan dan beberapa tabel untuk digunakan menggunakan SQL di bawah ini:

postgres=# CREATE DATABASE example_backups;
CREATE DATABASE
example_backups=# CREATE TABLE students(id INTEGER,
example_backups(# f_name VARCHAR(20),
example_backups(# l_name VARCHAR(20));
CREATE TABLE
example_backups=# CREATE TABLE classes(id INTEGER,
example_backups(# subject VARCHAR(20));
CREATE TABLE
example_backups=# INSERT INTO students(id, f_name, l_name)
example_backups-# VALUES (1, 'John', 'Thorn'), (2, 'Phil', 'Hampt'),
example_backups-# (3, 'Sue', 'Dean'), (4, 'Johnny', 'Rames');
INSERT 0 4
example_backups=# INSERT INTO classes(id, subject)
example_backups-# VALUES (1, 'Math'), (2, 'Science'),
example_backups-# (3, 'Biology');
INSERT 0 3
example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)
example_backups=# SELECT * FROM students;
id | f_name | l_name
----+--------+--------
 1 | John   | Thorn
 2 | Phil   | Hampt
 3 | Sue    | Dean
 4 | Johnny | Rames
(4 rows)
example_backups=# SELECT * FROM classes;
id | subject
----+---------
 1 | Math
 2 | Science
 3 | Biology
(3 rows)

Database dan tabel sudah siap.

Untuk diperhatikan:

Dalam banyak contoh ini, saya akan memanfaatkan psql \! meta-command, memungkinkan Anda untuk masuk ke shell (command-line), atau menjalankan perintah shell apa pun yang mengikutinya.

Perlu diketahui bahwa dalam sesi terminal atau baris perintah (dilambangkan dengan '$' di awal posting blog ini), \! meta-command tidak boleh disertakan dalam perintah pg_dump atau pg_dumpall mana pun. Sekali lagi, ini adalah perintah meta praktis dalam psql.

Mencadangkan satu tabel

Dalam contoh pertama ini, saya akan membuang satu-satunya tabel siswa:

example_backups=# \! pg_dump -U postgres -t students example_backups > ~/Example_Dumps/students.sql.

Mencantumkan isi direktori, kami melihat file ada di sana:

example_backups=# \! ls -a ~/Example_Dumps
.  .. students.sql

Opsi baris perintah untuk perintah individual ini adalah:

  • -U postgres:nama pengguna yang ditentukan
  • -t siswa:meja untuk dibuang
  • example_backups:database

Apa yang ada di file student.sql?

$ cat students.sql
--
-- PostgreSQL database dump
--
-- Dumped from database version 10.4 (Ubuntu 10.4-2.pgdg16.04+1)
-- Dumped by pg_dump version 10.4 (Ubuntu 10.4-2.pgdg16.04+1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
 
SET default_tablespace = '';
 
SET default_with_oids = false;
 
--
-- Name: students; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.students (
   id integer,
   f_name character varying(20),
   l_name character varying(20)
);
 
ALTER TABLE public.students OWNER TO postgres;
 
--
-- Data for Name: students; Type: TABLE DATA; Schema: public; Owner: postgres
--
COPY public.students (id, f_name, l_name) FROM stdin;
1 John Thorn
2 Phil Hampt
3 Sue Dean
4 Johnny Rames
\.
--
-- PostgreSQL database dump complete

Kita dapat melihat file tersebut memiliki perintah SQL yang diperlukan untuk membuat ulang dan mengisi ulang tabel siswa.

Tapi, apakah cadangannya bagus? Dapat diandalkan dan berfungsi?

Kami akan mengujinya dan melihat.

example_backups=# DROP TABLE students;
DROP TABLE
example_backups=# \dt;
         List of relations
Schema |  Name | Type  | Owner
--------+---------+-------+----------
public | classes | table | postgres
(1 row)

Sudah hilang.

Kemudian dari baris perintah, masukkan cadangan yang disimpan ke psql:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/students.sql
Password for user postgres:
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
COPY 4

Mari kita verifikasi di database:

example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)
example_backups=# SELECT * FROM students;
id | f_name | l_name
----+--------+--------
 1 | John   | Thorn
 2 | Phil   | Hampt
 3 | Sue    | Dean
 4 | Johnny | Rames
(4 rows)

Tabel dan data telah dipulihkan.

Mencadangkan beberapa tabel

Dalam contoh berikut ini, kita akan mencadangkan kedua tabel menggunakan perintah ini:

example_backups=# \! pg_dump -U postgres -W -t classes -t students -d example_backups > ~/Example_Dumps/all_tables.sql
Password:

(Perhatikan saya perlu menentukan kata sandi dalam perintah ini karena opsi -W, di mana saya tidak melakukannya pada contoh pertama. Lebih lanjut tentang ini akan datang.)

Mari kita verifikasi lagi bahwa file telah dibuat dengan membuat daftar isi direktori:

example_backups=# \! ls -a ~/Example_Dumps
.  .. all_tables.sql  students.sql

Kemudian letakkan tabelnya:

example_backups=# DROP TABLE classes;
DROP TABLE
example_backups=# DROP TABLE students;
DROP TABLE
example_backups=# \dt;
Did not find any relations.

Kemudian pulihkan dengan file cadangan all_tables.sql:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/all_tables.sql
Password for user postgres:
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 3
COPY 4
example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)

Kedua tabel telah dipulihkan.

Seperti yang dapat kita lihat dengan pg_dump, Anda dapat mencadangkan hanya satu, atau beberapa tabel dalam database tertentu.

Mencadangkan database

Sekarang mari kita lihat cara mencadangkan seluruh database example_backups dengan pg_dump.

example_backups=# \! pg_dump -U postgres -W -d example_backups > ~/Example_Dumps/ex_back_db.sql
Password:
 
example_backups=# \! ls -a ~/Example_Dumps
.  .. all_tables.sql  ex_back_db.sql students.sql

File ex_back_db.sql ada di sana.

Saya akan terhubung ke database postgres untuk menghapus database example_backups.

postgres=# DROP DATABASE example_backups;
DROP DATABASE

Kemudian pulihkan dari baris perintah:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/ex_back_db.sql
Password for user postgres:
psql: FATAL:  database "example_backups" does not exist

Itu tidak ada di sana. Kenapa tidak? Dan di mana itu?

Kita harus membuatnya terlebih dahulu.

postgres=# CREATE DATABASE example_backups;
CREATE DATABASE

Kemudian pulihkan dengan perintah yang sama:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/ex_back_db.sql
Password for user postgres:
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
CREATE EXTENSION
COMMENT
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 3
COPY 4
postgres=# \c example_backups;
You are now connected to database "example_backups" as user "postgres".
example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)

Basis data dan semua tabel ada dan diperhitungkan.

Kita dapat menghindari skenario keharusan membuat database target terlebih dahulu, dengan menyertakan opsi -C saat mengambil cadangan.

example_backups=# \! pg_dump -U postgres -W -C -d example_backups > ~/Example_Dumps/ex_back2_db.sql
Password:

Saya akan menyambungkan kembali ke database postgres dan menghapus database example_backups sehingga kita dapat melihat cara kerja pemulihan sekarang (Perhatikan bahwa perintah connect dan DROP tidak ditampilkan untuk singkatnya).

Kemudian pada baris perintah (perhatikan tidak ada opsi -d dbname yang disertakan):

$ psql -U postgres -W -f ~/Example_Dumps/ex_back2_db.sql
Password for user postgres:
……………..
(And partway through the output...)
CREATE DATABASE
ALTER DATABASE
Password for user postgres:
You are now connected to database "example_backups" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
CREATE EXTENSION
COMMENT
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 3
COPY 4

Menggunakan opsi -C, kami dimintai kata sandi untuk membuat koneksi seperti yang disebutkan dalam dokumentasi mengenai flag -C:

“Mulai output dengan perintah untuk membuat database itu sendiri dan sambungkan kembali ke database yang dibuat.”

Kemudian di sesi psql:

postgres=# \c example_backups;
You are now connected to database "example_backups" as user "postgres".

Semuanya dipulihkan, siap digunakan, dan tanpa perlu membuat database target sebelum pemulihan.

pg_dumpall untuk seluruh cluster

Sejauh ini, kami telah mencadangkan satu tabel, beberapa tabel, dan satu database.

Namun jika kita ingin lebih dari itu, misalnya membackup seluruh cluster PostgreSQL, disitulah kita perlu menggunakan pg_dumpall.

Jadi apa perbedaan mencolok antara pg_dump dan pg_dumpall?

Sebagai permulaan, berikut adalah perbedaan penting dari dokumentasi:

“Karena pg_dumpall membaca tabel dari semua database, kemungkinan besar Anda harus terhubung sebagai superuser database untuk menghasilkan dump lengkap. Selain itu, Anda akan memerlukan hak pengguna super untuk menjalankan skrip yang disimpan agar diizinkan untuk menambahkan pengguna dan grup serta untuk membuat basis data.”

Dengan menggunakan perintah di bawah ini, saya akan mencadangkan seluruh cluster PostgreSQL saya dan menyimpannya di file whole_cluster.sql:

$ pg_dumpall -U postgres -W -f ~/Example_Dumps/Cluster_Dumps/entire_cluster.sql
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:

Apa di bumi? Apakah Anda bertanya-tanya apakah saya harus memasukkan kata sandi untuk setiap perintah?

Ya, tentu saja. 24 kali.

Hitung mereka. (Hei, saya suka menjelajahi dan mempelajari database yang berbeda saat saya belajar? Apa yang bisa saya katakan?)

Tapi mengapa semua petunjuknya?

Pertama-tama, setelah semua kerja keras itu, apakah pg_dumpall membuat file cadangan?

postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
.  .. entire_cluster.sql

Ya, file cadangan ada di sana.

Mari kita jelaskan semua 'latihan mengetik itu ' dengan melihat bagian ini dari dokumentasi:

“pg_dumpall perlu terhubung beberapa kali ke server PostgreSQL (sekali per database). Jika Anda menggunakan otentikasi kata sandi, itu akan meminta kata sandi setiap kali.”

Saya tahu apa yang Anda pikirkan.

Ini mungkin tidak ideal atau bahkan layak. Bagaimana dengan proses, skrip, atau tugas cron yang berjalan di tengah malam?

Apakah seseorang akan mengarahkan kursor ke keyboard, menunggu untuk mengetik?

Mungkin tidak.

Salah satu tindakan efektif untuk mencegah menghadapi permintaan sandi berulang tersebut adalah file ~/.pgpass.

Berikut adalah sintaks yang diperlukan file ~/.pgpass untuk berfungsi (contoh disediakan dari dokumentasi lihat tautan di atas):

hostname:port:database:username:password

Dengan file ~/.pgpass yang ada di lingkungan pengembangan saya, yang berisi kredensial yang diperlukan untuk peran postgres, saya dapat menghilangkan opsi -W (juga -w) dan menjalankan pg_dumpall tanpa mengautentikasi secara manual dengan kata sandi:

$ pg_dumpall -U postgres -f ~/Example_Dumps/Cluster_Dumps/entire_cluster2nd.sql

Mencantumkan isi direktori:

postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
.  .. entire_cluster2nd.sql  entire_cluster.sql

File dibuat dan tidak ada permintaan kata sandi yang berulang.

File yang disimpan dapat dimuat ulang dengan psql mirip dengan pg_dump.

Basis data koneksi juga kurang penting menurut bagian ini dari dokumentasi:”Tidak penting ke basis data mana yang Anda sambungkan di sini karena file skrip yang dibuat oleh pg_dumpall akan berisi perintah yang sesuai untuk membuat dan menyambung ke basis data yang disimpan.”

Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh Whitepaper

pg_dump, pg_dumpall, dan skrip shell - Kombinasi Praktis

Di bagian ini, kita akan melihat beberapa contoh penggabungan pg_dump dan pg_dumpall ke dalam skrip shell sederhana.

Yang jelas, ini bukan tutorial skrip shell. Saya juga bukan guru skrip shell. Saya terutama akan memberikan beberapa contoh yang saya gunakan di lingkungan pengembangan/pembelajaran lokal saya.

Pertama, mari kita lihat skrip shell sederhana yang dapat Anda gunakan untuk membuat cadangan satu database:

#!/bin/bash
# This script performs a pg_dump, saving the file the specified dir.
# The first arg ($1) is the database user to connect with.
# The second arg ($2) is the database to backup and is included in the file name.
# $(date +"%Y_%m_%d") includes the current system date into the actual file name.

pg_dump -U $1 -W -C -d $2 > ~/PG_dumps/Dump_Scripts/$(date +"%Y_%m_%d")_$2.sql

Seperti yang Anda lihat, skrip ini menerima 2 argumen:yang pertama adalah pengguna (atau peran) yang akan dihubungkan untuk pencadangan, sedangkan yang kedua adalah nama database yang ingin Anda cadangkan.

Perhatikan opsi -C pada perintah tersebut agar kita dapat melakukan restore jika database kebetulan tidak ada, tanpa perlu membuatnya secara manual terlebih dahulu.

Mari kita panggil skrip dengan peran postgres untuk database example_backups (Jangan lupa untuk membuat skrip dapat dieksekusi dengan setidaknya chmod +x sebelum memanggil untuk pertama kalinya):

$ ~/My_Scripts/pgd.sh postgres example_backups
Password:

Dan verifikasi ada di sana:

$ ls -a ~/PG_dumps/Dump_Scripts/
.  .. 2018_06_06_example_backups.sql

Pemulihan dilakukan dengan skrip cadangan ini seperti pada contoh sebelumnya.

Skrip shell serupa dapat digunakan dengan pg_dumpall untuk mencadangkan seluruh cluster PostgreSQL.

Skrip shell ini akan menyalurkan (|) pg_dumpall ke gzip, yang kemudian diarahkan ke lokasi file yang ditentukan:

#!/bin/bash
# This shell script calls pg_dumpall and pipes into the gzip utility, then directs to
# a directory for storage.
# $(date +"%Y_%m_%d") incorporates the current system date into the file name.
 
pg_dumpall -U postgres | gzip > ~/PG_dumps/Cluster_Dumps/$(date +"%Y_%m_%d")_pg_bck.gz

Tidak seperti skrip contoh sebelumnya, skrip ini tidak menerima argumen apa pun.

Saya akan memanggil skrip ini di baris perintah, (tidak ada permintaan kata sandi karena peran postgres menggunakan file ~/.pgpass - Lihat bagian di atas.)

$ ~/My_Scripts/pgalldmp.sh

Setelah selesai, saya akan membuat daftar isi direktori yang juga menunjukkan ukuran file untuk perbandingan antara file .sql dan gz:

postgres=# \! ls -sh ~/PG_dumps/Cluster_Dumps
total 957M
37M 2018_05_22_pg_bck.gz   32M 2018_06_06_pg_bck.gz 445M entire_cluster2nd.sql  445M entire_cluster.sql

Catatan untuk format arsip gz dari dokumen:

“Format file arsip alternatif harus digunakan dengan pg_restore untuk membangun kembali database.”

Ringkasan

Saya telah mengumpulkan poin-poin penting dari dokumentasi di pg_dump dan pg_dumpall, bersama dengan pengamatan saya, untuk menutup entri blog ini:

Catatan:Poin yang diberikan dari dokumentasi ada dalam tanda kutip.

  • “pg_dump hanya membuang satu database”
  • Format file SQL teks biasa adalah keluaran default untuk pg_dump.
  • Sebuah peran memerlukan hak istimewa SELECT untuk menjalankan pg_dump sesuai dengan baris ini dalam dokumentasi:“pg_dump secara internal mengeksekusi pernyataan SELECT. Jika Anda memiliki masalah dalam menjalankan pg_dump, pastikan Anda dapat memilih informasi dari database menggunakan, misalnya, psql”
  • Untuk menyertakan perintah DDL CREATE DATABASE yang diperlukan dan koneksi dalam file cadangan, sertakan opsi -C.
  • -W:Opsi ini memaksa pg_dump untuk meminta kata sandi. Bendera ini tidak diperlukan karena jika server memerlukan kata sandi, Anda tetap akan diminta. Namun demikian, bagian dalam dokumentasi ini menarik perhatian saya, jadi saya berpikir untuk memasukkannya di sini:“Namun, pg_dump akan menyia-nyiakan upaya koneksi untuk mengetahui bahwa server menginginkan kata sandi. Dalam beberapa kasus, sebaiknya ketik -W untuk menghindari upaya koneksi ekstra.”
  • -d:Menentukan database yang akan disambungkan. Juga dalam dokumentasi:”Ini sama dengan menetapkan dbname sebagai argumen non-opsi pertama di baris perintah.”
  • Menggunakan tanda seperti -t (tabel) memungkinkan pengguna untuk membuat cadangan bagian dari database, yaitu tabel, mereka memiliki hak akses untuk.
  • Format file cadangan dapat bervariasi. Namun, file .sql adalah pilihan yang bagus di antara yang lainnya. File cadangan dibaca kembali oleh psql untuk pemulihan.
  • pg_dump dapat mencadangkan database aktif yang sedang berjalan tanpa mengganggu operasi lain (yaitu, pembaca dan penulis lain).
  • Satu peringatan:pg_dump tidak membuang peran atau objek database lainnya termasuk tablespace, hanya database tunggal.
  • Untuk mengambil cadangan di seluruh cluster PostgreSQL Anda, pg_dumpall adalah pilihan yang lebih baik.
  • pg_dumpall dapat menangani seluruh cluster, mencadangkan informasi tentang peran, tablespace, pengguna, izin, dll... di mana pg_dump tidak bisa.
  • Kemungkinan, peran dengan hak SUPERUSER harus melakukan dump, dan memulihkan/membuat ulang file saat dibaca kembali melalui psql karena selama pemulihan, hak istimewa untuk membaca semua tabel di semua database diperlukan.

Harapan saya adalah melalui posting blog ini, saya telah memberikan contoh dan detail yang memadai untuk ikhtisar tingkat pemula tentang pg_dump dan pg_dumpall untuk satu lingkungan pengembangan/pembelajaran PostgreSQL.

Meskipun semua opsi yang tersedia tidak dieksplorasi, dokumentasi resmi berisi banyak informasi dengan contoh untuk kedua utilitas, jadi pastikan dan konsultasikan sumber daya itu untuk studi, pertanyaan, dan bacaan lebih lanjut.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah ada opsi untuk bergabung ke tabel untuk asosiasi banyak-ke-banyak?

  2. Kesalahan saat mengatur n_distinct menggunakan variabel plpgsql

  3. Pemicu sisipan Postgresql untuk menetapkan nilai

  4. Meneliti kelambatan PostGIS (edisi 2019)

  5. 3 Cara Memeriksa Tipe Data Kolom di PostgreSQL