Postgres membuang hanya bagian tabel untuk snapshot dev

95

Saat diproduksi, database kami berukuran beberapa ratus gigabyte. Untuk pengembangan dan pengujian, kita perlu membuat snapshot dari database ini yang secara fungsional setara, tetapi hanya berukuran 10 atau 20 gigs.

Tantangannya adalah data entitas bisnis kita tersebar di banyak tabel. Kami ingin membuat semacam snapshot yang difilter sehingga hanya beberapa entitas yang disertakan dalam dump. Dengan begitu kami bisa mendapatkan snapshot baru setiap bulan atau lebih untuk dev dan pengujian.

Misalnya, kita memiliki entitas yang memiliki hubungan banyak ke banyak ini:

  • Perusahaan memiliki Divisi N.
  • Divisi memiliki N Karyawan
  • Karyawan memiliki N Catatan Kehadiran

Mungkin ada 1000 perusahaan, 2500 divisi, 175000 karyawan, dan puluhan juta catatan kehadiran. Kami ingin cara yang dapat direplikasi untuk menarik, katakanlah, 100 perusahaan pertama dan semua divisi, karyawan, dan catatan kehadirannya .

Saat ini kami menggunakan pg_dump untuk skema, lalu menjalankan pg_dump dengan --disable-triggers dan --data-only untuk mengeluarkan semua data dari tabel yang lebih kecil. Kami tidak ingin harus menulis skrip ubahsuaian untuk menarik sebagian data karena kami memiliki siklus pengembangan yang cepat dan khawatir skrip ubahsuaian tersebut akan rapuh dan kemungkinan kedaluwarsa.

Bagaimana kita bisa melakukan ini? Apakah ada alat pihak ketiga yang dapat membantu mengeluarkan partisi logis dari database? Apa alat ini disebut?

Saran umum apa pun juga dihargai!

Jonathan Peterson
sumber

Jawaban:

108

Pada tabel Anda yang lebih besar, Anda dapat menggunakan perintah COPY untuk menarik subset ...

COPY (SELECT * FROM mytable WHERE ...) TO '/tmp/myfile.tsv'

COPY mytable FROM 'myfile.tsv'

https://www.postgresql.org/docs/current/static/sql-copy.html

Anda harus mempertimbangkan untuk mempertahankan satu set data pengembangan daripada hanya menarik sebagian dari produksi Anda. Jika Anda menulis pengujian unit, Anda dapat menggunakan data yang sama yang diperlukan untuk pengujian, mencoba untuk mencapai semua kemungkinan kasus penggunaan.

Ben
sumber
1
Saya menggunakan teknik ini untuk sukses besar untuk melakukan hal yang sama seperti OP. Untuk uji coba, saya memuat COPY (PILIH ..) KE .. data yang dibatasi ke dalam database "template" dan menggunakan BUAT DATABASE test_run_XX TEMPLATE product_snapshot_XX. Saya tentu saja mengotak-atik data seminimal mungkin sehingga snapshot produk dimuat dan operasi pembuatan db uji cukup cepat untuk tidak menjadi penghalang tim.
Trey
5
Adakah cara untuk membuat ini berfungsi jika Anda memiliki beberapa tabel gabungan yang ingin Anda snapshotnya? COPY FROM tidak mendukung pengimporan beberapa tabel.
mlissner
1
Kaulah orangnya ... Ini membuat segalanya jadi mudah bagiku, tapi untuk tujuan berbeda. Saya menggunakannya untuk memindahkan data dari skema publik ke skema khusus pengguna dalam aplikasi multi-tenant. Terima kasih!
Jeremy F.
5
Perhatikan bahwa metode ini tidak memperbarui urutan pada tabel yang disalin sehingga penyisipan lebih lanjut dapat melanggar batasan kunci utama.
pengguna2859458
1
Aku harus menggunakan \copybukan COPYjuga, karena yang terakhir adalah superuser-satunya. Untungnya semuanya bekerja dengan sempurna tanpa perubahan lain di 9.1.
PJSCopeland
8

Saya tidak tahu tentang perangkat lunak apa pun yang sudah melakukan ini, tetapi saya dapat memikirkan 3 solusi alternatif. Sayangnya, semuanya membutuhkan beberapa pengkodean khusus.

  1. Buat ulang semua tabel dalam skema terpisah, lalu salin ke tabel tersebut hanya subset data yang ingin Anda buang, gunakan, INSERT INTO copy.tablename SELECT * FROM tablename WHERE ...dan buang itu.

  2. Tulis skrip Anda sendiri untuk membuang data sebagai pernyataan SQL. Saya telah menggunakan pendekatan ini di masa lalu dan hanya membutuhkan sekitar 20-30 baris PHP.

  3. Ubah pg_dump sehingga menerima kondisi bersama dengan -t switch saat membuang satu tabel.

Aleksander Kmetec
sumber
6

http://jailer.sourceforge.net/ melakukan ini.

Paul Legato
sumber
12
Meskipun tautan ini mungkin menjawab pertanyaan, lebih baik menyertakan bagian penting dari jawaban di sini dan menyediakan tautan untuk referensi. Jawaban link saja bisa menjadi tidak valid jika halaman tertaut berubah.
cakar
3
Itu tidak masuk akal di sini. OP meminta secara khusus nama alat pihak ketiga yang melakukan ini. Oleh karena itu, inti dari jawabannya hanyalah, "Ada alat pihak ketiga yang disebut 'Jailer' yang melakukan ini, di URL ini." Tautan itu sendiri menyediakan semua informasi penting itu; tidak ada lagi yang bisa ditambahkan. Jika tautan itu berhenti bekerja, itu dapat dengan mudah disimpulkan dari URL bahwa "program itu disebut Jailer," jadi akan berlebihan untuk menambahkannya.
Paul Legato
2
Tentu saja tautannya sekarang rusak, dan google ternyata tidak punya alternatif.
owensmartin
1
Tautan saat ini berfungsi untuk saya, dan Googling untuk "jailer postgres" juga muncul di github.com/Wisser/Jailer .
Paul Legato
8
Mungkin jika Anda menambahkan deskripsi bermanfaat tentang howAnda menggunakan alat ini, kami mungkin dapat memahami bagaimana alat ini mencapai tujuan
Bryan Ash