PostgreSQLでのデータベースのコピーの作成


730

データベース全体(その構造とデータ)をpgAdminの新しいデータベースにコピーする正しい方法は何ですか?

回答:


1121

Postgresでは、新しいデータベースを作成するときに、サーバー上の既存のデータベースをテンプレートとして使用できます。pgAdminがデータベース作成ダイアログのオプションを提供するかどうかはわかりませんが、そうでない場合はクエリウィンドウで以下を実行できるはずです。

CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;

それでも、あなたは得るかもしれません:

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

他のすべてのユーザーをデータベースから切断するには、次のクエリを使用できます。

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

68
これが機能するには、originaldbがアイドル状態(書き込みトランザクションなし)である必要があることに注意してください。
synecdoche

62
pgAdmin3のオブジェクトブラウザー(左側)ペインで、[ Servers-> (サーバー) -> Databasesを選択し、[データベース]を右クリックして[新しいデータベース]を選択します。オプションの1つはテンプレートで、データベースの作成に使用されるSQLは同等です。それはあるので、はるかに高速/同じサーバー上に復元するダンプより。
jwhitlock 2011年

22
これは古いQ / Aであることはわかっていますが、説明が必要だと思います。@ synecdocheがoriginaldbをアイドル状態にする必要があると言った場合、書き込みの可能性はまったくありません。この方法でデータベースを「コピー」しても、originaldbはロックされません。PostgreSQLは、コピーの開始後ではなく、originaldbにアクセスしている他のユーザーがいる場合にのみコピーの開始を防止するため、「コピー」の実行中に別の接続がデータベースを変更する可能性があります。私見、これが最も簡単な答えかもしれませんが、「最善」はダンプ/復元を使用することです。
Josh、

10
私はこれを見た。@Josh:originaldbがテンプレート付きのcreate databaseによってコピーされている間、postgresqlはそれに新しい接続を作成することを許可しないため、変更はできません。
ceteras 2012年

4
pgAdminを使用していて、SQLコマンドウィンドウからCREATE DATABASE ... TEMPLATE xxxを実行している場合、メインのpgAdminウィンドウでデータベースから切断する必要があります。そうしないと、データベースに接続しているユーザーに関するエラーが発生します。
Jack RG

296

Bellの回答のコマンドラインバージョン:

createdb -O ownername -T originaldb newdb

これは、データベースマスター(通常はpostgres)の権限で実行する必要があります。


5
これは便利なコマンドですがcreatedb: database creation failed: ERROR: source database "conf" is being accessed by other users、本番データベースで実行しようとしても、期待どおりにシャットダウンしてコピーを作成したくない場合に表示されます。
ソリン2012

7
はい、明示的なCREATE DATABASEの呼び出しと同じ警告がこのコマンドに適用されます。上記のベルの回答に対するコメントのように、データベースはアイドル状態でなければなりません。
zbyszek

108

postgresで既存のデータベースのクローンを作成するには、それを行うことができます

/* 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;

ITはソースデータベースへのすべての接続を強制終了し、エラーを回避します

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

7
アクセスエラーを回避するためのスクリプトソリューションについて言及した場合の+1
いじめ14

14
Postgresの9.2に私は交換する必要がprocpidpid仕事に、このために
marxjohnson

75

元のデータベースが混雑している本番環境では、私は単に以下を使用しています:

pg_dump production-db | psql test-db

8
この方法で私が見つけた1つの問題は、pg_dumpが実際にダンプを終了した場合でも、新しいデータベースへの復元が完了するまで、pg_dumpがトランザクションを開いたままにすることです。これにより、場合によってはロックの問題が発生する可能性があります(たとえば、ソースDBでDDLステートメントが実行される場合)。
Chris Butler

3
一時的な中間ファイルを使用しないための1つ。
Ardee Aram、2015

それも私の解決策でした。昨日はうまくいきましたが、今ではランダムな一意の制約に違反しています。注:すべてのテーブルをレシーバーdbにドロップします。
gunzapper


1
これはtest-dbが存在することを前提としています。それ以外の場合は、$ createdb newdb
次のコマンドで

50

pgAdminについては知りませんがpgdump、SQLでデータベースのダンプを提供します。同じ名前でデータベースを作成して実行するだけです

psql mydatabase < my dump

すべてのテーブルとそのデータ、およびすべてのアクセス権限を復元します。


おかげで、私は別のサーバからのダンプを作成するために必要な、このことができますようだ:postgresql.org/docs/8.3/interactive/...
egaga

19
pg_dump -U postgres sourcedb | psql -U postgres newdbこのテクニックの効率には疑問があるかもしれませんが、実行することもできます(おそらく、読み取りと書き込みの間でコンテキストが切り替わるので)
Frank Farmer

1
あなたも、ssh経由でリモートマシンからあなたのダンプを取得することができます:ssh dbserver pg_dump DBNAME | psql NEWDB...かpg_dump DBNAME | ssh otherserver pgsql NEWDB ...しかし、あなたがそれらを処理する処理されるパーミッションと当然の認証が必要。
ghoti 2012

23

まず、sudoデータベースユーザーとして:

sudo su postgres

PostgreSQLコマンドラインに移動します。

psql

新しいデータベースを作成し、権限を付与して終了します。

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

古いデータベースから新しいデータベースに構造とデータをコピーします。

pg_dump old_database_name | psql new_database_name

いくつかのエラー(ネットワークの問題)が発生しても、問題がないことを確認する方法 移行後に2つのデータベースが同じかどうかを確認するにはどうすればよいですか?
BAE

エラーは、発生するたびにターミナルに表示されます。操作後、2つのデータベースは同じになります。ただし、これを確認する方法がわからない...
Mathieu Rodic '15年

2
魅力的な作品で、データベースが稼働しているときに行いました。
BioRod 2016年

これはうまくいくようです。ただし、2つのデータベースはを介してディスクサイズが異なります\l+。なぜサイズ違い?
kosgeinsky

@kosgeinskyこれはここで広範囲に回答されています:dba.stackexchange.com/a/102089/39386
Mathieu Rodic

18

このアプローチを上記の例と組み合わせました。「負荷のかかった」サーバーで作業していて、@ zbyszekからアプローチを試みたときにエラーが発生しました。また、「コマンドラインのみ」のソリューションも必要でした。

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

これが私のために働いたものです(出力をファイルに移動してサーバーの切断から保護するために先頭に付加されnohupたコマンド):

  1. nohup pg_dump exampledb > example-01.sql
  2. createdb -O postgres exampledbclone_01

    私のユーザーは「postgres」です

  3. nohup psql exampledbclone_01 < example-01.sql


15

pgAdminでは、元のデータベースからバックアップを作成し、新しいデータベースを作成して、作成したバックアップから復元できます。

  1. ソースデータベースを右クリックして、[バックアップ...]をクリックし、ファイルにダンプします。
  2. 右クリックして、[新しいオブジェクト]、[新しいデータベース...]をクリックし、コピー先に名前を付けます。
  3. 新しいデータベースを右クリックして[復元...]をクリックし、ファイルを選択します。

外部キーを介して関連するテーブルがありますが、これは問題なく機能しました。
Randall Blake

12

データベース全体(その構造とデータ)をpgAdminの新しいデータベースにコピーする正しい方法は何ですか?

回答:

CREATE DATABASE newdb WITH TEMPLATE originaldb;

試してテストしました。


3
これには、originaldbが使用されていないことが必要です。アイソモルフの方法はそうではありません。
Bradley、

2
同じ答えがあなたの3年近く前に提供されました
Jason S

8

ドキュメントから、createdbまたはCREATE DATABASEテンプレートを使用することは推奨されていません:

テンプレートとして名前を指定して、template1以外のデータベースをコピーすることは可能ですが、これは(まだ)汎用の「COPY DATABASE」機能としては意図されていません。主な制限は、コピー中は他のセッションをテンプレートデータベースに接続できないことです。開始時に他の接続が存在する場合、CREATE DATABASEは失敗します。それ以外の場合、テンプレートデータベースへの新しい接続は、CREATE DATABASEが完了するまでロックされます。

pg_dumpまたはpg_dumpall、データベースとすべてのデータをコピーするための良い方法です。pgAdminなどのGUIを使用している場合、これらのコマンドは、バックアップコマンドを実行するとバックグラウンドで呼び出されます。新しいデータベースへのコピーは、バックアップと復元の2つのフェーズで行われます。

pg_dumpallすべてのデータベースをPostgreSQLクラスターに保存します。このアプローチの欠点は、データベースを作成してデータを入力するために必要なSQLでいっぱいの非常に大きなテキストファイルが作成されることです。このアプローチの利点は、クラスターのすべての役割(権限)を無料で取得できることです。すべてのデータベースをダンプするには、スーパーユーザーアカウントからこれを実行します

pg_dumpall > db.out

そして復元する

psql -f db.out postgres

pg_dumpはるかに小さなファイルを提供するいくつかの圧縮オプションがあります。私が使用するcronジョブで1日に2回バックアップする本番データベースがあります

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

ここで、compress圧縮レベル(0〜9)であるとcreate指示しpg_dump、データベースを作成するコマンドを追加します。を使用して復元(または新しいクラスターに移動)

pg_restore -d newdb db.dump

ここで、newdbは使用するデータベースの名前です。

その他の考慮事項

PostgreSQLは、権限の管理にROLESを使用します。これらはによってコピーされませんpg_dump。また、postgresql.confpg_hba.confの設定は扱っていません(データベースを別のサーバーに移動する場合)。自分でconf設定を把握する必要があります。しかし、ロールをバックアップするために今発見したトリックがあります。役割はクラスターレベルで管理されpg_dumpall--roles-onlyコマンドラインスイッチを使用して役割のみのバックアップを要求できます。


7

PostgreSQL 9.1.2:

$ CREATEDB new_db_name -T orig_db_name -O db_user;

3
これはおそらく実装されCREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;ており、その結果、元のデータベースがアイドル状態(書き込みアクセスのある接続なし)である必要があり、コピーの処理中は元のデータベースへの新しい接続が阻止されます。あなたがそれに満足しているなら、これはうまくいきます。
Mikko Rantalainen 2013年

素敵なディテール。ありがとうございました!
2015

6

まだ興味がある人のために、筆者が望んだことを(多かれ少なかれ)実行するbashスクリプトを思いつきました。私は本番システムで毎日ビジネスデータベースのコピーを作成する必要がありましたが、このスクリプトでうまくいくようです。データベース名/ユーザー/ 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"

5

データベースダンプを作成するには

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

データベースダンプを再割り当てするには

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

5

これは、pgadmin4 GUIのみを使用して(バックアップと復元を介して)データベースにコピーを作成するプロセス全体です。

PostgresにはPgadmin4が付属しています。macOSを使用している場合は、CMD+ SPACEを押して入力pgadmin4し、実行します。これにより、ブラウザのタブがChromeで開きます。


コピーの手順

1.バックアップを作成する

これを行うには、データベースを右クリックし、[バックアップ]をクリックします。

ここに画像の説明を入力してください

2.ファイルに名前を付けます。

のようにtest12345。バックアップをクリックします。これは、バイナリファイルダンプを作成しますが、.sql形式ではありません

ここに画像の説明を入力してください

3.ダウンロードした場所を確認する

画面の右下にポップアップがあります。[詳細]ページをクリックして、バックアップのダウンロード先を確認します

ここに画像の説明を入力してください

4.ダウンロードしたファイルの場所を見つける

この場合、それは /users/vincenttang

ここに画像の説明を入力してください

5. pgadminからバックアップを復元します

手順1〜4を正しく実行したとすると、復元バイナリファイルが作成されます。同僚がローカルマシンで復元ファイルを使用したいときがあるかもしれません。その人にpgadminに行って復元してもらいました

これを行うには、データベースを右クリックし、[復元]をクリックします。

ここに画像の説明を入力してください

6.ファイルファインダーを選択します

必ずファイルの場所を手動で選択してください。ファイルをpgadminのアップローダーフィールドにドラッグアンドドロップしないでください。エラー権限に遭遇するからです。代わりに、作成したファイルを見つけます。

ここに画像の説明を入力してください

7.上記のファイルを見つける

右下のフィルターを「すべてのファイル」に変更する必要がある場合があります。その後、ステップ4からファイルを見つけます。次に、右下の[選択]ボタンをクリックして確定します。

ここに画像の説明を入力してください

8.上記のファイルを復元する

ファイルの場所が選択された状態で、このページが再び表示されます。先に進んで、それを復元してください

ここに画像の説明を入力してください

9.成功

すべて問題なければ、右下に復元の成功を示すインジケーターがポップアップ表示されます。テーブルに移動して、データが各テーブルで適切に復元されているかどうかを確認できます。

10.成功しなかった場合:

手順9が失敗した場合は、データベースの古いパブリックスキーマを削除してみてください。「クエリツール」に行く

ここに画像の説明を入力してください

次のコードブロックを実行します。

DROP SCHEMA public CASCADE; CREATE SCHEMA public;

ここに画像の説明を入力してください

ステップ5から9をもう一度試してください。うまくいくはずです。

編集 -いくつかの追加メモ。復元中に「アーカイバヘッダー1.14サポートされていないバージョン」の行に沿ってアップロード中にエラーが発生した場合は、PGADMIN4を更新します。


3

データベースの接続が開いている場合、このスクリプトが役立つことがあります。私はこれを使用して、ライブプロダクションデータベースのバックアップから毎晩テストデータベースを作成します。これは、運用データベースからの.SQLバックアップファイルがあることを前提としています(私はこれを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"

1

pgAdminを使用して、テンプレートとして使用するデータベースを切断します。次に、それをテンプレートとして選択して、新しいデータベースを作成します。これにより、すでに使用中のエラーが発生するのを回避できます。


0

スキーマ全体をコピーしたい場合は、次のコマンドでpg_dumpを作成できます。

pg_dump -h database.host.com -d database_name -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" -f sql_dump_to_import.sql

接続文字列の詳細:https : //www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING

または、それを1つのライナーに組み合わせます。

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
  1. pgAdminでメインウィンドウを開き、別のクエリツールウィンドウを開きます。
  2. pgAdminのメインウィンドウで、

テンプレートとして使用する「テンプレート」データベースを切断します。

  1. クエリツールウィンドウに移動

以下のように2つのクエリを実行する

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

(上記のSQLステートメントはTemplateDBとのすべてのアクティブなセッションを終了し、それをテンプレートとして選択して新しいTargetDBデータベースを作成できます。これにより、すでに使用中のエラーが発生するのを回避できます。)

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

-4

これを試して:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.