2012-04-11 3 views
9

Sto cercando uno script/comando di base che creerà una copia di un database attivo (denominiamoli mydb e mydb_test, entrambi sullo stesso server).Come clonare un database di test da uno di produzione in un'unica azione?

Requisiti

  • deve funzionare anche se il mydb_test esiste già e hanno record
  • deve lavorare anche se mydb e mydb_test cosa che ho, le connessioni esistenti
  • si deve pulire il potenziale esistente database se necessario

Suggerimenti:

  • drop database non può essere utilizzato se si dispone di connessioni esistenti

risposta

2

Questo è quello che stavo cercando, ma ho dovuto compilare me: P

solo Vorrei sapere un modo per mantenere lo stesso utente e non dover mettere all'interno dello script.


#!/bin/bash 
DB_SRC=conf 
DB_DST=conf_test 
DB_OWNER=confuser 

T="$(date +%s)" 

psql -c "select pg_terminate_backend(procpid) from pg_stat_activity where datname='$DB_DST';" || { echo "disconnect users failed"; exit 1; } 
psql -c "drop database if exists $DB_DST;" || { echo "drop failed"; exit 1; } 
psql -c "create database $DB_DST owner confuser;" || { echo "create failed"; exit 1; } 
pg_dump $DB_SRC|psql $DB_DST || { echo "dump/restore failed"; exit 1; } 

T="$(($(date +%s)-T))" 
echo "Time in seconds: ${T}" 
2

Dal momento che non è stato detto che era un problema di cadere oggetti nel database, penso che correre pg_dump con l'opzione --clean farà quello che volere. È possibile reindirizzare l'output di pg_dump in psql per questo tipo di cose.

5

Il metodo più semplice e veloce per creare una copia completa di un database esistente (live) è quello di utilizzare CREATE DATABASE with a TEMPLATE:

CREATE DATABASE mydb_test TEMPLATE mydb; 

Tuttavia, v'è un importante limitazione violare il secondo requisito: il database modello (origine) non può avere connessioni aggiuntive ad esso. I quote the manual:

E 'possibile creare database template aggiuntivi, e in effetti uno può copiare qualsiasi database in un cluster specificando il suo nome come il modello per CREATE DATABASE. È importante capire, tuttavia, che questo non è (ancora) inteso come una funzione "COPY DATABASE" per uso generale " ". La principale limitazione è che nessuna altra sessione può essere connessa al database di origine durante la copia. CREATE DATABASE non riuscirà se esiste un'altra connessione all'avvio; durante l'operazione di copia , vengono impedite nuove connessioni al database di origine.

È possibile terminare tutte le sessioni nel database dei modelli se si dispone dei privilegi necessari con pg_terminate_backend().
Per evitare la riconnessione tra sessioni di chiusura e copia dal modello, è possibile revoke the CONNECT privilege (and GRANT back later).

REVOKE CONNECT ON DATABASE mydb FROM PUBLIC; 

-- while connected to another DB (like the default maintenance DB "postgres") 
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE datname = 'mydb'   -- name of prospective template db 
AND pid <> pg_backend_pid(); -- don't kill your own session 

CREATE DATABASE mydb_test TEMPLATE mydb; 

GRANT CONNECT ON DATABASE mydb TO PUBLIC; -- only if they had it before 

Nelle versioni prima di Postgres 9.2 uso procpid invece di pid:


Se non può permettersi di terminare le sessioni simultanee, andare con una pipe l'output di pg_dump a psql come è già stato suggerito da altre risposte.

Problemi correlati