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 Whitepaperskripty 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í.