Bedrijven en diensten leveren waarde op basis van data. Beschikbaarheid, consistente staat en duurzaamheid zijn topprioriteiten om klanten en eindgebruikers tevreden te houden. Verloren of ontoegankelijke gegevens kunnen mogelijk gelijk staan aan verloren klanten.
Back-ups van databases moeten centraal staan in de dagelijkse operaties en taken.
We moeten voorbereid zijn op het geval dat onze gegevens beschadigd raken of verloren gaan.
Ik geloof heilig in een oud gezegde dat ik heb gehoord:"Het is beter om het te hebben en niet nodig te hebben dan het nodig te hebben en het niet te hebben . "
Dat geldt ook voor databaseback-ups. Laten we eerlijk zijn, zonder hen heb je eigenlijk niets. Werken met het idee dat er niets met uw gegevens kan gebeuren, is een misvatting.
De meeste DBMS'en bieden een of andere manier van ingebouwde back-uphulpprogramma's. PostgreSQL heeft pg_dump en pg_dumpall uit de doos.
Beide bieden tal van maatwerk- en structureringsmogelijkheden. Het zou bijna onmogelijk zijn om ze allemaal afzonderlijk in één blogpost te behandelen. In plaats daarvan zal ik kijken naar de voorbeelden die ik het beste kan toepassen in mijn persoonlijke ontwikkelings-/leeromgeving.
Dat gezegd hebbende, deze blogpost is niet gericht op een productieomgeving. Het is waarschijnlijker dat een enkel werkstation/ontwikkelomgeving het meeste voordeel heeft.
Wat zijn pg_dump en pg_dumpall?
De documentatie beschrijft pg_dump als:"pg_dump is een hulpprogramma voor het maken van back-ups van een PostgreSQL-database"
En de pg_dumpall-documentatie:"pg_dumpall is een hulpprogramma voor het wegschrijven ("dumpen") van alle PostgreSQL-databases van een cluster in één scriptbestand."
Back-up maken van een database en/of tabel(len)
Om te beginnen zal ik een oefendatabase en enkele tabellen maken om mee te werken met behulp van de onderstaande 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)
Database en tabellen zijn allemaal ingesteld.
Let op:
In veel van deze voorbeelden zal ik profiteren van de \! meta-commando, waarmee je ofwel in een shell (opdrachtregel) kunt vallen, of de shell-commando's die daarop volgen kunt uitvoeren.
Houd er rekening mee dat in een terminal- of opdrachtregelsessie (aangeduid met een '$' in deze blogpost), de \! meta-commando mag niet worden opgenomen in een van de pg_dump- of pg_dumpall-commando's. Nogmaals, het is een handige meta-opdracht binnen psql.
Een back-up maken van een enkele tabel
In dit eerste voorbeeld dump ik de enige tabel met studenten:
example_backups=# \! pg_dump -U postgres -t students example_backups > ~/Example_Dumps/students.sql.
Als we de inhoud van de map opsommen, zien we dat het bestand er is:
example_backups=# \! ls -a ~/Example_Dumps
. .. students.sql
De opdrachtregelopties voor deze individuele opdracht zijn:
- -U postgres:de opgegeven gebruikersnaam
- -t studenten:de tafel om te dumpen
- example_backups:de database
Wat staat er in het bestand 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
We kunnen zien dat het bestand de benodigde SQL-commando's heeft om tafelstudenten opnieuw te maken en opnieuw te vullen.
Maar is de back-up goed? Betrouwbaar en werkend?
We zullen het testen en zien.
example_backups=# DROP TABLE students;
DROP TABLE
example_backups=# \dt;
List of relations
Schema | Name | Type | Owner
--------+---------+-------+----------
public | classes | table | postgres
(1 row)
Het is weg.
Geef vervolgens vanaf de opdrachtregel de opgeslagen back-up door aan 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
Laten we verifiëren in de 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 en gegevens zijn hersteld.
Back-up maken van meerdere tabellen
In dit volgende voorbeeld maken we een back-up van beide tabellen met dit commando:
example_backups=# \! pg_dump -U postgres -W -t classes -t students -d example_backups > ~/Example_Dumps/all_tables.sql
Password:
(Merk op dat ik een wachtwoord in deze opdracht moest opgeven vanwege de -W-optie, waar ik dat niet deed in het eerste voorbeeld. Meer hierover volgt.)
Laten we nogmaals controleren of het bestand is gemaakt door de inhoud van de map op te sommen:
example_backups=# \! ls -a ~/Example_Dumps
. .. all_tables.sql students.sql
Laat de tabellen dan vallen:
example_backups=# DROP TABLE classes;
DROP TABLE
example_backups=# DROP TABLE students;
DROP TABLE
example_backups=# \dt;
Did not find any relations.
Herstel vervolgens met het back-upbestand 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)
Beide tabellen zijn hersteld.
Zoals we kunnen zien met pg_dump, kunt u een back-up maken van slechts één of meerdere tabellen binnen een specifieke database.
Back-up maken van een database
Laten we nu kijken hoe we een back-up kunnen maken van de hele example_backups-database met 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
Het ex_back_db.sql-bestand is er.
Ik zal verbinding maken met de postgres-database om de example_backups-database te verwijderen.
postgres=# DROP DATABASE example_backups;
DROP DATABASE
Herstel vervolgens vanaf de opdrachtregel:
$ 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
Het is niet daar. Waarom niet? En waar is het?
We moeten het eerst maken.
postgres=# CREATE DATABASE example_backups;
CREATE DATABASE
Herstel vervolgens met hetzelfde commando:
$ 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)
Database en alle tabellen aanwezig en verantwoord.
We kunnen voorkomen dat we eerst de doeldatabase moeten maken door de optie -C op te nemen bij het maken van de back-up.
example_backups=# \! pg_dump -U postgres -W -C -d example_backups > ~/Example_Dumps/ex_back2_db.sql
Password:
Ik zal opnieuw verbinding maken met de postgres-database en de example_backups-database laten vallen, zodat we kunnen zien hoe het herstel nu werkt (let op die connect- en DROP-commando's die niet worden weergegeven voor de beknoptheid).
Dan op de opdrachtregel (let op geen optie -d dbname inbegrepen):
$ 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
Bij gebruik van de -C optie wordt er om een wachtwoord gevraagd om een verbinding tot stand te brengen zoals vermeld in de documentatie betreffende de -C vlag:
"Begin de uitvoer met een opdracht om de database zelf te maken en maak opnieuw verbinding met de gemaakte database."
Dan in de psql-sessie:
postgres=# \c example_backups;
You are now connected to database "example_backups" as user "postgres".
Alles is hersteld, goed om te gaan, en zonder de noodzaak om de doeldatabase te maken voorafgaand aan het herstel.
pg_dumpall voor het hele cluster
Tot nu toe hebben we een back-up gemaakt van een enkele tabel, meerdere tabellen en een enkele database.
Maar als we meer willen dan dat, bijvoorbeeld een back-up maken van het hele PostgreSQL-cluster, dan moeten we pg_dumpall gebruiken.
Dus wat zijn enkele opmerkelijke verschillen tussen pg_dump en pg_dumpall?
Om te beginnen is hier een belangrijk onderscheid met de documentatie:
“Omdat pg_dumpall tabellen uit alle databases leest, zul je hoogstwaarschijnlijk verbinding moeten maken als database-superuser om een volledige dump te maken. Ook heb je superuser-rechten nodig om het opgeslagen script uit te voeren om gebruikers en groepen toe te voegen en databases aan te maken.”
Met de onderstaande opdracht maak ik een back-up van mijn hele PostgreSQL-cluster en sla het op in het bestand 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:
Wat op aarde? Vraag je je af of ik voor elke prompt een wachtwoord moet invoeren?
Ja, zeker. 24 keer.
Tel ze. (Hé, ik vind het leuk om verschillende databases te verkennen en erin te duiken terwijl ik leer? Wat kan ik zeggen?)
Maar waarom al die prompts?
Ten eerste, heeft pg_dumpall, na al dat harde werk, het back-upbestand gemaakt?
postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
. .. entire_cluster.sql
Ja, het back-upbestand is er.
Laten we wat licht werpen op al die 'typoefeningen ’ door naar deze passage uit de documentatie te kijken:
“pg_dumpall moet meerdere keren verbinding maken met de PostgreSQL-server (eenmaal per database). Als je wachtwoordverificatie gebruikt, wordt er elke keer om een wachtwoord gevraagd.”
Ik weet wat je denkt.
Dit is misschien niet ideaal of zelfs niet haalbaar. Hoe zit het met processen, scripts of cron-jobs die midden in de nacht worden uitgevoerd?
Gaat iemand over het toetsenbord zweven, wachtend om te typen?
Waarschijnlijk niet.
Een effectieve maatregel om te voorkomen dat u met die herhaalde wachtwoordvragen wordt geconfronteerd, is een ~/.pgpass-bestand.
Hier is de syntaxis die het ~/.pgpass-bestand nodig heeft om te werken (voorbeeld uit de documentatie zie link hierboven):
hostname:port:database:username:password
Met een ~/.pgpass-bestand aanwezig in mijn ontwikkelomgeving, met de nodige referenties voor de postgres-rol, kan ik de -W (ook -w) optie weglaten en pg_dumpall uitvoeren zonder handmatig te verifiëren met het wachtwoord:
$ pg_dumpall -U postgres -f ~/Example_Dumps/Cluster_Dumps/entire_cluster2nd.sql
De inhoud van de map weergeven:
postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
. .. entire_cluster2nd.sql entire_cluster.sql
Het bestand wordt aangemaakt en er worden geen herhaalde wachtwoordvragen gesteld.
Het opgeslagen bestand kan opnieuw worden geladen met psql, vergelijkbaar met pg_dump.
De verbindingsdatabase is ook minder kritisch volgens deze passage uit de documentatie:"Het is niet belangrijk met welke database u hier verbinding maakt, aangezien het scriptbestand gemaakt door pg_dumpall de juiste opdrachten zal bevatten om de opgeslagen databases te maken en er verbinding mee te maken."
Download de whitepaper vandaag PostgreSQL-beheer en -automatisering met ClusterControlLees wat u moet weten om PostgreSQL te implementeren, bewaken, beheren en schalenDownload de whitepaperpg_dump, pg_dumpall en shell-scripts - een handige combinatie
In deze sectie zullen we een aantal voorbeelden zien van het opnemen van pg_dump en pg_dumpall in eenvoudige shellscripts.
Wees duidelijk, dit is geen zelfstudie over shellscripts. Ik ben ook geen shellscript-goeroe. Ik zal voornamelijk een paar voorbeelden geven die ik gebruik in mijn lokale ontwikkel-/leeromgeving.
Laten we eerst eens kijken naar een eenvoudig shellscript dat u kunt gebruiken om een back-up van een enkele database te maken:
#!/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
Zoals u kunt zien, accepteert dit script 2 argumenten:de eerste is de gebruiker (of rol) waarmee verbinding moet worden gemaakt voor de back-up, terwijl de tweede de naam is van de database waarvan u een back-up wilt maken.
Let op de -C-optie in de opdracht, zodat we kunnen herstellen als de database niet bestaat, zonder dat we deze vooraf handmatig hoeven te maken.
Laten we het script aanroepen met de rol postgres voor de database example_backups (vergeet niet om het script uitvoerbaar te maken met ten minste chmod +x voordat u voor de eerste keer aanroept):
$ ~/My_Scripts/pgd.sh postgres example_backups
Password:
En controleer of het er is:
$ ls -a ~/PG_dumps/Dump_Scripts/
. .. 2018_06_06_example_backups.sql
Herstel wordt uitgevoerd met dit back-upscript zoals in de vorige voorbeelden.
Een soortgelijk shellscript kan worden gebruikt met pg_dumpall om een back-up te maken van het hele PostgreSQL-cluster.
Dit shellscript stuurt (|) pg_dumpall naar gzip, die vervolgens naar een aangewezen bestandslocatie wordt geleid:
#!/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
In tegenstelling tot het vorige voorbeeldscript, accepteert dit geen argumenten.
Ik noem dit script op de opdrachtregel (geen wachtwoordprompt aangezien de postgres-rol het bestand ~/.pgpass gebruikt - zie het bovenstaande gedeelte.)
$ ~/My_Scripts/pgalldmp.sh
Eenmaal voltooid, zal ik de inhoud van de map weergeven en ook de bestandsgroottes weergeven ter vergelijking tussen de .sql- en gz-bestanden:
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
Een opmerking voor het gz-archiefformaat uit de documenten:
"De alternatieve archiefbestandsindelingen moeten worden gebruikt met pg_restore om de database opnieuw op te bouwen."
Samenvatting
Ik heb de belangrijkste punten uit de documentatie op pg_dump en pg_dumpall verzameld, samen met mijn observaties, om deze blogpost af te sluiten:
Opmerking:Punten uit de documentatie staan tussen aanhalingstekens.
- “pg_dump dumpt slechts één database”
- Het SQL-bestandsformaat met platte tekst is de standaarduitvoer voor pg_dump.
- Een rol heeft het SELECT-recht nodig om pg_dump uit te voeren volgens deze regel in de documentatie:“pg_dump voert intern SELECT-instructies uit. Als je problemen hebt met het uitvoeren van pg_dump, zorg er dan voor dat je informatie uit de database kunt selecteren met bijvoorbeeld psql”
- Om de benodigde DDL CREATE DATABASE-opdracht en een verbinding in het back-upbestand op te nemen, voegt u de optie -C toe.
- -W:Deze optie dwingt pg_dump om om een wachtwoord te vragen. Deze vlag is niet nodig, want als de server een wachtwoord vereist, wordt u hier toch om gevraagd. Desalniettemin trok deze passage in de documentatie mijn aandacht, dus ik dacht om hem hier op te nemen:“Echter, pg_dump verspilt een verbindingspoging om erachter te komen dat de server een wachtwoord wil. In sommige gevallen is het de moeite waard om -W te typen om de extra verbindingspoging te vermijden.”
- -d:Specificeert de database waarmee verbinding moet worden gemaakt. Ook in de documentatie:"Dit komt overeen met het specificeren van dbname als het eerste niet-optie-argument op de opdrachtregel."
- Door vlaggen zoals -t (tabel) te gebruiken, kunnen gebruikers een back-up maken van delen van de database, namelijk tabellen, waarvoor ze toegangsrechten hebben.
- Indelingen voor back-upbestanden kunnen variëren. Onder andere .sql-bestanden zijn echter een goede keuze. Back-upbestanden worden terug ingelezen door psql voor herstel.
- pg_dump kan een back-up maken van een actieve, actieve database zonder andere bewerkingen (d.w.z. andere lezers en schrijvers) te verstoren.
- Eén waarschuwing:pg_dump dumpt geen rollen of andere database-objecten, inclusief tablespaces, alleen een enkele database.
- Als u back-ups wilt maken van uw gehele PostgreSQL-cluster, is pg_dumpall de betere keuze.
- pg_dumpall kan het hele cluster aan en maakt een back-up van informatie over rollen, tablespaces, gebruikers, machtigingen, enz... waar pg_dump dat niet kan.
- De kans is groot dat een rol met SUPERUSER-rechten de dump moet uitvoeren en het bestand moet herstellen/opnieuw moet maken wanneer het opnieuw wordt ingelezen via psql, omdat tijdens het herstellen het recht om alle tabellen in alle databases te lezen vereist is. li>
Mijn hoop is dat ik via deze blogpost voldoende voorbeelden en details heb gegeven voor een overzicht op beginnersniveau op pg_dump en pg_dumpall voor een enkele PostgreSQL-omgeving voor ontwikkeling/leren.
Hoewel niet alle beschikbare opties zijn onderzocht, bevat de officiële documentatie een schat aan informatie met voorbeelden voor beide hulpprogramma's, dus zorg ervoor dat u die bron raadpleegt voor verder onderzoek, vragen en lezen.