Створення копії бази даних у 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 повинен працювати в режимі очікування (без транзакцій з записом).
синекдоха

62
у pgAdmin3, на панелі браузера об’єктів (ліворуч) я можу вибрати Servers-> (мій сервер) -> Databases, клацнути правою кнопкою миші Бази даних та вибрати «Нова база даних». Одним із варіантів є шаблон, а SQL, що використовується для створення бази даних, є рівнозначним. Це так набагато швидше , ніж звалище / відновлення на тому ж сервері.
jwhitlock

22
Я знаю, що це старий Q / A, але я вважаю, що це потребує уточнення: Коли @synecdoche каже, що originaldb повинен працювати в режимі очікування, це означає, що взагалі немає можливості запису. "Копіювання" бази даних таким чином не блокує originaldb. PostgreSQL заважає запускати копію лише в тому випадку, якщо інші користувачі отримують доступ до originaldb - не після запуску копії, тому можливо, що інше з'єднання могло б змінити базу даних під час "копіювання". ІМХО, це може бути найпростішою відповіддю, але "найкращим" було б використання дампа / відновлення.
Джош

10
Я щойно це бачив. @Josh: під час копіювання originaldb створюється база даних із шаблоном, postgresql не дозволяє створити нове з'єднання з ним, тому ніякі зміни неможливі.
цетерас

4
Зауважте, що якщо ви використовуєте pgAdmin та виконуєте CREATE DATABASE ... TEMPLATE xxx з вікна команд SQL, ви повинні відключитися від бази даних у головному вікні pgAdmin, або ви отримаєте помилку щодо користувачів, підключених до бази даних.
Jack RG

296

Версія відповіді командного рядка відповіді Белла :

createdb -O ownername -T originaldb newdb

Це має бути запущено під привілеями майстра бази даних, як правило, постгресів.


5
Це хороша команда, але ви отримаєте, createdb: database creation failed: ERROR: source database "conf" is being accessed by other usersякщо спробуєте це зробити на виробничій базі даних, і, як очікується, ви не хочете її закривати, щоб створити копію.
sorin

7
Так, ці ж застереження застосовуються до цієї команди, як і до явного виклику CREATE DATABASE. Як і коментарі до відповіді Белла, сказані вище, база даних повинна працювати в режимі очікування.
zbyszek

108

Щоб клонувати наявну базу даних з постгресами, ви можете це зробити

/* 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 за згадку про рішення сценарію, щоб уникнути помилки доступу
хуліган

14
На Postgres 9.2 я повинен замінити procpidз pidдля цієї роботи
marxjohnson

75

У виробничих умовах, де оригінальна база даних знаходиться під трафіком, я просто використовую:

pg_dump production-db | psql test-db

8
Одне з проблем, які я знайшов за допомогою цього методу, полягає в тому, що pg_dump буде відкривати свою транзакцію до повного відновлення в новій базі даних, навіть якщо pg_dump фактично закінчив свій дамп. Це може спричинити проблеми із блокуванням у деяких випадках (наприклад, якщо оператор DDL запускається у вихідній БД).
Кріс Батлер

3
Плюс один - не використовувати тимчасові проміжні файли.
Ardee Aram

Це було також моїм рішенням. Вчора це спрацювало, тепер випадкові унікальні обмеження порушуються. Примітка: я передаю всю таблицю на db приймача.
gunzapper


1
Це передбачає, що test-db існує. В іншому випадку створіть новий db за допомогою$ createdb newdb
SamGoody

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хоча ефективність цієї методики може бути сумнівною (оскільки ви, ймовірно, закінчуєте переключення контексту між читаннями і записами)
Френк Фармер

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

Помилки повинні відображатися в терміналі, коли виникають. Дві бази даних повинні бути однаковими після операції. Однак я не знаю, як це перевірити ...
Матьє Родіч

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. Клацніть правою кнопкою миші нову базу даних, Відновити ... та виберіть файл.

У мене пов’язані таблиці за допомогою зовнішніх ключів, і це спрацювало чудово.
Рэндалл Блейк

12

Який правильний спосіб скопіювати всю базу даних (її структуру та дані) в нову в pgAdmin?

Відповідь:

CREATE DATABASE newdb WITH TEMPLATE originaldb;

Перепробував і випробував.


3
Це вимагає, щоб originaldb не використовувався. Метод Ізоморфа ні.
Бредлі

2
Таку ж відповідь було надано майже за три роки до вашого
Jason S

8

З документації використання createdbабо CREATE DATABASEз шаблонами не рекомендується:

Хоча можна скопіювати базу даних, крім шаблону1, вказавши її ім'я як шаблон, це (ще) не призначено як загальний засіб "ДОДАТКОВА КОПІЯ" загального призначення. Основне обмеження полягає в тому, що жоден інший сеанс не може бути підключений до бази даних шаблонів під час його копіювання. CREATE DATABASE не вдасться, якщо будь-яке інше з'єднання існує під час його запуску; в іншому випадку нові підключення до бази даних шаблонів блокуються, поки CREATE DATABASE не завершиться.

pg_dumpабо pg_dumpallце хороший спосіб скопіювати базу даних та ВСІ ДАНІ. Якщо ви використовуєте графічний інтерфейс, наприклад pgAdmin, ці команди викликаються поза кадром під час виконання команди резервного копіювання. Копіювання в нову базу даних проводиться в два етапи: резервне копіювання та відновлення

pg_dumpallзберігає всі бази даних на кластері PostgreSQL. Недоліком такого підходу є те, що у вас є потенційно дуже великий текстовий файл, повний SQL, необхідний для створення бази даних та заповнення даних. Перевага такого підходу полягає в тому, що ви отримуєте всі ролі (дозволи) для кластеру безкоштовно. Щоб скинути всі бази даних, зробіть це з облікового запису суперпользователя

pg_dumpall > db.out

і відновити

psql -f db.out postgres

pg_dumpмає кілька варіантів стиснення, які дають вам значно менші файли. У мене є виробнича база даних, яку я резервно копіюю двічі на день, використовуючи роботу cron

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.conf та pg_hba.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;оскільки в результаті вимагає, щоб оригінальна база даних не працювала (відсутність з'єднань з доступом до запису), а будь-які нові з'єднання з оригінальною базою даних запобігалися під час копіювання. Якщо ви цим задоволені, це працює.
Мікко Ранталайнен

Приємна деталь. Дякую!
Арта

6

Для тих, хто все ще цікавиться, я придумав сценарій баш, який робить (більш-менш) те, що хотів автор. Мені довелося робити щоденну копію бази даних для бізнесу у виробничій системі, схоже, цей сценарій робить свою справу. Не забудьте змінити значення бази даних / користувача / 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 (за допомогою резервного копіювання та відновлення)

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 знову, це має спрацювати

EDIT - Деякі додаткові примітки. Оновіть PGADMIN4, якщо під час завантаження виникає помилка під час відновлення "непідтримувана версія архіватора заголовка 1.14" під час відновлення


3

Якщо база даних має відкриті підключення, цей скрипт може допомогти. Я використовую це для створення тестової бази даних із резервної копії бази даних в реальному часі щовечора. Це передбачає, що у вас є файл резервного копіювання .SQL з виробництва db (я це роблю в 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, а потім відкрийте інше вікно інструментів запитів
  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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.