Còpies de seguretat de Postgres I

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Fent la còpia de seguretat: pg_dump dbname > outfile

http://www.postgresql.org/docs/8.3/interactive/backup-dump.html

Amb pg_dump generarem un fitxer de text amb les comandes SQL de manera que, un cop importades altre cop al servidor, recrearà la base de dades i la deixarà en el mateix estat que quan vam fer el dump.

pg_dump és una aplicació client del PostgreSQL, i a efectes pràctics, per no tenir problemes de permisos, millor executar-lo com a superusuari:


$ pg_dump -h localhost -p 5432 -U postgres abanq > abanq.dmp

o bé, per tal que no ens demani password (que és el que necessito per poder fer còpies de seguretat):

$ PGUSER=postgres
$ PGPASSWORD=postgres
$ PGHOST=localhost
$ PGPORT=5432
$ export PGUSER PGPASSWORD PGHOST PGPORT
$ pg_dump abanq > abanq.dmp


$ joe abanq.dmp

--
-- PostgreSQL database dump
--

SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off;

SET search_path = public, pg_catalog;

SET default_tablespace = '';

SET default_with_oids = false;
  
--
-- Name: agentes; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
--

CREATE TABLE agentes (
    codpostal character varying(10),
    codagente character varying(10) NOT NULL,
...

com veiem, aquesta exportació s'ha realitzat en mode text pla, amb totes les comandes SQL visibles i comprensibles.

La Comanda pg_dmp té diferents opcions (man pg_dmp), les més destacades són:

  • p: text pla
  • c: custom. És el format més flexible, és un format comprimit, i va bé per utilitzar després el pg_restore en la restauració.
  • t: tar, comprimit

Per exemple, també podem fer:

$ PGUSER=postgres
$ PGPASSWORD=postgres
$ PGHOST=localhost
$ PGPORT=5432
$ export PGUSER PGPASSWORD PGHOST PGPORT
$ pg_dump abanq -f abanq2.dmp -i -x -O

Si vull exportar a un fitxer comprimit, i que després pugui importar mitjançant pg_restore:

$ pg_dump abanq -f abanq3.dmp -i -x -O -Fc

Si ara visualitzo el fitxer abanq3.dmp, veuré que hi ha caràcters comprimits, sobretot en la part de les dades.

Si volem comprimir el fitxer de sortida:

$ pg_dump dbname | gzip > filename.gz (per fer la còpia)
$ gunzip -c filename.gz | psql dbname (per fer la restauració, veure més avall com utilitzem psql)

pg_dumpall

pg_dump només fa la còpia d'una base de dades, i no copia informació de rols i espais de taula. Per fer una còpia total del clúster de base de dades, s'utilitza pg_dumpall:

$ pg_dumpall > outfile (còpia)
$ psql -f infile postgres (restauració)
PGUSER=postgres
PGPASSWORD=postgres
PGHOST=localhost
PGPORT=5432
export PGUSER PGPASSWORD PGHOST PGPORT

Restaurar la còpia de seguretat

Per restaurar hi ha vàries possibilitats: psql, pg_restore (que utilitzarem quan utilitzem el format custom: -Fc)

Restauració amb psql

els fitxers de text creats amb pg_dump es restauren amb psql:

$ psql dbname < infile
$ psql abanq < abanq.dmp

Dóna un missatge de què els objectes ja existeixen. Una possibilitat és dir en el pg_dump que es tornin a crear els objectes (-c). En aquest cas no es pot utilitzar -C per tornar a crear la base de dades.

Una seqüència que funciona sense errors i sense missatges d'error és:

$ pg_dump abanq -f abanq4.dmp  -c
$ psql abanq < abanq4.dmp

Nota: si fem l'exportació amb l'opció -Fc, hem de restaurar amb pg_restore.

Restauració amb pg_restore

$ man pg_restore

És la restauració que farem quan utilitzem l'opció -Fc (o qualsevol format que no sigui text pla), que és un format que comprimeix. És el format que utiltizaré per a fer les meves còpies de seguretat automàtiques.

pg_restore permet ser selectiu amb allò que es restaura.

$ pg_dump -Fc dbname > filename
$ pg_restore -d dbname filename

Per exemple, una seqüència que funciona és:

$ pg_dump -Fc -f abanq6.dmp abanq

$ # eliminem les dues files de la taula provincias
$ psql -h localhost -p 5432 -U postgres abanq
abanq# delete from provincias;
abanq# \q

$ pg_restore -a -d abanq abanq6.dmp

$ psql -h localhost -p 5432 -U postgres abanq
abanq# select from provincias; (comprovem que la informació hi és)
abanq# \q

Per llistar tot allò que conté un fitxer de restauració:

$ pg_restore -l -d abanq abanq6.dmp

Una seqüència que funciona, eliminant la base de dades i tornant-la a crear és:

$ pg_dump -C -Fc -f abanq8.dmp abanq
$ dropdb abanq
http://www.postgresql.org/docs/8.3/interactive/backup-dump.html
$ createdb -T template0 abanq
$ pg_restore -d abanq abanq8.dmp

scripts: automatitzar les còpies de seguretat

pg_dmp_automatic.sh

Aquest script és una simplificació del script pg_dmp.sh, que utilitza la utilitat pg_dump del postgres per fer còpies de seguretat.

Ús: ./pg_dmp_automatic.sh <base_dades>, on <base_dades> és la base de dades de la que vull fer un backup.

#!/bin/bash
##############################  #Script by Joan Q, a partir de pg_dmp.sh  ##############################    
PGUSER=postgres
PGPASSWORD=postgres
PGHOST=localhost
PGPORT=5432

export PGUSER PGPASSWORD PGHOST PGPORT

tdate=`date +%d%m%y`    
     
if ! [ -d $HOME/pg_backup_$1 ] 
then
#if folder pg_backup_'databsename' does not exist in the current users home dierectory then create a new folder
mkdir $HOME/pg_backup_$1
fi

pg_dump $1 -f $HOME/pg_backup_$1/$1_$tdate -i -x -Fc


#reset PGUSER and PGPASSWORD  
PGUSER=""
PGPASSWORD=""
PGHOST=""
PGPORT=""
export PGUSER PGPASSWORD PGHOST PGPORT  
 
#End
fa la còpia de seguretat pròpiament dita.
especifico la base de dades que vull copiar, el fitxer que es crearà (-f), que serà del tipus postgres_101108, ignore-version (-i), no-privileges (-x), format custom (-Fc, custom: Output a custom archive suitable for input into pg_restore. This is the most flexible format in that it allows reordering of loading data as well as object definitions. This format is also compressed by default.)

pg_dmp.sh

#!/bin/bash
##############################  #Script by Anas V  ##############################    
#Substitute your postgresql root username in the below given line  
PGUSER=postgres
#Substitute your postgresql root password in the below given line  
PGPASSWORD=postgres
export PGUSER PGPASSWORD

PGHOST=localhost
PGPORT=5432
export PGHOST PGPORT

tdate=`date +%d-%b-%Y`    

if [ $# -lt 1 ]    
# Check if there is at least one argument [i.e the database whose dump is to be taken]  
#First argument is mandatory - Databse name  
#Second argument is optional - Destination path to save dump  
then            
	echo "Bad Arguments"          
	echo "-----------------------------------"          
	echo "USAGE : pg_dmp.sh <databasename> [outputfile]"          
	echo "-----------------------------------"          
	exit 1  
else    

#if one or more arguments were provided          
	if [ $# -ge 2 ]          
	#if arguments provided is greater than or equal to 2          
	then    
		#Comment out the below given file exist check and it's associated messages    
		# if you want to run the pg_dmpsh script to run silently. i.e from a cron or at job    
		# without any user interaction. Then the output dump file will be rewritten if a file   
		# already exists.                   
		if [ -f $2  ]                  
		# if destination file ie argument 2 is already existing                  
		then                          
			#Show confirmation message to confirm whether replace file with new one or exit
			dialog --title "Confirm File Replace" --backtitle "pg_dmp.sh" --yesno "\nFile already exist, Do you want to replace it with '$2' file" 7 90
			sel=$?
			case $sel in
			#if Yes then take dump and replace the existing file with new dump
			0)  pg_dump $1 -f $2 -i -x -O -R;;
			#if No then exit
			1) exit 1 ;;
			#if escape then exit
			255) exit 1;;
			esac
		else
			#if destination file does not exist then create and save the dump in destination path
			pg_dump $1 -f $2 -i -x -O -R
		fi
	else
		if [ $# -eq 1 ]
		#if arguments provided is equal to 1
		then
			if [ -d $HOME/pg_backup_$1 ]
			#if folder name pg_backup_'databsename' exist in the current users home directory
			then
				if [ -f $HOME/pg_backup_$1/$1_$tdate ]
				#if destination file name exist in pg_backup_'databasename' folder in current users home dierectory
				then
				#Show confirmation message for replacing the file with new dump
					dialog --title "Confirm File Replace" --backtitle "pg_dump.sh"\
					--yesno "\nFile already exist, Do you want to replace it with '$HOME/pg_backup_$1/$1_$tdate' file" 7 90
					sel=$?
					case $sel in
					#if Yes then replace the file with new dump file
					0) pg_dump $1 -f $HOME/pg_backup_$1/$1_$tdate -i -x -O -R;;
					#if No then exit
					1) exit 1 ;;
					#if escape thenexit
					255) exit 1;;
					esac
				else
					#if destination file does not exist then create and save the dump
					pg_dump $1 -f $HOME/pg_backup_$1/$1_$tdate -i -x -O -R
				fi
			else
				#if folder pg_backup_'databsename' does not exist in the current users home dierectory then
				#Create a new folder
				mkdir $HOME/pg_backup_$1
				#then create dump and save it
				pg_dump $1 -f $HOME/pg_backup_$1/$1_$tdate -i -x -O -R
				#if databse to take does not exist then Delete the folder created
				if [ $? -ne 0 ]
				then
					rmdir $HOME/pg_backup_$1
				fi
			fi
		fi
	fi
	if [ $# -gt 2 ]
	#if arguments passed where greater than 2 then  show message
	then
		echo "Extra Arguments ignored"
	fi
fi

#reset PGUSER and PGPASSWORD  
PGUSER=""
PGPASSWORD=""
export PGUSER PGPASSWORD
PGHOST=""
PGPORT=""
export PGHOST PGPORT  
#End

En aquest script, més complet, tenim la possibilitat de ficar un segon argument, que és el nom que donarem a la còpia. En el cas de què existeixi la còpia hi ha la possibilitat de reemplaçar-la o conservar-la. Es fa de forma interactiva mitjançant un dialog.

Si no funciona la comanda dialog, s'ha d'instal.lar el paquet:

$ sudo apt-get install dialog
$ man dialog
$ dialog --msgbox 'hola món!' 0 0

Cron: Còpies periòdiques. Fitxer crontab

el fitxer crontab queda de la següent manera, on la última línia diu que s'executi cada minut el script pg_dmp_automatic.sh, que fa una còpia de la base de dades <postgres>, valor que passo com a paràmetre.

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
*/1 * 	* * *	joan	/home/joan/llegir.sh
*/1 *	* * *	joan	/home/joan/pg_dmp_automatic.sh postgres
#

creat per Joan Quintana Compte, novembre 2008

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
IES Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines