PostgreSQL에서 데이터베이스 사본 생성


728

전체 데이터베이스 (구조 및 데이터)를 pgAdmin의 새 데이터베이스로 복사하는 올바른 방법은 무엇입니까?

답변:


1120

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선택하고 데이터베이스를 마우스 오른쪽 단추로 클릭 한 다음 "새 데이터베이스"를 선택할 수 있습니다. 옵션 중 하나는 템플리트이며 데이터베이스를 작성하는 데 사용되는 SQL은 동일합니다. 그것은이다 그래서 동일한 서버에 복원 / 더 빠르게 덤프보다.
jwhitlock

22
나는 이것이 오래된 Q / A라는 것을 알고 있지만 설명이 필요하다고 생각합니다. @ synecdoche가 originaldb가 유휴 상태 여야한다고 말하면 쓰기 가능성이 전혀 없습니다. 이런 방식으로 데이터베이스를 "복사"해도 originaldb는 잠기지 않습니다. PostgreSQL은 복사가 시작된 후가 아니라 originaldb에 액세스하는 다른 사람이있는 경우에만 복사를 시작하지 못하므로 "복사"가 발생하는 동안 다른 연결이 데이터베이스를 수정할 수 있습니다. IMHO, 이것은 가장 쉬운 대답 일 수 있지만 가장 좋은 방법은 덤프 / 복원을 사용하는 것입니다.
Josh

10
방금 봤어요 @Josh : 템플릿을 사용하여 데이터베이스 생성으로 originaldb를 복사하는 동안 postgresql은 새 연결을 만들 수 없으므로 변경할 수 없습니다.
ceteras

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프로덕션 데이터베이스에서 수행하려고하면 사본을 만들기 위해 종료하지 않으려 는 경우 얻을 수 있습니다.
sorin

7
예, 명시적인 CREATE DATABASE 호출과 동일한 경고가이 명령에 적용됩니다. 위의 Bell 답변에 대한 의견과 마찬가지로 데이터베이스는 유휴 상태 여야합니다.
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는 오류를 피하면서 소스 DB에 대한 모든 연결을 종료합니다

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

7
액세스 오류를 피하기위한 스크립트 솔루션을 언급 한 +1
bully

14
포스트 그레스 9.2에 나는 교체해야 procpid와 함께 pid이 작업을 수행하려면
marxjohnson

75

원본 데이터베이스가 트래픽을 받고있는 프로덕션 환경에서는 다음을 사용합니다.

pg_dump production-db | psql test-db

8
이 방법으로 찾은 한 가지 문제는 pg_dump가 실제로 덤프를 완료 한 경우에도 pg_dump가 새 데이터베이스로의 복원이 완료 될 때까지 트랜잭션을 열린 상태로 유지한다는 것입니다. 이로 인해 경우에 따라 잠금 문제가 발생할 수 있습니다 (예를 들어, DDL 문이 소스 DB에서 실행되는 경우).
크리스 버틀러

3
임시 중간 파일을 사용하지 않는 것에 대한 플러스.
Ardee Aram

또한 내 솔루션이었습니다. 어제 효과가 있었지만 이제는 임의의 고유 제약 조건을 위반했습니다. 참고 : 모든 테이블을 수신자 db에 삭제합니다.
gunzapper


1
이것은 test-db가 존재한다고 가정합니다. 그렇지 않은 경우$ createdb newdb
SamGoody

50

pgAdmin에 대해 모르지만 pgdumpSQL로 데이터베이스 덤프를 제공합니다. 같은 이름으로 데이터베이스를 작성하면됩니다.

psql mydatabase < my dump

모든 테이블과 해당 데이터 및 모든 액세스 권한을 복원합니다.


고마워, 나는 다른 서버에서 덤프를 만들어야했고 이것이 도움이 될 것 같다 : postgresql.org/docs/8.3/interactive/…
egaga

19
당신은 할 수있는 pg_dump -U postgres sourcedb | psql -U postgres newdb이 기술의 효율성이 의심 될 수 있지만 (읽기 및 쓰기 사이에 당신은 아마 컨텍스트 전환을 끝낼 때문에)
프랭크 파머

1
ssh : ssh dbserver pg_dump DBNAME | psql NEWDB... 또는 pg_dump DBNAME | ssh otherserver pgsql NEWDB ... 를 통해 원격 시스템에서 덤프를 가져올 수도 있습니다. 물론 권한 및 인증을 처리해야하지만 처리하려는 경우.
ghoti

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

몇 가지 오류 (네트워크 문제)가 발생하더라도 모든 것이 정상인지 확인하는 방법은 무엇입니까? 마이그레이션 후 두 데이터베이스가 동일한 지 확인하는 방법은 무엇입니까?
BAE

오류가 발생할 때마다 터미널에 표시되어야합니다. 작업 후 두 데이터베이스는 동일해야합니다. 그러나, 나는 이것을 확인하는 방법을 모른다 ...
Mathieu Rodic

2
매력처럼 작동하지만 데이터베이스가 프로덕션 환경에있는 동안했습니다.
BioRod

이것은 잘 작동하는 것으로 보입니다. 그러나 두 데이터베이스의 디스크 크기는 서로 다릅니다 \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. 새 데이터베이스 인 Restore ...를 마우스 오른쪽 단추로 클릭하고 파일을 선택하십시오.

외래 키를 통해 관련 테이블이 있으며 이것은 잘 작동합니다.
랜달 블레이크

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를 사용하는 경우, 백업 명령을 실행할 때 이러한 명령이 뒤에서 호출됩니다. 새 데이터베이스에 복사는 백업 및 복원의 두 단계로 수행됩니다.

pg_dumpallPostgreSQL 클러스터에 모든 데이터베이스를 저장합니다. 이 방법의 단점은 데이터베이스를 작성하고 데이터를 채우는 데 필요한 SQL로 가득 찬 잠재적으로 매우 큰 텍스트 파일로 끝나는 것입니다. 이 방법의 장점은 클러스터의 모든 역할 (권한)을 무료로 얻을 수 있다는 것입니다. 모든 데이터베이스를 덤프하려면 수퍼 유저 계정에서이 작업을 수행하십시오.

pg_dumpall > db.out

복원

psql -f db.out postgres

pg_dump더 작은 파일을 제공하는 압축 옵션이 있습니다. 사용하는 크론 작업으로 하루에 두 번 백업하는 프로덕션 데이터베이스가 있습니다.

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

좋은 디테일. 감사합니다!
Arta

6

여전히 관심이있는 사람들을 위해 저자가 원하는 것을 수행하는 bash 스크립트를 생각해 냈습니다. 프로덕션 시스템에서 매일 비즈니스 데이터베이스 복사본을 만들어야했지만이 스크립트는 트릭을 수행하는 것 같습니다. 데이터베이스 이름 / 사용자 / 암호 값을 변경해야합니다.

#!/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하여 실행할 수 있습니다. 크롬에서 브라우저 탭이 열립니다.


복사 단계

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

데이터베이스에 연결이 열려 있으면이 스크립트가 도움이 될 수 있습니다. 매일 밤 라이브 프로덕션 데이터베이스의 백업에서 테스트 데이터베이스를 만드는 데 사용합니다. 이것은 프로덕션 DB의 .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

또는 하나의 라이너로 결합하면됩니다.

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에서 메인 창을 연 다음 다른 Query Tools 창을여십시오
  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.