Menyalin database PostgreSQL ke server lain

492

Saya ingin menyalin basis data produksi PostgreSQL ke server pengembangan. Apa cara tercepat dan termudah untuk melakukan ini?

Robin Barnes
sumber

Jawaban:

668

Anda tidak perlu membuat file perantara. Anda dapat melakukan

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

atau

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

menggunakan psqlatau pg_dumpmenghubungkan ke host jarak jauh.

Dengan database besar atau koneksi yang lambat, membuang file dan mentransfer file yang dikompresi mungkin lebih cepat.

Seperti yang dikatakan Kornel, tidak perlu lagi membuang ke file perantara, jika Anda ingin bekerja dengan kompresi, Anda bisa menggunakan terowongan terkompresi.

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

atau

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

tetapi solusi ini juga mengharuskan untuk mendapatkan sesi di kedua ujungnya.

Catatan: pg_dump untuk pencadangan dan psqluntuk memulihkan. Jadi, perintah pertama dalam jawaban ini adalah menyalin dari lokal ke jarak jauh dan yang kedua adalah dari jarak jauh ke lokal . Lainnya -> https://www.postgresql.org/docs/9.6/app-pgdump.html

Ferran
sumber
28
Tidak perlu untuk file perantara - Anda dapat menggunakan terowongan SSH terkompresi atau cukup pipa: pg_dump | bzip2 | ssh "bunzip2 | pg_restore"
Kornel
4
Jika Anda menggunakan bzip2, matikan kompresi ssh untuk mempercepat transfer!
lzap
8
Bagaimana saya dapat bekerja dengan kompresi jika saya menarik data dari produksi ke dalam pengembangan? Saya telah mengatur koneksi SSH dari pengembangan menjadi produksi. Apakah itu akan terjadi ssh remoteuser@remotehost "pg_dump -C dbname | bzip2" | bunzip2 | psql dbname?
Jeromy French
2
Saya berharap bahwa Anda harus dapat menyalin basis data jarak jauh dengan nama x ke basis data lokal dengan nama y, tetapi solusi @ Ferran tidak berfungsi untuk ini ... Sepertinya saya seperti solusi porneL hanya menyisakan file bzip2 pada server, jadi itu bukan proses satu langkah. Karena itu, saya kira saya akan menjatuhkan basis data y, menggunakan bagian "atau" dari solusi Ferran yang mengembalikan x, kemudian mengubah nama basis data menjadi y.
Darin Peterson
3
Inilah yang saya lakukan: (1) pg_dump -C -h remotehost -U remoteuser x | psql -h localhost -U pengguna lokal (2) dropdb y (3) psql -U postgres -c 'ALTER DATABASE "x" RENAME TO "y"'
Darin Peterson
131
pg_dump the_db_name > the_backup.sql

Kemudian salin cadangan ke server pengembangan Anda, pulihkan dengan:

psql the_new_dev_db < the_backup.sql
lepas
sumber
3
Seseorang mengatakan kepada saya ini bisa bermasalah - masalah perizinan menyebabkan dump atau mengembalikan mati ketika menyentuh pemicu?
Robin Barnes
17
@ rmbarnes: Jika ada masalah - mereka harus diperbaiki. Tanpa pengetahuan terperinci apa yang dilakukan "Seseorang" ini - tidak ada yang dapat mengkonfirmasi atau menolak klaim ini.
4
Gunakan flag --no-owner dengan pg_dump. Ini melewatkan masalah dan edit pertama dari posting ini menggunakannya - tapi kemudian saya pikir Anda mungkin perlu kesetiaan yang lebih tepat untuk database asli.
unmount
4
Bagi saya, pendekatan di atas bekerja dengan cara berikut: pg_dump -C -h host -U username db_name> / any_directory / dump_schema_and_data_file. Dan untuk memulihkan dari file: psql -h host -U username db_name <dump_schema_and_data_file
Ali Raza Bhayani
Itu menyelamatkan saya dari banyak kesusahan. Saya menggunakan Google drive untuk memindahkan file antar mesin. Karena saya sudah memiliki database pada mesin baru (Tapi kosong) saya mendapat BANYAK kesalahan kunci duplikat. Namun, itu adalah lingkungan dev dan mereka tidak melukai apa pun.
Chris Mendla
37

Gunakan pg_dump , dan kemudian psql atau pg_restore - tergantung apakah Anda memilih opsi -Fp atau -Fc untuk pg_dump.

Contoh penggunaan:

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

sumber
22

Jika Anda ingin bermigrasi di antara versi (mis. Anda memperbarui postgres dan menjalankan 9.1 di localhost: 5432 dan 9.3 berjalan di localhost: 5434) Anda dapat menjalankan:

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

Lihat dokumen migrasi .

Eric H.
sumber
Saya ditanyai (myuser91 / postgres) -password beberapa kali, apakah ada cara agar saya hanya perlu memasukkan kata sandi?
Martin Weber
@MartinWeber Buat file, pgpass sesuai dokumen ini postgresql.org/docs/9.4/static/libpq-pgpass.html
Scott Warren
bagaimana jika mereka memiliki kedua port yang sama?
ggnoredo
Jika mereka berada di server yang berbeda, Anda dapat menggunakan -h untuk menentukan host.
Haroldo_OK
16

pg_basebackup tampaknya menjadi cara yang lebih baik untuk melakukan ini sekarang, terutama untuk database besar.

Anda dapat menyalin database dari server dengan versi utama yang sama atau lebih tua. Atau lebih tepatnya :

pg_basebackupbekerja dengan server dari versi utama yang sama atau yang lebih tua, ke 9.1. Namun, mode streaming WAL ( -X stream) hanya berfungsi dengan versi server 9.3 dan yang lebih baru, dan mode format tar ( --format=tar) dari versi saat ini hanya berfungsi dengan versi server 9.5 atau yang lebih baru.

Untuk itu Anda perlu di server sumber:

  1. listen_addresses = '*'untuk dapat terhubung dari server target. Pastikan port 5432 terbuka untuk masalah ini.
  2. Setidaknya 1 koneksi replikasi tersedia: max_wal_senders = 1( -X fetch), 2untuk -X stream(default untuk PostgreSQL 12), atau lebih.
  3. wal_level = replicaatau lebih tinggi untuk dapat diatur max_wal_senders > 0.
  4. host replication postgres DST_IP/32 trustdi pg_hba.conf. Ini memberikan akses ke pgcluster kepada siapa pun dari DST_IPmesin. Anda mungkin ingin menggunakan opsi yang lebih aman.

Perubahan 1, 2, 3 memerlukan server restart, perubahan 4 membutuhkan memuat ulang.

Di server target:

# systemctl stop postgresql@VERSION-NAME
postgres$ pg_basebackup -h SRC_IP -U postgres -D VERSION/NAME --progress
# systemctl start postgresql@VERSION-NAME
Ubah nama pengguna2701173
sumber
11
Bisakah Anda memberikan rincian lebih lanjut dalam jawaban Anda, seperti contoh?
Magnilex
7
Ini hanya berfungsi ketika kedua mesin memiliki versi PG yang sama.
sm
Kemungkinannya kecil sehingga Anda akan menggunakan versi database yang berbeda untuk pengembangan dan produksi. Terakhir kali saya melakukan percakapan yang tidak menyenangkan dengan salah satu rekan tim saya ketika dia mencoba mengirimkan masalah bahwa beberapa kode tidak berfungsi dengan PG 9.6 sementara kami menggunakan 9.5 dalam produksi pada waktu itu. Cadangan basis jauh lebih cepat. Maka pg_upgrade adalah cara untuk pergi jika diperlukan.
Zorg
2
Kemungkinannya adalah Anda ingin bermigrasi ke versi yang lebih baru, dan tidak ingin menghentikan PostgreSQL.
x-yuri
1
Kemungkinannya adalah bahwa setiap kali Anda memutakhirkan database Anda, Anda memutakhirkannya pada dev dan pementasan sebelum Anda melakukannya pada produksi.
andrew lorien
8

Jalankan perintah ini dengan nama database, Anda ingin membuat cadangan, untuk mengambil dump DB.

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

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

Sekarang scp file dump ini ke mesin jarak jauh di mana Anda ingin menyalin DB.

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

Pada mesin jarak jauh, jalankan perintah berikut di ~ / some / folder untuk mengembalikan DB.

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

 eg. psql -U postgres -d mynewdb -f mydbnamedump.sql
pengguna01
sumber
7

Saya banyak berjuang dan akhirnya metode yang memungkinkan saya untuk membuatnya bekerja dengan Rails 4 adalah:

di server lama Anda

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

Saya harus menggunakan pengguna linux postgres untuk membuat dump. Saya juga harus menggunakan -c untuk memaksa pembuatan database di server baru. --inserts memberitahukannya untuk menggunakan sintaks INSERT () yang jika tidak akan bekerja untuk saya :(

kemudian, di server baru, simpy:

sudo su - postgres
psql new_database_name < dump.sql

untuk mentransfer file dump.sql antara server saya cukup menggunakan "cat" untuk mencetak konten dan dari "nano" untuk membuatnya ulang menyalin konten.

Juga, PERAN yang saya gunakan pada dua database berbeda jadi saya harus mencari-mengganti semua nama pemilik di dump.

pastullo
sumber
6

Buang database Anda: pg_dump database_name_name > backup.sql


Impor kembali basis data Anda: psql db_name < backup.sql

MisterJoyson
sumber
5

Biarkan saya berbagi skrip shell Linux untuk menyalin data tabel Anda dari satu server ke server PostgreSQL lainnya.

Referensi diambil dari blog ini:

Linux Bash Shell Script untuk migrasi data antara Server 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"

Saya hanya memigrasi data; silakan buat tabel kosong di server database tujuan / kedua Anda.

Ini adalah skrip utilitas. Selanjutnya, Anda dapat memodifikasi skrip untuk penggunaan umum seperti dengan menambahkan parameter untuk host_name, database_name, table_name, dan lainnya

Landasan
sumber
5

Jawaban yang diterima benar, tetapi jika Anda ingin menghindari memasukkan kata sandi secara interaktif, Anda dapat menggunakan ini:

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}}
zoran
sumber