วิธีที่ถูกต้องในการคัดลอกฐานข้อมูลทั้งหมด (โครงสร้างและข้อมูล) ไปยังฐานข้อมูลใหม่ใน pgAdmin คืออะไร?
วิธีที่ถูกต้องในการคัดลอกฐานข้อมูลทั้งหมด (โครงสร้างและข้อมูล) ไปยังฐานข้อมูลใหม่ใน pgAdmin คืออะไร?
คำตอบ:
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();
Servers
-> (เซิร์ฟเวอร์ของฉัน) -> Databases
คลิกขวาที่ฐานข้อมูลและเลือก "ฐานข้อมูลใหม่" หนึ่งในตัวเลือกคือเทมเพลตและ SQL ที่ใช้สร้างฐานข้อมูลนั้นเทียบเท่า มันเป็นเช่นนั้นเร็วกว่าการถ่ายโอนข้อมูล / กู้คืนบนเซิร์ฟเวอร์เดียวกัน
คำตอบของ Bellเวอร์ชันบรรทัดคำสั่ง:
createdb -O ownername -T originaldb newdb
สิ่งนี้ควรถูกเรียกใช้ภายใต้สิทธิ์ของต้นแบบฐานข้อมูลซึ่งปกติแล้วจะเป็น postgres
createdb: database creation failed: ERROR: source database "conf" is being accessed by other users
ถ้าคุณพยายามทำบนฐานข้อมูลการผลิตและตามที่คาดไว้คุณไม่ต้องการปิดมันเพื่อสร้างสำเนา
หากต้องการโคลนฐานข้อมูลที่มีอยู่ด้วย 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;
มันจะฆ่าการเชื่อมต่อทั้งหมดไปยังแหล่ง db หลีกเลี่ยงข้อผิดพลาด
ERROR: source database "SOURCE_DB" is being accessed by other users
procpid
ด้วยpid
สำหรับการทำงาน
ในสภาพแวดล้อมการผลิตที่ฐานข้อมูลดั้งเดิมอยู่ภายใต้การรับส่งข้อมูลฉันเพียงแค่ใช้:
pg_dump production-db | psql test-db
pg_dump -s
? postgresql.org/docs/current/static/app-pgdump.html
$ createdb newdb
ไม่ทราบเกี่ยวกับ pgAdmin แต่pgdump
ให้ดัมพ์ของฐานข้อมูลใน SQL คุณจะต้องสร้างฐานข้อมูลด้วยชื่อเดียวกันและทำ
psql mydatabase < my dump
เพื่อเรียกคืนตารางและข้อมูลทั้งหมดและสิทธิ์การเข้าถึงทั้งหมด
pg_dump -U postgres sourcedb | psql -U postgres newdb
แม้ว่าประสิทธิภาพของเทคนิคนี้อาจจะเป็นที่น่าสงสัย (ตั้งแต่คุณอาจจบลงด้วยการเปลี่ยนบริบทระหว่างอ่านและเขียน)
ssh dbserver pg_dump DBNAME | psql NEWDB
... หรือpg_dump DBNAME | ssh otherserver pgsql NEWDB
... สิทธิ์และการรับรองความถูกต้องแน่นอนต้องได้รับการจัดการ แต่คุณต้องการจัดการกับมัน
ก่อนอื่น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
\l+
แต่ทั้งสองฐานข้อมูลมีขนาดที่แตกต่างกันผ่านทางแผ่นดิสก์ ทำไมขนาดแตกต่างกันอย่างไร
ฉันสรุปวิธีนี้พร้อมกับตัวอย่างจากด้านบน ฉันกำลังทำงานกับเซิร์ฟเวอร์ "under load" และได้รับข้อผิดพลาดเมื่อฉันพยายามใช้วิธีการจาก @zbyszek ฉันยังอยู่หลังโซลูชัน "บรรทัดคำสั่งเท่านั้น"
createdb: database creation failed: ERROR: source database "exampledb" is being accessed by other users
.
นี่คือสิ่งที่ใช้งานได้สำหรับฉัน ( คำสั่งเสริมด้วยnohup
เพื่อย้ายเอาต์พุตไปยังไฟล์และป้องกันการยกเลิกการเชื่อมต่อกับเซิร์ฟเวอร์ ):
nohup pg_dump exampledb > example-01.sql
createdb -O postgres exampledbclone_01
ผู้ใช้ของฉันคือ "postgres"
nohup psql exampledbclone_01 < example-01.sql
ใน pgAdmin คุณสามารถทำการสำรองข้อมูลจากฐานข้อมูลเดิมของคุณจากนั้นเพียงแค่สร้างฐานข้อมูลใหม่และเรียกคืนจากการสำรองข้อมูลที่เพิ่งสร้างขึ้น:
วิธีที่ถูกต้องในการคัดลอกฐานข้อมูลทั้งหมด (โครงสร้างและข้อมูล) ไปยังฐานข้อมูลใหม่ใน pgAdmin คืออะไร?
ตอบ:
CREATE DATABASE newdb WITH TEMPLATE originaldb;
พยายามและทดสอบ
จากเอกสารที่ใช้createdb
หรือCREATE DATABASE
กับแม่แบบไม่ได้รับการสนับสนุน:
แม้ว่ามันจะเป็นไปได้ที่จะคัดลอกฐานข้อมูลอื่นนอกเหนือจาก template1 โดยการระบุชื่อของมันเป็นเทมเพลต แต่มันก็ยังไม่ได้มีวัตถุประสงค์เพื่อเป็นสิ่งอำนวยความสะดวก“ COPY DATABASE” วัตถุประสงค์ทั่วไป ข้อ จำกัด หลักคือไม่มีเซสชันอื่นใดที่สามารถเชื่อมต่อกับฐานข้อมูลแม่แบบในขณะที่กำลังถูกคัดลอก CREAT DATABASE จะล้มเหลวหากมีการเชื่อมต่ออื่นอยู่เมื่อเริ่มทำงาน มิฉะนั้นการเชื่อมต่อใหม่ไปยังฐานข้อมูลแม่แบบจะถูกล็อคจนกว่า CREATE DATABASE จะเสร็จสมบูรณ์
pg_dump
หรือpg_dumpall
เป็นวิธีที่ดีในการคัดลอกฐานข้อมูลและข้อมูลทั้งหมด หากคุณใช้ GUI เช่น pgAdmin คำสั่งเหล่านี้จะถูกเรียกใช้เบื้องหลังเมื่อคุณเรียกใช้คำสั่งสำรอง การคัดลอกไปยังฐานข้อมูลใหม่ทำได้ในสองขั้นตอนคือการสำรองและกู้คืน
pg_dumpall
บันทึกฐานข้อมูลทั้งหมดในคลัสเตอร์ PostgreSQL ข้อเสียของวิธีการนี้คือคุณต้องจบด้วยไฟล์ข้อความที่มีขนาดใหญ่มากซึ่งเต็มไปด้วย SQL ที่จำเป็นสำหรับการสร้างฐานข้อมูลและเติมข้อมูล ข้อดีของวิธีนี้คือคุณจะได้รับบทบาททั้งหมด (สิทธิ์) สำหรับคลัสเตอร์ได้ฟรี การถ่ายโอนฐานข้อมูลทั้งหมดทำได้จากบัญชี superuser
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 ใช้บทบาทในการจัดการการอนุญาต pg_dump
เหล่านี้จะไม่ได้คัดลอกจาก นอกจากนี้เรายังไม่ได้จัดการกับการตั้งค่าในpostgresql.confและpg_hba.conf (หากคุณย้ายฐานข้อมูลไปยังเซิร์ฟเวอร์อื่น) คุณจะต้องคิดการตั้งค่า conf ด้วยตัวคุณเอง แต่มีเคล็ดลับที่ฉันเพิ่งค้นพบสำหรับการสำรองบทบาท บทบาทได้รับการจัดการในระดับคลัสเตอร์และคุณสามารถขอpg_dumpall
ให้สำรองข้อมูลเฉพาะบทบาทด้วย--roles-only
สวิตช์บรรทัดคำสั่ง
PostgreSQL 9.1.2:
$ CREATEDB new_db_name -T orig_db_name -O db_user;
CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;
และเป็นผลให้ต้องการให้ฐานข้อมูลต้นฉบับต้องว่าง (ไม่มีการเชื่อมต่อที่มีการเข้าถึงการเขียน) และการเชื่อมต่อใหม่ไปยังฐานข้อมูลเดิมจะถูกป้องกันในขณะที่การคัดลอกกำลังดำเนินการอยู่ หากคุณพอใจกับสิ่งนี้
สำหรับผู้ที่ยังสนใจฉันได้สร้างสคริปต์ทุบตีที่ทำ (มากหรือน้อย) ตามที่ผู้เขียนต้องการ ฉันต้องทำสำเนาฐานข้อมูลธุรกิจรายวันบนระบบการผลิตสคริปต์นี้ดูเหมือนจะทำเคล็ดลับ อย่าลืมเปลี่ยนชื่อฐานข้อมูล / ค่าผู้ใช้ / 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"
เพื่อสร้างฐานข้อมูลดัมพ์
cd /var/lib/pgsql/
pg_dump database_name> database_name.out
เพื่อ resote ฐานข้อมูลการถ่ายโอนข้อมูล
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
นี่คือกระบวนการทั้งหมดของการสร้างการคัดลอกไปยังฐานข้อมูลโดยใช้เฉพาะ pgadmin4 GUI (ผ่านการสำรองและกู้คืน)
Postgres มาพร้อมกับ Pgadmin4 หากคุณใช้ macOS คุณสามารถกดCMD
+ SPACE
และพิมพ์pgadmin4
เพื่อเรียกใช้ สิ่งนี้จะเปิดแท็บเบราว์เซอร์ใน Chrome
ทำได้โดยคลิกขวาที่ฐานข้อมูล -> "สำรอง"
กดtest12345
ไลค์ คลิกสำรองข้อมูล สิ่งนี้สร้างดัมพ์ไฟล์ไบนารีไม่ใช่ใน.sql
รูปแบบ
ควรมีป๊อปอัพที่ด้านล่างของหน้าจอของคุณ คลิกหน้า "รายละเอียดเพิ่มเติม" เพื่อดูว่าข้อมูลสำรองของคุณถูกดาวน์โหลดไปที่ใด
ในกรณีนี้มันเป็น /users/vincenttang
สมมติว่าคุณทำตามขั้นตอนที่ 1 ถึง 4 อย่างถูกต้องคุณจะมีไฟล์ไบนารีกู้คืน อาจมีบางครั้งที่เพื่อนร่วมงานของคุณต้องการใช้ไฟล์กู้คืนในเครื่องของพวกเขา มีคนกล่าวว่าไป pgadmin และเรียกคืน
ทำได้โดยคลิกขวาที่ฐานข้อมูล -> "กู้คืน"
อย่าลืมเลือกตำแหน่งไฟล์ด้วยตัวเองอย่าลากและวางไฟล์ลงในช่องอัพโหลดใน pgadmin เพราะคุณจะพบข้อผิดพลาดในการอนุญาต ค้นหาไฟล์ที่คุณเพิ่งสร้างขึ้นแทน:
คุณอาจต้องเปลี่ยนตัวกรองที่ด้านล่างเป็น "ไฟล์ทั้งหมด" ค้นหาไฟล์หลังจากนั้นจากขั้นตอนที่ 4 ตอนนี้กดปุ่ม "เลือก" ที่ด้านล่างเพื่อยืนยัน
คุณจะเห็นหน้านี้อีกครั้งพร้อมที่ตั้งของไฟล์ที่เลือก ไปข้างหน้าและเรียกคืน
หากทุกอย่างดีด้านล่างขวาควรป๊อปอัพตัวบ่งชี้ที่แสดงว่าการกู้คืนสำเร็จ คุณสามารถนำทางไปยังตารางของคุณเพื่อดูว่าข้อมูลได้รับการกู้คืนอย่างเหมาะสมในแต่ละตารางหรือไม่
หากขั้นตอนที่ 9 ล้มเหลวลองลบสคีมาเก่าของคุณในฐานข้อมูลของคุณ ไปที่ "เครื่องมือค้นหา"
ดำเนินการบล็อกรหัสนี้:
DROP SCHEMA public CASCADE; CREATE SCHEMA public;
ตอนนี้ลองขั้นตอนที่ 5 ถึง 9 อีกครั้งมันควรจะได้ผล
แก้ไข - บันทึกเพิ่มเติมบางส่วน อัปเดต PGADMIN4 หากคุณได้รับข้อผิดพลาดระหว่างการอัปโหลดพร้อมบางอย่างตามบรรทัดของ "archiver header 1.14 เวอร์ชั่นที่ไม่สนับสนุน" ระหว่างการกู้คืน
หากฐานข้อมูลมีการเชื่อมต่อแบบเปิดสคริปต์นี้อาจช่วยได้ ฉันใช้สิ่งนี้เพื่อสร้างฐานข้อมูลทดสอบจากข้อมูลสำรองของฐานข้อมูลการผลิตสดทุกคืน นี่ถือว่าคุณมีไฟล์สำรอง. 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"
ใช้ pgAdmin ตัดการเชื่อมต่อฐานข้อมูลที่คุณต้องการใช้เป็นเทมเพลต จากนั้นคุณเลือกเป็นเทมเพลตเพื่อสร้างฐานข้อมูลใหม่เพื่อหลีกเลี่ยงข้อผิดพลาดในการใช้งาน
หากคุณต้องการคัดลอกสคีมาทั้งหมดคุณสามารถสร้าง 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”
ตัดการเชื่อมต่อฐานข้อมูล "templated" ที่คุณต้องการใช้เป็นแม่แบบ
เรียกใช้ 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;
ลองสิ่งนี้:
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