Réponses:
Postgres autorise l'utilisation de toute 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 ce qui suit dans une fenêtre de requête si ce n'est pas le cas:
CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;
Pourtant, vous pouvez obtenir:
ERROR: source database "originaldb" is being accessed by other users
Pour déconnecter tous les autres utilisateurs de la base de données, 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();
Servers
-> (mon serveur) -> Databases
, cliquer avec le bouton droit sur Bases de données et sélectionner "Nouvelle base de données". L'une des options est le modèle et le SQL utilisé pour créer la base de données est équivalent. C'est tellement plus rapide qu'une sauvegarde / restauration sur le même serveur.
Une version en ligne de commande de la réponse de Bell :
createdb -O ownername -T originaldb newdb
Cela doit être exécuté sous les privilèges du maître de base de données, généralement postgres.
createdb: database creation failed: ERROR: source database "conf" is being accessed by other users
si vous essayez de le faire sur une base de données de production et comme prévu, vous ne voulez pas l'arrêter pour créer une copie.
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 source en évitant l'erreur
ERROR: source database "SOURCE_DB" is being accessed by other users
procpid
par pid
pour que cela fonctionne
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
pg_dump -s
? postgresql.org/docs/current/static/app-pgdump.html
$ createdb newdb
Je ne connais pas pgAdmin, mais pgdump
vous donne un vidage 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 faire
psql mydatabase < my dump
pour restaurer toutes les tables et leurs données et tous les privilèges d'accès.
pg_dump -U postgres sourcedb | psql -U postgres newdb
si l'efficacité de cette technique peut être mise en doute (car vous finissez probablement par changer de contexte entre les lectures et les écritures)
ssh dbserver pg_dump DBNAME | psql NEWDB
... ou pg_dump DBNAME | ssh otherserver pgsql NEWDB
... Les autorisations et l'authentification doivent bien sûr être gérées comme vous le souhaitez.
Tout d'abord, en sudo
tant qu'utilisateur de la base de données:
sudo su postgres
Accédez à 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 vers la nouvelle:
pg_dump old_database_name | psql new_database_name
\l+
. Pourquoi la différence de taille?
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. J'étais également à la recherche d'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 ( commandes précédées nohup
de déplacer la sortie dans un fichier et de se protéger d'une déconnexion du serveur ):
nohup pg_dump exampledb > example-01.sql
createdb -O postgres exampledbclone_01
mon utilisateur est "postgres"
nohup psql exampledbclone_01 < example-01.sql
Dans pgAdmin, vous pouvez effectuer une sauvegarde à partir de votre base de données d'origine, puis simplement créer une nouvelle base de données et restaurer à partir de la sauvegarde que vous venez de créer:
Quelle est la bonne façon de copier une base de données entière (sa structure et ses données) vers une nouvelle dans pgAdmin?
Réponse:
CREATE DATABASE newdb WITH TEMPLATE originaldb;
Essayé et testé.
D'après la documentation , l'utilisation 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 en spécifiant son nom comme modèle, cela n'est pas (encore) conçu comme une 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 pendant sa copie. CREATE DATABASE échouera si une autre connexion existe au démarrage; sinon, les nouvelles connexions à la base de données de modèles 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 comme pgAdmin, ces commandes sont appelées en arrière-plan lorsque vous exécutez une commande de sauvegarde. La copie vers une nouvelle base de données se fait en deux phases: sauvegarde et restauration
pg_dumpall
enregistre toutes les bases de données du cluster PostgreSQL. L'inconvénient de cette approche est que vous vous retrouvez avec un fichier texte potentiellement très volumineux rempli de SQL requis pour créer la base de données et remplir 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, effectuez cette opération à partir du compte superutilisateur
pg_dumpall > db.out
et pour restaurer
psql -f db.out postgres
pg_dump
a quelques 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 en utilisant
pg_dump --create --format=custom --compress=5 --file=db.dump mydatabase
où 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. Restaurer (ou déplacer 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.
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 dans postgresql.conf et pg_hba.conf (si vous déplacez la base de données vers un autre serveur). Vous devrez déterminer vous-même les paramètres de conf. Mais il y a une astuce que je viens de découvrir pour sauvegarder les rôles. Les rôles sont gérés au niveau du cluster et vous pouvez demander pg_dumpall
de sauvegarder uniquement les rôles avec le --roles-only
commutateur de ligne de commande.
PostgreSQL 9.1.2:
$ CREATEDB new_db_name -T orig_db_name -O db_user;
CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;
, par conséquent, la base de données d'origine doit être inactive (aucune connexion avec accès en écriture) et toute nouvelle connexion à la base de données d'origine est empêchée pendant la copie. Si vous êtes satisfait de cela, cela fonctionne.
Pour ceux qui sont toujours intéressés, j'ai trouvé un script bash qui fait (plus ou moins) ce que l'auteur voulait. J'ai dû faire une copie quotidienne de la base de données d'entreprise sur un système de production, ce script semble faire l'affaire. N'oubliez pas de modifier le nom de la base de données / les valeurs utilisateur / 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"
Pour créer un vidage de base de données
cd /var/lib/pgsql/
pg_dump database_name> database_name.out
Pour resoter le vidage 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
Voici tout le processus de création d'une copie sur une base de données en utilisant uniquement l'interface graphique pgadmin4 (via la sauvegarde et la restauration)
Postgres est livré avec Pgadmin4. Si vous utilisez macOS, vous pouvez appuyer sur CMD
+ SPACE
et taper pgadmin4
pour l'exécuter. Cela ouvrira un onglet de navigateur en chrome.
Pour ce faire, cliquez avec le bouton droit sur la base de données -> "sauvegarde"
Comme test12345
. Cliquez sur sauvegarde. Cela crée un vidage de fichier binaire, ce n'est pas dans un .sql
format
Il devrait y avoir une fenêtre contextuelle en bas à droite de votre écran. Cliquez sur la page "plus de détails" pour voir où votre sauvegarde a été téléchargée
Dans ce cas, c'est /users/vincenttang
En supposant que vous ayez effectué les étapes 1 à 4 correctement, vous aurez un fichier binaire de restauration. Il peut arriver que votre collègue veuille utiliser votre fichier de restauration sur sa machine locale. Demandez à cette personne d'aller sur pgadmin et de restaurer
Pour ce faire, cliquez avec le bouton droit sur la base de données -> "restaurer"
Assurez-vous de sélectionner l'emplacement du fichier manuellement, NE PAS faire glisser et déposer un fichier sur les champs de l'uploader dans pgadmin. Parce que vous rencontrerez des autorisations d'erreur. À la place, recherchez le fichier que vous venez de créer:
Vous devrez peut-être modifier le filtre en bas à droite sur "Tous les fichiers". Recherchez le fichier par la suite, à partir de l'étape 4. Appuyez maintenant sur le bouton "Sélectionner" en bas à droite pour confirmer
Vous verrez à nouveau cette page, avec l'emplacement du fichier sélectionné. Allez-y et restaurez-le
Si tout va bien, le coin inférieur droit devrait afficher un indicateur indiquant une restauration réussie. Vous pouvez naviguer vers vos tables pour voir si les données ont été restaurées propery sur chaque table.
Si l'étape 9 échoue, essayez de supprimer votre ancien schéma public sur votre base de données. Allez dans "Outil de requête"
Exécutez ce bloc de code:
DROP SCHEMA public CASCADE; CREATE SCHEMA public;
Maintenant, essayez à nouveau les étapes 5 à 9, cela devrait fonctionner
EDIT - Quelques notes supplémentaires. Mettez à jour PGADMIN4 si vous obtenez une erreur pendant le téléchargement avec quelque chose du type "version non prise en charge de l'en-tête 1.14 de l'archiveur" pendant la restauration
Si la base de données a des connexions ouvertes, ce script peut vous aider. Je l'utilise pour créer une base de données de test à partir d'une sauvegarde de la base de données de production en direct tous les soirs. Cela suppose que vous disposez d'un fichier de sauvegarde .SQL de la base de données 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"
À 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à en cours d'utilisation.
Si vous voulez copier tout le schéma, 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 vidage, 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”
Déconnectez la base de données "modèle" que vous souhaitez utiliser comme modèle.
Exécutez 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, puis vous pouvez maintenant le sélectionner comme 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;
Essaye ça:
CREATE DATABASE newdb WITH ENCODING='UTF8' OWNER=owner TEMPLATE=templatedb LC_COLLATE='en_US.UTF-8' LC_CTYPE='en_US.UTF-8' CONNECTION LIMIT=-1;
gl XD