Praktik terbaik untuk perubahan skema dan migrasi data ke database langsung tanpa downtime?

43

Bagaimana Anda membuat perubahan skema ke database langsung tanpa downtime?

Sebagai contoh, katakanlah saya memiliki database PostgreSQL dengan tabel termasuk berbagai data pengguna seperti alamat email dll, semua terkait dengan pengguna tertentu. Jika saya ingin memindahkan alamat email ke tabel khusus baru, saya harus mengubah skema dan kemudian memigrasikan data email ke tabel baru. Bagaimana ini bisa dilakukan tanpa berhenti menulis ke meja asli? Tentunya sementara data dituliskan dari tabel lama ke yang baru, data baru akan terus ditulis ke meja lama dan dilewatkan, bukan?

Saya kira masalah ini cukup sering muncul tetapi saya tidak dapat menemukan solusi standar untuk mengatasinya.

Artikel ini membahas masalah tetapi saya tidak benar-benar mengerti langkah 3. Dia mengatakan untuk menulis ke kedua tabel, lalu memigrasikan data lama dari tabel pertama ke yang baru. Bagaimana Anda memastikan Anda hanya memigrasi data lama?

(Saya menggunakan PostgreSQL di Heroku .)

Dan Leary
sumber
2
Facebook mengembangkan alat untuk melakukan ini untuk MySQL.
Nick Chammas
2
K. Scott Allen menulis tentang sistem untuk mengelola versi skema di sini . Saya membuat DbUpdater, alat open source untuk penyebaran skema versi sadar. Lebih lanjut di sini - http://www.tewari.info/dbupdater
ash
@NickChammas Terima kasih telah membagikannya. Saya punya banyak pertanyaan. Bisakah Anda menyarankan tutorial yang lebih rinci, video lebih disukai, yang menjelaskan hal-hal seperti bit log, indeks non clustered, dan menjawab pertanyaan-pertanyaan seperti - 1. Bagaimana memilih data dari tabel sumber ke dalam outfile mengurangi beban dibandingkan dengan menyalin ke tujuan meja secara langsung. 2. Kapan fase copy akan berakhir? Ini hanya beberapa pertanyaan yang saya miliki dan saya baru mulai membacanya.
Sandeepan Nath
@SandeepanNath - Maaf, saya tidak terlalu familiar dengan alat Facebook dan karenanya tidak dapat mengarahkan Anda ke sumber daya yang lebih banyak. Saya membaca pengumuman tentang itu dan memposting komentar saya bertahun-tahun yang lalu, tetapi saya tidak pernah menggunakannya.
Nick Chammas

Jawaban:

27

Anda hampir memiliki jawaban Anda:

  1. Buat struktur baru secara paralel
  2. Mulai menulis ke kedua struktur
  3. Migrasikan data lama ke struktur baru
  4. Hanya tulis dan baca struktur baru
  5. Hapus kolom lama

Adapun langkah 3 , gunakan sesuatu seperti ini (dalam satu transaksi):

Masukkan apa yang belum ada:

INSERT INTO new_tbl (old_id, data)
SELECT old_id, data
FROM   old_tbl
WHERE  NOT EXISTS (SELECT * FROM new_tbl WHERE new_tbl.old_id = old_tbl.old_id);

Perbarui yang telah berubah sementara itu:

UPDATE new_tbl
SET    data  = old.data
USING  old_tbl
WHERE  new_tbl.old_id = old_tbl.old_id
AND    new_tbl.data IS DISTINCT FROM old_tbl.data;

Data baru tidak akan disentuh, karena identik di kedua tempat.

Erwin Brandstetter
sumber
Saya punya beberapa pertanyaan saat mencoba memahami skenario yang Anda usulkan jawaban ini - 1. Apakah perubahan kode akan digunakan bersamaan dengan dimulainya perubahan db? 2. Mengapa ada kebutuhan untuk menulis ke kedua struktur? 3. Mengapa struktur baru tidak dapat dinaikkan terlebih dahulu dan kemudian data yang ada dimigrasikan dan kemudian perubahan kode digunakan yang akan mengisi struktur baru? 4. Mengapa ada kebutuhan untuk mencari tahu apa yang tidak ada (permintaan pertama Anda)? Apakah Anda mengusulkan penyisipan dalam beberapa upaya?
Sandeepan Nath
2
@SandeepanNath, untuk menjawab pertanyaan 3 dalam komentar Anda: karena jika Anda (a) memunculkan struktur baru, (b) memigrasikan data ke dalamnya, (c) mengubah kode Anda untuk menulis data ke struktur baru alih-alih yang lama, maka semua perubahan data yang dibuat antara langkah b dan langkah c hanya akan ada di struktur lama . Pertanyaannya adalah bagaimana membuat perubahan skema tanpa downtime. Baca jawaban ini lagi, hati-hati.
Wildcard