sql >> Databáze >  >> RDS >> PostgreSQL

Zálohujte PostgreSQL pomocí pg_dump a pg_dumpall

Podniky a služby přinášejí hodnotu založenou na datech. Dostupnost, konzistentní stav a trvanlivost jsou hlavními prioritami pro udržení spokojenosti zákazníků a koncových uživatelů. Ztracená nebo nedostupná data by se mohla rovnat ztrátě zákazníků.

Zálohování databáze by mělo být v popředí každodenních operací a úkolů.

Měli bychom být připraveni na případ, že se naše data poškodí nebo ztratí.

Pevně ​​věřím ve staré přísloví, které jsem slyšel:„Je lepší to mít a nepotřebovat to, než to potřebovat a nemít to . "

."

To platí i pro zálohování databáze. Přiznejme si, že bez nich nemáte v podstatě nic. Vycházet z představy, že se vašim datům nemůže nic stát, je klam.

Většina DBMS poskytuje některé prostředky vestavěných zálohovacích nástrojů. PostgreSQL má pg_dump a pg_dumpall po vybalení.

Oba nabízejí četné možnosti přizpůsobení a strukturování. Pokrýt je všechny jednotlivě v jednom blogovém příspěvku by bylo téměř nemožné. Místo toho se podívám na ty příklady, které mohu nejlépe aplikovat na své osobní rozvojové/vzdělávací prostředí.

Jak již bylo řečeno, tento blogový příspěvek není zaměřen na produkční prostředí. Nejpravděpodobnější je, že největší přínos by měla mít jediná pracovní stanice/vývojové prostředí.

Co jsou pg_dump a pg_dumpall?

Dokumentace popisuje pg_dump jako:„pg_dump je nástroj pro zálohování databáze PostgreSQL“

A dokumentace pg_dumpall:“pg_dumpall je utilita pro vypisování (“dumping”) všech PostgreSQL databází clusteru do jednoho souboru skriptu.”

Zálohování databáze a/nebo tabulek

Pro začátek vytvořím cvičnou databázi a několik tabulek pro práci s použitím níže uvedeného SQL:

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)

Databáze a tabulky jsou nastaveny.

Poznámka:

V mnoha z těchto příkladů využiji psql \! meta-command, který vám umožní buď vstoupit do shellu (příkazový řádek), nebo spustit jakékoli příkazy shellu, které následují.

Uvědomte si však, že v relaci terminálu nebo příkazového řádku (v tomto příspěvku na blogu označeno počátečním '$') se \! meta-command by neměl být zahrnut v žádném z příkazů pg_dump nebo pg_dumpall. Opět jde o pohodlný meta-příkaz v rámci psql.

Zálohování jedné tabulky

V tomto prvním příkladu vypíšu jedinou tabulku studentů:

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

Když vypíšeme obsah adresáře, vidíme, že soubor tam je:

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

Možnosti příkazového řádku pro tento jednotlivý příkaz jsou:

  • -U postgres:zadané uživatelské jméno
  • -t studenti:tabulka pro výpis
  • example_backups:databáze

Co je v souboru students.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

Vidíme, že soubor má potřebné příkazy SQL k opětovnému vytvoření a opětovnému naplnění tabulky studentů.

Ale je záloha dobrá? Spolehlivý a funkční?

Vyzkoušíme to a uvidíme.

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

Je to pryč.

Poté z příkazového řádku předejte uloženou zálohu do 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

Pojďme ověřit v databázi:

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)

Tabulka a data byly obnoveny.

Zálohování více tabulek

V tomto dalším příkladu provedeme zálohu obou tabulek pomocí tohoto příkazu:

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

(Všimněte si, že jsem v tomto příkazu potřeboval zadat heslo kvůli volbě -W, kde jsem to v prvním příkladu neudělal. Více o tom přijde.)

Znovu ověřte, že byl soubor vytvořen, uvedením obsahu adresáře:

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

Potom tabulky zahoďte:

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

Poté obnovte pomocí záložního souboru 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)

Obě tabulky byly obnoveny.

Jak můžeme vidět u pg_dump, můžete zálohovat pouze jednu nebo více tabulek v rámci konkrétní databáze.

Zálohování databáze

Podívejme se nyní, jak zálohovat celou databázi example_backups pomocí 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

Existuje soubor ex_back_db.sql.

Připojím se k databázi postgres, abych odstranil databázi example_backups.

postgres=# DROP DATABASE example_backups;
DROP DATABASE

Poté obnovte z příkazového řádku:

$ 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

Není to tam. Proč ne? A kde to je?

Nejprve jej musíme vytvořit.

postgres=# CREATE DATABASE example_backups;
CREATE DATABASE

Poté obnovte pomocí stejného příkazu:

$ 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)

Databáze a všechny přítomné a zaúčtované tabulky.

Tomuto scénáři, kdy musíme nejprve vytvořit cílovou databázi, se můžeme vyhnout tím, že při vytváření zálohy zahrneme volbu -C.

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

Znovu se připojím k databázi postgres a zahodím databázi example_backups, abychom viděli, jak nyní obnovení funguje (Všimněte si, že příkazy connect a DROP nejsou pro stručnost zobrazeny).

Potom na příkazovém řádku (všimněte si, že není zahrnuta volba -d název_databáze):

$ 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

Pomocí volby -C jsme vyzváni k zadání hesla pro vytvoření připojení, jak je uvedeno v dokumentaci týkající se parametru -C:

“Začněte výstup příkazem k vytvoření samotné databáze a znovu se připojte k vytvořené databázi.”

Poté v relaci psql:

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

Vše je obnoveno, připraveno a bez nutnosti vytvářet cílovou databázi před obnovením.

pg_dumpall pro celý cluster

Dosud jsme zálohovali jednu tabulku, více tabulek a jednu databázi.

Ale pokud chceme víc než to, například zálohovat celý cluster PostgreSQL, musíme použít pg_dumpall.

Jaké jsou tedy některé významné rozdíly mezi pg_dump a pg_dumpall?

Pro začátek je zde důležitý rozdíl od dokumentace:

„Protože pg_dumpall čte tabulky ze všech databází, budete se s největší pravděpodobností muset připojit jako databázový superuživatel, abyste vytvořili úplný výpis. Také budete potřebovat oprávnění superuživatele ke spuštění uloženého skriptu, abyste mohli přidávat uživatele a skupiny a vytvářet databáze.“

Pomocí níže uvedeného příkazu zazálohuji celý svůj PostgreSQL cluster a uložím jej do souboru 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:

To si děláš srandu? Zajímá vás, zda jsem musel pro každou výzvu zadat heslo?

Jo, určitě ano. 24krát.

Počítejte je. (Hej, rád prozkoumávám různé databáze a ponořím se do nich, když se učím? Co mohu říci?)

Ale proč všechny ty výzvy?

Za prvé, po vší té tvrdé práci vytvořil pg_dumpall záložní soubor?

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

Ano, záložní soubor je tam.

Pojďme si osvětlit všechny ty 'nácvik psaní ’ pohledem na tuto pasáž z dokumentace:

“pg_dumpall se potřebuje několikrát připojit k serveru PostgreSQL (jednou pro každou databázi). Pokud používáte ověřování heslem, bude pokaždé vyžadovat heslo.“

Vím, co si myslíš.

To nemusí být ideální nebo dokonce proveditelné. A co procesy, skripty nebo úlohy cron, které běží uprostřed noci?

Bude někdo přecházet na klávesnici a čekat na psaní?

Pravděpodobně ne.

Jedním z účinných opatření, jak zabránit těmto opakovaným výzvám k zadání hesla, je soubor ~/.pgpass.

Zde je syntaxe, kterou soubor ~/.pgpass vyžaduje, aby fungoval (příklad poskytnutý z dokumentace viz odkaz výše):

hostname:port:database:username:password

Se souborem ~/.pgpass přítomným v mém vývojovém prostředí, který obsahuje potřebná pověření pro postgresovou roli, mohu vynechat volbu -W (také -w) a spustit pg_dumpall bez ručního ověřování pomocí hesla:

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

Výpis obsahu adresáře:

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

Soubor je vytvořen a žádné opakované výzvy k zadání hesla.

Uložený soubor lze znovu načíst pomocí psql podobně jako pg_dump.

Databáze připojení je také méně kritická podle této pasáže z dokumentace:„Není důležité, ke které databázi se zde připojíte, protože soubor skriptu vytvořený pg_dumpall bude obsahovat příslušné příkazy pro vytvoření a připojení k uloženým databázím.“

Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si Whitepaper

skripty pg_dump, pg_dumpall a shell – praktická kombinace

V této sekci uvidíme několik příkladů začlenění pg_dump a pg_dumpall do jednoduchých shellových skriptů.

Je jasné, že se nejedná o tutoriál shellového skriptu. Nejsem ani guru shellových skriptů. Uvedu především několik příkladů, které používám ve svém místním vývojovém/výukovém prostředí.

Nejprve se podívejme na jednoduchý shell skript, který můžete použít k zálohování jedné databáze:

#!/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

Jak můžete vidět, tento skript přijímá 2 argumenty:první je uživatel (nebo role), se kterým se chcete spojit pro zálohování, zatímco druhý je název databáze, kterou chcete zálohovat.

Všimněte si volby -C v příkazu, abychom mohli provést obnovu, pokud databáze náhodou neexistuje, aniž bychom ji museli předem ručně vytvářet.

Zavolejte skript s postgresovou rolí pro databázi example_backups (Nezapomeňte, že skript bude před prvním voláním spustitelný alespoň s chmod +x):

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

A ověřte, že tam je:

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

Obnova se provádí pomocí tohoto zálohovacího skriptu jako v předchozích příkladech.

Podobný shell skript lze použít s pg_dumpall pro zálohování celého clusteru PostgreSQL.

Tento skript shellu převede (|) pg_dumpall do gzip, který je poté přesměrován do určeného umístění souboru:

#!/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

Na rozdíl od předchozího příkladu skriptu tento nepřijímá žádné argumenty.

Tento skript zavolám na příkazovém řádku (žádná výzva k zadání hesla, protože role postgres využívá soubor ~/.pgpass – viz část výše.)

$ ~/My_Scripts/pgalldmp.sh

Po dokončení uvedu seznam obsahu adresáře také s velikostí souborů pro srovnání mezi soubory .sql a 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

Poznámka k archivnímu formátu gz z dokumentů:

“Alternativní formáty archivních souborů musí být použity s pg_restore k opětovnému sestavení databáze.”

Shrnutí

Shromáždil jsem klíčové body z dokumentace na pg_dump a pg_dumpall, spolu s mými pozorováními, abych uzavřel tento blogový příspěvek:

Poznámka:Body uvedené v dokumentaci jsou v uvozovkách.

  • „pg_dump vypíše pouze jednu databázi“
  • Formát souboru SQL ve formátu prostého textu je výchozím výstupem pro pg_dump.
  • Role potřebuje oprávnění SELECT ke spouštění pg_dump podle tohoto řádku v dokumentaci:„pg_dump interně provádí příkazy SELECT. Pokud máte problémy se spuštěním pg_dump, ujistěte se, že jste schopni vybrat informace z databáze například pomocí psql”
  • Chcete-li do záložního souboru zahrnout nezbytný příkaz DDL CREATE DATABASE a připojení, použijte volbu -C.
  • -W:Tato volba přinutí pg_dump požádat o heslo. Tento příznak není nutný, protože pokud server vyžaduje heslo, budete stejně vyzváni. Přesto mě tato pasáž v dokumentaci zaujala, a tak jsem se rozhodl ji sem zahrnout:„Pg_dump však promarní pokus o připojení, aby zjistil, že server chce heslo. V některých případech se vyplatí zadat -W, ​​abyste se vyhnuli dalším pokusům o připojení.“
  • -d:Určuje databázi, ke které se má připojit. Také v dokumentaci:“Toto je ekvivalentní zadání dbname jako prvního argumentu bez možnosti na příkazovém řádku.”
  • Využití parametrů, jako je -t (tabulka), umožňuje uživatelům zálohovat části databáze, konkrétně tabulky, ke kterým mají přístupová práva.
  • Formáty záložních souborů se mohou lišit. Soubory .sql jsou však mimo jiné skvělou volbou. Záložní soubory jsou načteny zpět pomocí psql pro obnovení.
  • pg_dump může zálohovat běžící aktivní databázi, aniž by zasahoval do jiných operací (tj. jiných čteček a zapisovačů).
  • Jedno upozornění:pg_dump nevypisuje role ani jiné databázové objekty včetně tabulkových prostorů, pouze jedinou databázi.
  • Pro zálohování celého clusteru PostgreSQL je lepší volbou pg_dumpall.
  • pg_dumpall zvládne celý cluster, zálohuje informace o rolích, tabulkových prostorech, uživatelích, oprávněních atd., kde pg_dump nemůže.
  • Je pravděpodobné, že role s oprávněními SUPERUSER bude muset provést výpis a obnovit/znovu vytvořit soubor, když je načten zpět prostřednictvím psql, protože během obnovy je vyžadováno oprávnění číst všechny tabulky ve všech databázích.
  • li>

Doufám, že prostřednictvím tohoto příspěvku na blogu jsem poskytl adekvátní příklady a podrobnosti pro přehled úrovně začátečníků na pg_dump a pg_dumpall pro jediné vývojové/výukové prostředí PostgreSQL.

Ačkoli nebyly prozkoumány všechny dostupné možnosti, oficiální dokumentace obsahuje velké množství informací s příklady pro oba nástroje, takže si buďte jisti a konzultujte tento zdroj pro další studium, otázky a čtení.


  1. Funkce MariaDB JSON

  2. Měl by mít každý cizí klíč SQL Server odpovídající index?

  3. Je možné provádět mezidatabázové dotazy s PostgreSQL?

  4. MariaDB JSON_EXISTS() Vysvětleno