web-dev-qa-db-fra.com

Créer une copie d'une base de données dans PostgreSQL

Quelle est la bonne façon de copier la base de données entière (sa structure et ses données) dans une nouvelle base de données dans pgAdmin?

633
egaga

Postgres permet d'utiliser n'importe quelle base de données existante sur le serveur comme modèle lors de la création d'une nouvelle base de données. Je ne sais pas si pgAdmin vous donne l'option dans la boîte de dialogue de création de base de données, mais vous devriez pouvoir exécuter les opérations suivantes dans une fenêtre de requête si ce n'est pas le cas:

CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;

Cependant, vous pouvez obtenir:

ERROR:  source database "originaldb" is being accessed by other users

Pour résoudre ce problème, vous pouvez utiliser cette requête.

SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity 
WHERE pg_stat_activity.datname = 'originaldb' AND pid <> pg_backend_pid();
988
Bell

Une version en ligne de commande de Réponse de Bell :

createdb -O ownername -T originaldb newdb

Cela devrait être exécuté sous les privilèges du maître de la base de données, généralement postgres.

272
zbyszek

Pour cloner une base de données existante avec postgres, vous pouvez le faire. 

/* KILL ALL EXISTING CONNECTION FROM ORIGINAL DB (sourcedb)*/
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity 
WHERE pg_stat_activity.datname = 'SOURCE_DB' AND pid <> pg_backend_pid();

/* CLONE DATABASE TO NEW ONE(TARGET_DB) */
CREATE DATABASE TARGET_DB WITH TEMPLATE SOURCE_DB OWNER USER_DB;

Il va tuer toute la connexion à la base de données en évitant l'erreur

ERROR:  source database "SOURCE_DB" is being accessed by other users
99
Brugolo

Dans l'environnement de production, où la base de données d'origine est sous trafic, j'utilise simplement:

pg_dump production-db | psql test-db
62
Tregoreg

Je ne connais pas pgAdmin, mais pgdump vous donne une image de la base de données en SQL Il vous suffit de créer une base de données du même nom et de 

psql mydatabase < my dump

pour restaurer toutes les tables et leurs données et tous les privilèges d'accès.

47
TrayMan

Tout d’abord, Sudo en tant qu’utilisateur de la base de données:

Sudo su postgres

Aller à la ligne de commande PostgreSQL:

psql

Créez la nouvelle base de données, donnez les droits et quittez:

CREATE DATABASE new_database_name;
GRANT ALL PRIVILEGES ON DATABASE new_database_name TO my_user;
\d

Copiez la structure et les données de l'ancienne base de données sur la nouvelle:

pg_dump old_database_name | psql new_database_name
18
Mathieu Rodic

J'ai reconstitué cette approche avec les exemples ci-dessus. Je travaille sur un serveur "sous charge" et j'ai eu l'erreur lorsque j'ai tenté l'approche de @zbyszek. Je recherchais également une solution "en ligne de commande uniquement". 

createdb: database creation failed: ERROR: source database "exampledb" is being accessed by other users

Voici ce qui a fonctionné pour moi ( Les commandes précédées de Nohup pour déplacer la sortie dans un fichier et se protéger d'un serveur déconnecté ):

  1. Nohup pg_dump exampledb > example-01.sql
  2. createdb -O postgres exampledbclone_01</ p>

    mon utilisateur est "postgres" </ li>

  3. Nohup psql exampledbclone_01 < example-01.sql
  4. </ ol>

15
fusion27

Dans pgAdmin, vous pouvez créer une sauvegarde à partir de votre base de données d'origine, puis simplement créer une nouvelle base de données et la restaurer à partir de la sauvegarde créée:

  1. Cliquez avec le bouton droit sur la base de données source, Sauvegarder ... et sauvegardez dans un fichier.
  2. Faites un clic droit, Nouvel objet, Nouvelle base de données ... et nommez la destination.
  3. Faites un clic droit sur la nouvelle base de données, Restaurer ... et sélectionnez votre fichier.
12
Isomorph

Quelle est la bonne façon de copier la base de données entière (sa structure et ses données) dans une nouvelle base de données dans pgAdmin?

Réponse:

CREATE DATABASE newdb WITH TEMPLATE originaldb;

Essayé et testé.

10
Anirban Chakrabarti

PostgreSQL 9.1.2:

$ CREATEDB new_db_name -T orig_db_name -O db_user;
7
Arta

Pour ceux qui sont toujours intéressés, j'ai créé un script bash qui fait (plus ou moins) ce que l'auteur voulait. Je devais faire une copie quotidienne de la base de données métier sur un système de production, ce script semble faire l'affaire. N'oubliez pas de changer le nom de la base de données/l'utilisateur/les valeurs de pw.

#!/bin/bash

if [ 1 -ne $# ]
then
  echo "Usage `basename $0` {tar.gz database file}"
  exit 65;
fi

if [ -f "$1" ]
then
  EXTRACTED=`tar -xzvf $1`
  echo "using database archive: $EXTRACTED";
else
  echo "file $1 does not exist"
  exit 1
fi


PGUSER=dbuser
PGPASSWORD=dbpw
export PGUSER PGPASSWORD

datestr=`date +%Y%m%d`


dbname="dbcpy_$datestr"
createdbcmd="CREATE DATABASE $dbname WITH OWNER = postgres ENCODING = 'UTF8' TABLESPACE = pg_default LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8' CONNECTION LIMIT = -1;"
dropdbcmp="DROP DATABASE $dbname"

echo "creating database $dbname"
psql -c "$createdbcmd"

rc=$?
if [[ $rc != 0 ]] ; then
  rm -rf "$EXTRACTED"
  echo "error occured while creating database $dbname ($rc)"
  exit $rc
fi


echo "loading data into database"
psql $dbname < $EXTRACTED > /dev/null

rc=$?

rm -rf "$EXTRACTED"

if [[ $rc != 0 ]] ; then
  psql -c "$dropdbcmd"
  echo "error occured while loading data to database $dbname ($rc)"
  exit $rc
fi


echo "finished OK"
4
Dariusz

Pour créer un vidage de base de données

cd /var/lib/pgsql/
pg_dump database_name> database_name.out

Pour resoter la sauvegarde de la base de données 

psql -d template1
CREATE DATABASE database_name WITH  ENCODING 'UTF8' LC_CTYPE 'en_US.UTF-8' LC_COLLATE 'en_US.UTF-   8' TEMPLATE template0;
CREATE USER  role_name WITH PASSWORD 'password';
ALTER DATABASE database_name OWNER TO role_name;
ALTER USER role_name CREATEDB;
GRANT ALL PRIVILEGES ON DATABASE database_name to role_name;


CTR+D(logout from pgsql console)
cd /var/lib/pgsql/

psql -d database_name -f database_name.out
4
Jagdish N

À partir de documentation , l'utilisation de createdb ou CREATE DATABASE avec des modèles n'est pas encouragée:

Bien qu'il soit possible de copier une base de données autre que template1 par en spécifiant son nom en tant que modèle, il ne s’agit pas (encore) de Fonction "COPY DATABASE" à usage général. La principale limitation est qu'aucune autre session ne peut être connectée à la base de données de modèles avec il est copié. CREATE DATABASE échouera si toute autre connexion existe quand il commence; sinon, nouvelles connexions au modèle base de données sont verrouillées jusqu'à la fin de CREATE DATABASE.

pg_dump ou pg_dumpall est un bon moyen de copier la base de données ET TOUTES LES DONNÉES. Si vous utilisez une interface graphique telle que pgAdmin, ces commandes sont appelées en arrière-plan lorsque vous exécutez une commande de sauvegarde. La copie dans une nouvelle base de données se fait en deux phases: Sauvegarde et restauration

pg_dumpall enregistre toutes les bases de données sur le cluster PostgreSQL. L'inconvénient de cette approche est que vous vous retrouvez avec un fichier texte potentiellement très volumineux contenant du code SQL requis pour créer la base de données et renseigner les données. L'avantage de cette approche est que vous obtenez gratuitement tous les rôles (autorisations) du cluster. Pour vider toutes les bases de données, faites-le à partir du compte superutilisateur.

pg_dumpall > db.out

et pour restaurer

psql -f db.out postgres

pg_dump a des options de compression qui vous donnent des fichiers beaucoup plus petits. J'ai une base de données de production que je sauvegarde deux fois par jour avec un travail cron utilisant

pg_dump --create --format=custom --compress=5 ==file=db.dump mydatabase

compress est le niveau de compression (0 à 9) et create indique à pg_dump d'ajouter des commandes pour créer la base de données. Restaurez (ou déplacez vers un nouveau cluster) en utilisant

pg_restore -d newdb db.dump

où newdb est le nom de la base de données que vous souhaitez utiliser.

Autres choses à penser

PostgreSQL utilise ROLES pour gérer les autorisations. Ceux-ci ne sont pas copiés par pg_dump. De plus, nous n'avons pas traité les paramètres de postgresql.conf et pg_hba.conf (si vous déplacez la base de données sur un autre serveur). Vous devrez déterminer vous-même les paramètres de configuration. Mais il y a un truc que je viens de découvrir pour la sauvegarde des rôles. Les rôles sont gérés au niveau du cluster et vous pouvez demander à pg_dumpall de ne sauvegarder que les rôles à l'aide du commutateur de ligne de commande --roles-only

2
bfris

Si la base de données a des connexions ouvertes, ce script peut vous aider. J'utilise ceci pour créer chaque nuit une base de données de test à partir d'une sauvegarde de la base de données de production en direct. Cela suppose que vous ayez un fichier de sauvegarde .SQL de la base de production (je le fais dans Webmin).

#!/bin/sh

dbname="desired_db_name_of_test_enviroment"
username="user_name"
fname="/path to /ExistingBackupFileOfLive.sql"

dropdbcmp="DROP DATABASE $dbname"
createdbcmd="CREATE DATABASE $dbname WITH OWNER = $username "

export PGPASSWORD=MyPassword



echo "**********"
echo "** Dropping $dbname"
psql -d postgres -h localhost -U "$username" -c "$dropdbcmp"

echo "**********"
echo "** Creating database $dbname"
psql -d postgres -h localhost -U "$username" -c "$createdbcmd"

echo "**********"
echo "** Loading data into database"
psql -d postgres -h localhost -U "$username" -d "$dbname" -a -f "$fname"
2
screig

À l’aide de pgAdmin, déconnectez la base de données que vous souhaitez utiliser comme modèle. Ensuite, vous le sélectionnez comme modèle pour créer la nouvelle base de données, cela évite d’obtenir l’erreur déjà utilisée. 

1
evergreener2

Si vous voulez copier le schéma entier, vous pouvez créer un pg_dump avec la commande suivante:

pg_dump -h database.Host.com -d database_name -n schema_name -U database_user --password

Et lorsque vous souhaitez importer ce dump, vous pouvez utiliser:

psql "Host=database.Host.com user=database_user password=database_password dbname=database_name options=--search_path=schema_name" -f sql_dump_to_import.sql

Plus d'informations sur les chaînes de connexion: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING

Ou alors simplement en le combinant dans une doublure:

pg_dump -h database.Host.com -d postgres -n schema_name -U database_user --password | psql "Host=database.Host.com user=database_user password=database_password dbname=database_name options=--search_path=schema_name”
0
Maksim Luzik
  1. Ouvrez la fenêtre principale dans pgAdmin puis ouvrez une autre fenêtre des outils de requête.
  2. Dans les fenêtres principales de pgAdmin,

Déconnectez la base de données "modèle" que vous souhaitez utiliser comme modèle.

  1. Aller à la fenêtre Outils de requête

Exécuter 2 requêtes comme ci-dessous

SELECT pg_terminate_backend(pg_stat_activity.pid) 
    FROM pg_stat_activity 
    WHERE pg_stat_activity.datname = 'TemplateDB' AND pid <> pg_backend_pid(); 

(L'instruction SQL ci-dessus mettra fin à toutes les sessions actives avec TemplateDB. Vous pourrez ensuite la sélectionner en tant que modèle pour créer la nouvelle base de données TargetDB. Cela évite d'obtenir l'erreur déjà utilisée.)

CREATE DATABASE 'TargetDB'
  WITH TEMPLATE='TemplateDB'
       CONNECTION LIMIT=-1;
0
titushui