คัดลอกฐานข้อมูล PostgreSQL ไปยังเซิร์ฟเวอร์อื่น


492

ฉันต้องการคัดลอกฐานข้อมูล PostgreSQL ที่ใช้งานจริงไปยังเซิร์ฟเวอร์การพัฒนา วิธีที่เร็วและง่ายที่สุดในการทำสิ่งนี้คืออะไร?

คำตอบ:


666

คุณไม่จำเป็นต้องสร้างไฟล์ระดับกลาง คุณทำได้

pg_dump -C -h localhost -U localuser dbname | psql -h remotehost -U remoteuser dbname

หรือ

pg_dump -C -h remotehost -U remoteuser dbname | psql -h localhost -U localuser dbname

การใช้psqlหรือpg_dumpเพื่อเชื่อมต่อกับโฮสต์ระยะไกล

ด้วยฐานข้อมูลขนาดใหญ่หรือการเชื่อมต่อที่ช้าการทิ้งไฟล์และถ่ายโอนไฟล์บีบอัดอาจเร็วกว่า

ดังที่ Kornel กล่าวว่าไม่จำเป็นต้องดัมพ์ไปยังไฟล์ระดับกลางหากคุณต้องการทำงานที่บีบอัดคุณสามารถใช้อุโมงค์ที่ถูกบีบอัดได้

pg_dump -C dbname | bzip2 | ssh  remoteuser@remotehost "bunzip2 | psql dbname"

หรือ

pg_dump -C dbname | ssh -C remoteuser@remotehost "psql dbname"

แต่วิธีนี้ยังต้องได้รับเซสชั่นในปลายทั้งสอง

หมายเหตุ: pg_dumpสำหรับการสำรองข้อมูลและpsqlสำหรับการกู้คืน ดังนั้นคำสั่งแรกในคำตอบนี้คือการคัดลอกจากท้องถิ่นเพื่อห่างไกลและคนที่สองจากระยะไกลเพื่อท้องถิ่น เพิ่มเติม -> https://www.postgresql.org/docs/9.6/app-pgdump.html


28
ไม่จำเป็นต้องมีไฟล์ระดับกลาง - คุณสามารถใช้อุโมงค์ SSH ที่ถูกบีบอัดหรือไพพ์ง่ายๆ: pg_dump | bzip2 | ssh "bunzip2 | pg_restore"
Kornel

4
หากคุณใช้ bzip2 ให้ปิดการบีบอัด ssh เพื่อเร่งความเร็วการถ่ายโอน!
lzap

8
ฉันจะทำงานบีบอัดได้อย่างไรหากฉันดึงข้อมูลจากการผลิตลงไปสู่การพัฒนา? ฉันได้ตั้งค่าการเชื่อมต่อ SSH จากการพัฒนาไปสู่การผลิต มันจะเป็นssh remoteuser@remotehost "pg_dump -C dbname | bzip2" | bunzip2 | psql dbnameอย่างไร
Jeromy French

2
ฉันคาดหวังว่าคุณควรจะสามารถคัดลอกฐานข้อมูลระยะไกลที่มีชื่อ x ไปยังฐานข้อมูลท้องถิ่นที่มีชื่อ y แต่โซลูชันของ @ Ferran ไม่ทำงานสำหรับสิ่งนี้ ... ดูเหมือนว่าฉันจะชอบวิธีการแก้ปัญหาของ porneL เพียงแค่ปล่อยไฟล์ bzip2 บน เซิร์ฟเวอร์ดังนั้นจึงไม่ใช่กระบวนการขั้นตอนเดียว เป็นกรณีนี้ฉันเดาว่าฉันจะลบฐานข้อมูล y ใช้ส่วน "หรือ" ของสารละลายของ Ferran ที่คืนค่า x จากนั้นเปลี่ยนชื่อฐานข้อมูลเป็น y
ดารินปีเตอร์สัน

3
นี่คือสิ่งที่ฉันทำ: (1) pg_dump -C -h remotehost -U remoteuser x | psql -h localhost -U localuser (2) dropdb y (3) psql -U postgres -c 'แก้ไขฐานข้อมูล "x" เปลี่ยนชื่อเป็น "y"'
Darin Peterson

131
pg_dump the_db_name > the_backup.sql

จากนั้นคัดลอกการสำรองข้อมูลไปยังเซิร์ฟเวอร์การพัฒนาของคุณคืนค่าด้วย:

psql the_new_dev_db < the_backup.sql

3
บางคนบอกฉันว่านี่อาจเป็นปัญหาได้ - ปัญหาเรื่องการอนุญาตที่ทำให้เกิดการถ่ายโอนข้อมูลหรือการเรียกคืนข้อมูลจะตายเมื่อมันกระทบกับทริกเกอร์
s โรบิน Barnes

17
@rmbarnes: หากมีปัญหา - พวกเขาต้องได้รับการแก้ไข หากไม่มีความรู้โดยละเอียดเกี่ยวกับสิ่งที่ "บางคน" ทำ - ไม่มีใครสามารถยืนยันหรือยกเลิกข้อเรียกร้องนี้ได้

4
ใช้แฟล็ก --no-owner กับ pg_dump สิ่งนี้จะข้ามปัญหาและการแก้ไขครั้งแรกของโพสต์นี้ใช้ - แต่ฉันคิดว่าคุณอาจต้องการความแม่นยำที่แม่นยำยิ่งขึ้นกับฐานข้อมูลต้นฉบับ
unmounted

4
สำหรับฉันวิธีการดังกล่าวทำงานในวิธีต่อไปนี้: pg_dump -C -h host -U ชื่อผู้ใช้ db_name> / any_directory / dump_schema_and_data_file และสำหรับการกู้คืนจากไฟล์: psql -h โฮสต์ -U ชื่อผู้ใช้ db_name <dump_schema_and_data_file
Ali Raza Bhayani

นั่นช่วยให้ฉันหงุดหงิดมาก ฉันใช้ไดรฟ์ของ Google เพื่อย้ายไฟล์ระหว่างเครื่อง เนื่องจากฉันมีฐานข้อมูลในเครื่องใหม่แล้ว (แต่ว่างเปล่า) ฉันได้รับข้อผิดพลาดที่สำคัญจำนวนมาก อย่างไรก็ตามมันเป็นสภาพแวดล้อมแบบ dev และพวกเขาไม่ได้ทำร้ายอะไร
Chris Mendla

37

ใช้pg_dumpและต่อมาpsqlหรือpg_restoreขึ้นอยู่กับว่าคุณเลือกตัวเลือก -Fp หรือ -Fc เพื่อ pg_dump

ตัวอย่างการใช้งาน:

ssh production
pg_dump -C -Fp -f dump.sql -U postgres some_database_name
scp dump.sql development:
rm dump.sql
ssh development
psql -U postgres -f dump.sql

22

หากคุณต้องการโยกย้ายระหว่างเวอร์ชัน (เช่นคุณอัปเดต postgres และให้ 9.1 ทำงานบน localhost: 5432 และ 9.3 ทำงานบน localhost: 5434) คุณสามารถเรียกใช้:

pg_dumpall -p 5432 -U myuser91 | psql -U myuser94 -d postgres -p 5434

ตรวจสอบเอกสารการย้ายถิ่น


ฉันขอรหัสผ่าน (myuser91 / postgres) - รหัสผ่านหลายครั้งมีวิธีใดบ้างที่ฉันต้องป้อนรหัสผ่านเพียงครั้งเดียว
Martin Weber

@MartinWeber สร้างไฟล์ pgpass ตามเอกสารนี้postgresql.org/docs/9.4/static/libpq-pgpass.html
Scott Warren

ถ้าพวกเขามีทั้งพอร์ตเดียวกันล่ะ
ggnoredo

หากอยู่บนเซิร์ฟเวอร์อื่นคุณสามารถใช้ -h เพื่อระบุโฮสต์
Haroldo_OK

16

pg_basebackup น่าจะเป็นวิธีที่ดีกว่าในการทำเช่นนี้โดยเฉพาะอย่างยิ่งสำหรับฐานข้อมูลขนาดใหญ่

คุณสามารถคัดลอกฐานข้อมูลจากเซิร์ฟเวอร์ด้วยเวอร์ชันหลักเดียวกันหรือเก่ากว่า หรือแม่นยำยิ่งขึ้น :

pg_basebackupทำงานร่วมกับเซิร์ฟเวอร์ที่เป็นเวอร์ชันหลักเดียวกันหรือเก่ากว่าลงไปที่ 9.1 อย่างไรก็ตามโหมดการสตรีม WAL ( -X stream) ใช้งานได้เฉพาะกับเซิร์ฟเวอร์เวอร์ชั่น 9.3 และใหม่กว่าและโหมดการจัดรูปแบบ tar ( --format=tar) ของเวอร์ชันปัจจุบันจะทำงานกับเซิร์ฟเวอร์เวอร์ชัน 9.5 หรือใหม่กว่าเท่านั้น

สำหรับสิ่งที่คุณต้องการบนเซิร์ฟเวอร์ต้นทาง:

  1. listen_addresses = '*'เพื่อให้สามารถเชื่อมต่อจากเซิร์ฟเวอร์เป้าหมาย ตรวจสอบให้แน่ใจว่าพอร์ต 5432 เปิดอยู่สำหรับเรื่องนั้น
  2. อย่างน้อย 1 การเชื่อมต่อที่มีอยู่การจำลองแบบ: max_wal_senders = 1( -X fetch) 2สำหรับ-X stream(ค่าเริ่มต้นในกรณีของ PostgreSQL 12) หรืออื่น ๆ อีกมากมาย
  3. wal_level = replicamax_wal_senders > 0หรือสูงกว่าเพื่อให้สามารถตั้งค่า
  4. host replication postgres DST_IP/32 trustในpg_hba.conf. สิ่งนี้ให้สิทธิ์การเข้าถึงpgคลัสเตอร์แก่ทุกคนจากDST_IPเครื่อง คุณอาจต้องการใช้ตัวเลือกที่ปลอดภัยกว่า

การเปลี่ยนแปลง 1, 2, 3 ต้องเริ่มต้นเซิร์ฟเวอร์ใหม่เปลี่ยน 4 ต้องรีโหลด

บนเซิร์ฟเวอร์เป้าหมาย:

# systemctl stop postgresql@VERSION-NAME
postgres$ pg_basebackup -h SRC_IP -U postgres -D VERSION/NAME --progress
# systemctl start postgresql@VERSION-NAME

11
คุณสามารถให้รายละเอียดเพิ่มเติมในคำตอบของคุณเช่นตัวอย่างได้หรือไม่?
Magnilex

7
สิ่งนี้ใช้ได้เฉพาะเมื่อเครื่องทั้งสองมีรุ่น PG เดียวกันเท่านั้น
เอสเอ็ม

โอกาสเล็กน้อยที่คุณจะใช้เวอร์ชันฐานข้อมูลที่แตกต่างกันสำหรับการพัฒนาและการผลิต ครั้งล่าสุดที่ฉันมีการสนทนาที่ไม่พึงประสงค์กับเพื่อนร่วมทีมของฉันขณะที่เธอพยายามส่งปัญหาที่บางรหัสไม่ทำงานกับ PG 9.6 ในขณะที่เราใช้ 9.5 ในการผลิตในเวลานั้น การสำรองฐานเร็วกว่ามาก จากนั้น pg_upgrade เป็นวิธีที่จะไปหากจำเป็น
Zorg

2
โอกาสที่คุณต้องการย้ายไปยังเวอร์ชันที่ใหม่กว่าและไม่ต้องการหยุด PostgreSQL
x-yuri

1
มีโอกาสที่ทุกครั้งที่คุณอัพเกรดฐานข้อมูลของคุณคุณจะอัพเกรดเป็น dev และ staging ก่อนที่จะทำการผลิต
andrew lorien

8

เรียกใช้คำสั่งนี้ด้วยชื่อฐานข้อมูลคุณต้องการสำรองข้อมูลเพื่อถ่ายโอนฐานข้อมูล

 pg_dump -U {user-name} {source_db} -f {dumpfilename.sql}

 eg. pg_dump -U postgres mydbname -f mydbnamedump.sql

ตอนนี้ scp ไฟล์การถ่ายโอนข้อมูลนี้ไปยังเครื่องระยะไกลที่คุณต้องการคัดลอกฐานข้อมูล

eg. scp mydbnamedump.sql user01@remotemachineip:~/some/folder/

บนเครื่องระยะไกลเรียกใช้คำสั่งต่อไปนี้ใน ~ / some / โฟลเดอร์เพื่อเรียกคืนฐานข้อมูล

 psql -U {user-name} -d {desintation_db}-f {dumpfilename.sql}

 eg. psql -U postgres -d mynewdb -f mydbnamedump.sql

7

ฉันพยายามอย่างมากและในที่สุดวิธีที่ทำให้ฉันใช้งานได้กับ Rails 4 คือ:

บนเซิร์ฟเวอร์เก่าของคุณ

sudo su - postgres
pg_dump -c --inserts old_db_name > dump.sql

ฉันต้องใช้ผู้ใช้ linux postgres เพื่อสร้างการถ่ายโอนข้อมูล ฉันต้องใช้ -c เพื่อบังคับให้สร้างฐานข้อมูลบนเซิร์ฟเวอร์ใหม่ - แทรกบอกให้ใช้ INSERT () ไวยากรณ์ซึ่งมิฉะนั้นจะไม่ทำงานสำหรับฉัน :(

จากนั้นบนเซิร์ฟเวอร์ใหม่ให้ simpy:

sudo su - postgres
psql new_database_name < dump.sql

เพื่อถ่ายโอนไฟล์ dump.sql ระหว่างเซิร์ฟเวอร์ฉันใช้ "cat" เพื่อพิมพ์เนื้อหาและไม่ใช่ "nano" เพื่อสร้างมันซ้ำเพื่อคัดลอกเนื้อหา

นอกจากนี้บทบาทที่ฉันใช้บนฐานข้อมูลทั้งสองนั้นแตกต่างกันดังนั้นฉันจึงต้องค้นหา - แทนที่ชื่อเจ้าของทั้งหมดในดัมพ์


6

ทิ้งฐานข้อมูลของคุณ: pg_dump database_name_name > backup.sql


นำเข้าฐานข้อมูลของคุณกลับมา: psql db_name < backup.sql


5

ให้ฉันแบ่งปัน Linux shell script เพื่อคัดลอกข้อมูลตารางของคุณจากเซิร์ฟเวอร์หนึ่งไปยังเซิร์ฟเวอร์ PostgreSQL อื่น

การอ้างอิงที่นำมาจากบล็อกนี้:

Linux Bash Shell Script สำหรับการย้ายข้อมูลระหว่างเซิร์ฟเวอร์ PostgreSQL:

#!/bin/bash
psql \
    -X \
    -U user_name \
    -h host_name1 \
    -d database_name \
    -c "\\copy tbl_Students to stdout" \
| \
psql \
    -X \
    -U user_name \
    -h host_name2 \
    -d database_name \
    -c "\\copy tbl_Students from stdin"

ฉันแค่ย้ายข้อมูล; โปรดสร้างตารางว่างที่เซิร์ฟเวอร์ฐานข้อมูลปลายทาง / วินาทีของคุณ

นี่คือสคริปต์ยูทิลิตี้ นอกจากนี้คุณสามารถแก้ไขสคริปต์สำหรับการใช้งานทั่วไปเช่นโดยการเพิ่มพารามิเตอร์สำหรับ host_name, database_name, table_name และอื่น ๆ


5

คำตอบที่ยอมรับนั้นถูกต้อง แต่ถ้าคุณต้องการหลีกเลี่ยงการป้อนรหัสผ่านแบบโต้ตอบคุณสามารถใช้สิ่งนี้:

PGPASSWORD={{export_db_password}} pg_dump --create -h {{export_db_host}} -U {{export_db_user}} {{export_db_name}} | PGPASSWORD={{import_db_password}} psql -h {{import_db_host}} -U {{import_db_user}} {{import_db_name}}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.