Bagaimana Anda memperbarui basis kode / basis data produksi Anda tanpa menyebabkan downtime?

42

Apa sajakah teknik untuk memperbarui basis kode / basis data server produksi tanpa menyebabkan downtime?

Olivier Lalonde
sumber
1
Pertanyaan bagus karena saya melihat begitu banyak orang mengabaikan ini. Waktu adalah uang dan waktu henti tidak pernah terlihat baik bagi pengguna akhir, terlepas dari seberapa sah alasannya.
Dan McGrath
@Dan McGrath: yang mengira Anda benar-benar dapat memiliki waktu henti, saya bekerja untuk sistem yang (biasanya) turun hanya 4 kali setahun (pemadaman seperempat) dan selama 15 menit maksimum setiap kali (selama waktu lalu lintas antrian). .. perubahan basis data sangat diperhatikan :)
Matthieu M.
2
Ini akan menjadi pertanyaan bagus untuk dba.stackexchange.com , yang masuk ke versi beta publik dalam beberapa jam.
Larry Coleman

Jawaban:

20

Secara umum, situs web yang saya kerjakan yang memiliki persyaratan semacam ini semuanya berada di belakang load-balancers, atau memiliki lokasi failover yang terpisah. Dalam sampel ini, saya akan menganggap bahwa Anda memiliki penyeimbang beban tunggal, 2 server web (A & B) dan 2 server basis data (M & N - biasanya server DB ditautkan melalui logshipping - setidaknya di dunia SQL Server ).

  1. Webserver A harus diputus dari load balancer (jadi semua traffic masuk ke B).
  2. Pengiriman log dihentikan (DB Server M akan diperbarui terlebih dahulu).
  3. Perbarui Webserver A. Arahkan konfigurasi ke DB Server M.
  4. Uji dan verifikasi bahwa pembaruan berhasil (biasanya orang langsung mengenai alamat IP).
  5. Atur load balancer sehingga sesi yang ada terus berlanjut ke B. Sesi baru masuk ke A.
  6. Tunggu semua sesi pada B kedaluwarsa (mungkin setengah jam atau lebih, biasanya kami menonton lalu lintas dan memiliki jeda istirahat 1 jam).
  7. Perbarui B dan N.
  8. Uji dan verifikasi bahwa pembaruan berhasil.
  9. Mengatur pengiriman log lagi dan mengujinya.
  10. Atur penyeimbang beban ke operasi reguler.

Dalam aplikasi web yang sangat rumit, apa yang digambarkan sebagai langkah 1-5 mungkin menghabiskan waktu semalaman dan menjadi 50 halaman Excel spreadsheet dengan waktu dan nomor kontak darurat. Dalam situasi seperti itu, memperbarui setengah sistem dijadwalkan pukul 6 sore hingga 6 pagi sambil membiarkan sistem tersedia bagi pengguna. Menangani pembaruan untuk situs DR biasanya dijadwalkan untuk malam berikutnya - hanya berharap tidak ada yang merusak hari pertama.

Dimana uptime adalah persyaratan, tambalan diuji pertama kali pada lingkungan QA, yang idealnya adalah perangkat keras yang sama dengan produksi. Jika mereka tidak menunjukkan gangguan, maka mereka dapat diterapkan pada jadwal reguler, yang biasanya pada akhir pekan.

Tangurena
sumber
7
Bagaimana Anda mengusulkan penggabungan data baru dari DB M dan DB N? Keduanya akan memiliki catatan baru, yang diperbarui dan dihapus yang tidak dimiliki pihak lain.
sixtyfootersdude
@Tururena, bisakah Anda menjawab komentar di atas?
sino
9

Untuk database biasa (Oracle misalnya) dimungkinkan untuk mengubah skema basis data saat masih menjalankan kueri secara paralel. Ini membutuhkan perencanaan ke depan.

Ada beberapa kendala agar perubahan diterapkan:

  • itu harus bekerja dengan kode yang ada, yang berarti bahwa kode tersebut harus berurusan dengan versi lama dan baru dari skema
  • seharusnya tidak menimbulkan beban pada DB bahwa transaksi akan memekik berhenti (saya melihat Anda CREATE INDEX)
  • seharusnya tidak menimbulkan kehilangan data (Anda tidak bisa menjatuhkan dan membuat ulang tabel)

Agar skema kompatibel dengan mundur, Anda biasanya dapat MENAMBAHKAN atau MEMODIFIKASI kolom, Anda hanya dapat MENGURANGI sesuatu jika kode yang ada tidak menggunakannya lagi.

Jika kode Anda tidak dapat menangani perubahan secara transparan, maka ubah kode sebelum mengubah database.

Saran sederhana untuk perencanaan ke depan: selalu jelaskan nama kolom dalam permintaan DB Anda (jangan gunakan SELECT * FROM). Dengan cara ini Anda tidak akan memiliki kolom baru muncul di permintaan lama.

Matthieu M.
sumber
1
Sebenarnya, untuk perencanaan kedepan dan kemampuan beradaptasi, pilih * dari jauh lebih baik daripada daftar kolom secara manual. Menggunakan nama kolom eksplisit menghasilkan banyak utang teknis dalam banyak kasus. Jika kode Anda rusak dari kolom baru, kode Anda sudah rusak.
Morg.
@ Maaf: Tidak juga. Untuk keamanan Anda perlu menggunakan variabel bind, yang dalam kerangka saya gunakan (setidaknya) mengharuskan menyediakan variabel untuk menulis, dan perlu ada variabel yang sama persis dengan ada kolom output, sehingga select *berarti bahwa kode rusak jika kolom baru ditambahkan (karena kurangnya variabel untuk menulisnya). Tentu saja, ini mungkin hasil dari menggunakan bahasa yang sangat diketik.
Matthieu M.
Ya benar, tidak ada keamanan tambahan dalam menghindari pilih *. Ini tidak ada hubungannya dengan bahasa yang sangat diketik dan semuanya berhubungan dengan desain yang sangat buruk. Jika kerangka kerja Anda tidak dapat menangani perubahan dengan mulus, itu tidak berguna. Ketika saya mengubah kolom, aplikasi saya tidak pernah berhenti berfungsi. Ketika Anda melakukannya istirahat. Saya tidak berpikir ada pertanyaan yang mana yang lebih dapat diandalkan atau aman.
Morg.
@Morg.: Saya gagal melihat bagaimana select *lebih dapat diandalkan dan aman. Jika dulu Anda miliki select one, two from ...maka Anda hanya menggunakan onedan two; jika thirdditambahkan ke tabel, maka Anda tidak menggunakannya (di sini), jadi tidak ada alasan untuk mengambilnya. Dan jika Anda harus menggunakannya secara tiba-tiba, maka Anda akan memodifikasi kodenya, jadi sebaiknya Anda memodifikasi kueri saat ini!
Matthieu M.
@Morg .: Ya, sepertinya kita berbicara melewati satu sama lain, mungkin karena pengalaman kita berbeda. Saya mengerjakan produk di mana kinerja adalah properti terpenting, dan ini berarti bahwa selectkebutuhan harus selektif mungkin (dan ditutupi oleh indeks) jika tidak saya bersulang (bahkan sebelum wajib bergabung). Saya minta maaf untuk mengatakan, tetapi pendekatan yang Anda gambarkan adalah kegagalan total pada produk-produk tersebut.
Matthieu M.
5

Tidak semua sistem dapat, itu harus diatur dengan cara yang mendukungnya.

Sebagai contoh, salah satu sistem utama kami yang saya bantu tingkatkan beberapa tahun lalu harus tersedia 24/7. Ini terdiri dari beberapa tingkatan, termasuk tingkatan komunikasi murni antara Lapisan Antarmuka Pengguna dan Lapisan Bisnis. Karena cara lapisan komunikasi dikodekan, setiap perubahan di masa depan untuk skema Lapisan Bisnis atau DB dapat diimplementasikan tanpa pemadaman nyata. Dalam skenario terburuk, pengguna akan mengalami jeda 10-30 detik saat perubahan mulai berlaku.

Jika perubahan itu murni perubahan kode ke lapisan bisnis, mereka bisa diantrikan dan 'bersepeda' dengan hanya penundaan milidetik.

Ini bisa dilakukan karena:

  • Lapisan komunikasi dapat menyimpan pesan. Ini memungkinkan kami untuk memiliki pemadaman yang sebenarnya pada salah satu tingkatan selain Lapisan UI tanpa harus menurunkan UI.
  • Lapisan Bisnis ditangani oleh MVDB yang disebut UniData . Ini menyimpan semua kode dalam memori. Setelah mengkompilasi kode, Anda dapat menggunakan perintah untuk memaksa kode objek baru ke dalam memori, menggantikan yang lama.

Teknik lain melibatkan replikasi transaksi ke cermin lain dari sistem yang ada. Dengan menerapkan pembaruan ke satu, beralih dan memutar ulang semua transaksi yang dilakukan antara pembaruan dan beralih. YMMV tergantung pada sistem Anda.

Dan McGrath
sumber
1

Berikut ini perspektif yang berbeda, dari dunia sistem database tertanam dan sistem embedded. Sistem yang disematkan meliputi berbagai peralatan infrastruktur jaringan / telekomunikasi, dan dalam bidang ini mereka sering berbicara tentang waktu aktif 99,999% (lima 9s).

Kami (McObject) adalah vendor dari keluarga eXtremeDB dari produk sistem basis data tertanam, termasuk Ketersediaan Tinggi eXtremeDB.

Pertama, pahami bahwa "basis data tertanam" berarti bahwa sistem basis data adalah pustaka yang dikompilasi dan dihubungkan dengan kode aplikasi Anda; dalam arti itu, "tertanam" dalam aplikasi Anda.

Dengan Ketersediaan Tinggi eXtremeDB, ada instance MASTER dari aplikasi Anda (yang mungkin satu atau beberapa proses) dan satu atau lebih instance REPLICA dari aplikasi Anda. Ketika replika membuat koneksi ke master, ia menerima salinan database master melalui proses yang disebut "sinkronisasi awal". Ini dapat dilakukan ketika aplikasi master melanjutkan pekerjaannya. Setelah disinkronkan, ia menerima transaksi master melalui replikasi. Oleh karena itu, replika selalu memiliki data saat ini dan dapat mengambil alih (melalui proses yang disebut failover) jika master gagal.

Salah satu fitur sinkronisasi awal disebut "evolusi skema biner." Dalam bahasa Inggris yang sederhana, ini berarti bahwa proses mengisi basis data replika akan mengakomodasi perbedaan antara skema basis data replika dan skema basis data master.

Dalam praktiknya, ini berarti bahwa Anda dapat membangun versi aplikasi Anda yang lebih baru (dengan tabel baru / turun, bidang baru / turun / diubah, indeks baru / turun), lampirkan versi baru aplikasi Anda ke master, dan kemudian menyebabkan replika yang lebih baru untuk menjadi master baru (yaitu memaksa failover ke replika baru sehingga menjadi master dan master lama dimatikan sendiri). Voila, Anda telah memigrasikan aplikasi Anda dari versi N ke N +1, tanpa mengganggu ketersediaan sistem Anda. Sekarang Anda dapat memutakhirkan master lama dan replika lainnya ke versi N + 1.


sumber