Bagaimana tidak menembak diri sendiri menggunakan Liquibase

Itu tidak pernah terjadi, dan ini dia lagi!

Pada proyek selanjutnya, kami memutuskan untuk menggunakan Liquibase sejak awal untuk menghindari masalah di masa mendatang. Ternyata, tidak semua anggota tim muda tahu cara menggunakannya dengan benar. Saya melakukan lokakarya internal, yang kemudian saya putuskan untuk dijadikan artikel.

Artikel ini mencakup tips dan deskripsi bermanfaat dari tiga jebakan paling jelas yang dapat Anda alami saat bekerja dengan alat migrasi basis data relasional, khususnya Liquibase. Dirancang untuk pengembang Java tingkat Junior dan Menengah, untuk pengembang yang lebih berpengalaman mungkin menarik untuk menyusun dan mengulangi apa yang kemungkinan besar sudah diketahui.

Bagaimana tidak menembak diri sendiri menggunakan Liquibase

Liquibase dan Flyway adalah teknologi pesaing utama untuk memecahkan masalah kontrol versi struktur relasional di dunia Java. Yang pertama benar-benar gratis, dalam praktiknya lebih sering dipilih untuk digunakan, itulah sebabnya Liquibase dipilih sebagai pahlawan publikasi. Namun, beberapa praktik yang dijelaskan mungkin bersifat umum, bergantung pada arsitektur aplikasi Anda.

Migrasi relasional adalah cara paksa untuk mengatasi lemahnya fleksibilitas penyimpanan data relasional. Di era mode OOP, gaya bekerja dengan database berarti kita akan mendeskripsikan skema sekali dan tidak menyentuhnya lagi. Tetapi kenyataannya selalu ada hal-hal yang berubah, dan perubahan pada struktur tabel cukup sering diperlukan. Secara alami, prosesnya sendiri menyakitkan dan tidak menyenangkan.

Saya tidak akan mempelajari deskripsi teknologi dan instruksi untuk menambahkan perpustakaan ke proyek Anda, cukup banyak artikel yang telah ditulis tentang topik ini:

Selain itu, sudah ada artikel bagus tentang topik tip berguna:

Π‘ΠΎΠ²Π΅Ρ‚Ρ‹

Saya ingin berbagi saran dan komentar saya, yang lahir melalui keringat, darah, dan rasa sakit dalam menyelesaikan masalah migrasi.

1. Sebelum memulai, Anda harus membaca bagian praktik terbaik Online Liquidbase

Disana dijelaskan hal-hal sederhana namun sangat penting, yang tanpanya penggunaan perpustakaan dapat mempersulit hidup Anda. Misalnya, pendekatan non-struktural untuk manajemen perubahan cepat atau lambat akan menyebabkan kebingungan dan migrasi yang rusak. Jika Anda tidak meluncurkan perubahan yang saling bergantung pada struktur database dan logika layanan pada saat yang sama, maka ada kemungkinan besar hal ini akan menyebabkan tes merah atau lingkungan yang rusak. Selain itu, rekomendasi untuk menggunakan Liquibase di situs resmi berisi paragraf tentang pengembangan dan verifikasi skrip rollback bersama dengan skrip migrasi utama. Nah, di artikel itu https://habr.com/ru/post/178665/ ada contoh kode yang terkait dengan migrasi dan mekanisme rollback.

2. Jika Anda mulai menggunakan alat migrasi, jangan izinkan koreksi manual dalam struktur database

Seperti kata pepatah: "Sekali Persil, selalu Persil." Jika basis aplikasi Anda sudah mulai dikelola oleh alat Liquibase, perubahan manual apa pun secara instan menyebabkan keadaan tidak konsisten, dan tingkat kepercayaan terhadap kumpulan perubahan menjadi nol. Risiko potensial - beberapa jam dihabiskan untuk memulihkan database, dalam skenario terburuk - server mati. Jika tim Anda memiliki Arsitek DBA "jadul", dengan sabar dan penuh perhatian jelaskan kepadanya betapa buruknya jika dia hanya mengedit database dengan caranya sendiri dari Pengembang SQL bersyarat.

3. Jika set perubahan sudah dimasukkan ke repositori, hindari pengeditan

Jika pengembang lain menarik dan menerapkan set perubahan yang akan diedit nanti, dia pasti akan mengingat Anda dengan kata-kata yang baik ketika menerima kesalahan saat memulai aplikasi. Jika mengedit changeset entah bagaimana bocor ke dalam pengembangan, Anda harus menuruni kemiringan hotfix yang licin. Inti dari masalah terletak pada validasi perubahan dengan jumlah hash - mekanisme utama Liquibase. Saat mengedit kode set perubahan, jumlah hash berubah. Mengedit kumpulan perubahan hanya mungkin jika memungkinkan untuk menyebarkan seluruh database dari awal tanpa kehilangan data. Dalam hal ini, pemfaktoran ulang kode SQL atau XML, sebaliknya, dapat membuat hidup lebih mudah, membuat migrasi lebih mudah dibaca. Contohnya adalah situasi ketika, pada awal aplikasi, skema database sumber dikoordinasikan di dalam tim.

4. Memiliki backup database yang terverifikasi jika memungkinkan

Di sini, saya pikir, semuanya jelas. Jika tiba-tiba migrasi tidak berhasil, semuanya dapat dikembalikan. Liquibase memiliki alat rollback, tetapi skrip rollback juga ditulis oleh pengembangnya sendiri, dan mereka dapat mengalami masalah dengan kemungkinan yang sama seperti pada skrip set perubahan utama. Ini berarti bermain aman dengan cadangan berguna dalam hal apa pun.

5. Gunakan cadangan basis data terverifikasi dalam pengembangan jika memungkinkan

Jika ini tidak bertentangan dengan kontrak dan privasi, tidak ada data pribadi di database, dan beratnya tidak seperti dua matahari - sebelum menerapkannya di server migrasi langsung, Anda dapat memeriksa cara kerjanya di mesin pengembang dan menghitung hampir 100% potensi masalah selama migrasi.

6. Ngobrol dengan pengembang lain di tim

Dalam proses pengembangan yang terorganisir dengan baik, semua orang di tim tahu siapa melakukan apa. Pada kenyataannya, seringkali tidak demikian, oleh karena itu, jika Anda sedang mempersiapkan perubahan dalam struktur database sebagai bagian dari tugas Anda, disarankan untuk memberi tahu seluruh tim tentang hal ini. Jika seseorang membuat perubahan secara paralel, Anda harus mengaturnya dengan hati-hati. Penting untuk berkomunikasi dengan rekan kerja bahkan di akhir pekerjaan, tidak hanya di awal. Banyak masalah potensial dengan kumpulan perubahan dapat diselesaikan pada tahap tinjauan kode.

7. Pikirkan apa yang Anda lakukan!

Nasihat yang tampaknya terbukti dengan sendirinya berlaku untuk situasi apa pun. Namun, banyak masalah dapat dihindari jika pengembang sekali lagi menganalisis apa yang dia lakukan dan apa pengaruhnya. Bekerja dengan migrasi selalu membutuhkan perhatian dan ketelitian ekstra.

Perangkap

Sekarang mari kita lihat jebakan tipikal yang dapat membuat Anda jatuh jika Anda tidak mengikuti saran di atas, dan apa sebenarnya yang harus dilakukan?

Situasi 1. Dua pengembang sedang mencoba menambahkan kumpulan perubahan baru pada saat yang bersamaan

Bagaimana tidak menembak diri sendiri menggunakan Liquibase
Vasya dan Petya ingin membuat set perubahan versi 4 tanpa mengetahui satu sama lain. Mereka membuat perubahan pada struktur database, dan meluncurkan permintaan penarikan, dengan file set perubahan yang berbeda. Mekanisme berikut diusulkan di bawah ini:

Bagaimana menyelesaikan

  1. Entah bagaimana, kolega harus menyetujui urutan perubahan yang harus dilakukan, katakanlah Petin harus diterapkan terlebih dahulu.
  2. Satu orang harus menuangkan yang lain dan menandai set perubahan Vasya dengan versi 5. Ini dapat dilakukan melalui Cherry Pick atau penggabungan yang rapi.
  3. Setelah perubahan, pastikan untuk memeriksa validitas tindakan yang diambil.
    Bahkan, mekanisme Liquibase akan memungkinkan Anda untuk memiliki dua set perubahan versi 4 di repositori, sehingga Anda dapat membiarkan semuanya apa adanya. Artinya, Anda hanya akan memiliki dua revisi versi 4 dengan nama berbeda. Dengan pendekatan ini, versi database menjadi sangat sulit dinavigasi nantinya.

Selain itu, Liquibase, seperti rumah para hobbit, menyimpan banyak rahasia. Salah satunya adalah kunci validCheckSum, yang telah muncul sejak versi 1.7 dan memungkinkan Anda menentukan nilai hash yang valid untuk kumpulan perubahan tertentu, terlepas dari apa yang disimpan dalam database. Dokumentasi https://www.liquibase.org/documentation/changeset.html mengatakan sebagai berikut:

Tambahkan checksum yang dianggap valid untuk set perubahan ini, terlepas dari apa yang disimpan di database. Digunakan terutama ketika Anda perlu mengubah changeSet dan tidak ingin kesalahan terjadi pada database yang telah dijalankan (bukan prosedur yang disarankan)

Ya, ini tidak disarankan. Namun terkadang pesulap cahaya yang kuat juga menguasai teknik gelap.

Kasus 2: Migrasi berbasis data

Bagaimana tidak menembak diri sendiri menggunakan Liquibase

Katakanlah Anda tidak dapat menggunakan cadangan basis data dari server langsung. Petya membuat kumpulan perubahan, mengujinya secara lokal, dan dengan keyakinan penuh bahwa dia benar, membuat permintaan tarik ke pengembang. Untuk berjaga-jaga, pemimpin proyek mengklarifikasi apakah Petya memeriksanya, lalu menuangkannya. Tetapi penerapan di server pengembangan telah gagal.

Nyatanya, ini mungkin, dan tidak ada yang kebal dari ini. Ini terjadi jika modifikasi struktur tabel terkait dengan data tertentu dari database. Tentunya, jika database Petya hanya diisi dengan data uji, mungkin tidak mencakup semua kasus masalah. Misalnya, saat menghapus tabel, ternyata ada record di tabel lain oleh Foreign Key yang terkait dengan record di tabel yang dihapus. Atau saat mengganti tipe kolom ternyata tidak 100% data bisa dikonversi ke tipe baru.

Bagaimana menyelesaikan

  • Tulis skrip khusus yang akan diterapkan sekali bersamaan dengan migrasi dan bawa data ke dalam bentuk yang tepat. Ini adalah cara umum untuk menyelesaikan masalah transfer data ke struktur baru setelah menerapkan migrasi, tetapi hal serupa dapat diterapkan sebelumnya, dalam kasus khusus. Jalur ini tentu saja tidak selalu tersedia, karena mengedit data di live server bisa berbahaya bahkan fatal.
  • Cara rumit lainnya adalah mengedit kumpulan perubahan yang ada. Kesulitannya adalah bahwa semua database yang telah diterapkan dalam bentuk yang ada harus dipulihkan. Sangat mungkin bahwa seluruh tim backend akan dipaksa untuk menggulung database secara lokal dari awal.
  • Dan cara paling universal adalah mentransfer masalah data ke lingkungan pengembang, membuat ulang situasi yang sama dan menambahkan set perubahan baru, ke yang rusak, yang akan mengatasi masalah.
    Bagaimana tidak menembak diri sendiri menggunakan Liquibase

Secara umum, semakin banyak basis data yang komposisinya mirip dengan basis data server produksi, semakin kecil kemungkinan masalah dengan migrasi akan berlanjut. Dan, tentu saja, sebelum Anda mengirim set perubahan ke repositori, Anda harus berpikir beberapa kali apakah itu akan merusak sesuatu.

Situasi 3. Liquibase mulai digunakan setelah diproduksi

Misalkan pemimpin tim meminta Petya untuk memasukkan Liquibase ke dalam proyek, tetapi proyek tersebut sudah dalam produksi dan struktur database sudah ada.

Oleh karena itu, masalahnya adalah pada server atau mesin pengembang baru mana pun, data tabel harus dibuat ulang dari awal, dan lingkungan yang sudah ada harus tetap dalam keadaan konsisten, siap menerima set perubahan baru.

Bagaimana menyelesaikan

Ada juga beberapa cara:

  • Yang pertama dan paling jelas adalah memiliki skrip terpisah yang harus diterapkan secara manual saat menginisialisasi lingkungan baru.
  • Yang kedua, kurang jelas, adalah memiliki migrasi Liquibase yang berada dalam Konteks Liquibase yang berbeda dan menerapkannya. Anda dapat membaca lebih lanjut tentang Konteks Liquibase di sini: https://www.liquibase.org/documentation/contexts.html. Secara umum, ini adalah mekanisme menarik yang dapat diterapkan dengan sukses, misalnya untuk pengujian.
  • Jalur ketiga terdiri dari beberapa langkah. Pertama, migrasi harus dibuat untuk tabel yang sudah ada. Kemudian itu harus diterapkan pada beberapa lingkungan dan dengan demikian jumlah hashnya akan diperoleh. Langkah selanjutnya adalah menginisialisasi tabel Liquibase kosong di server kami yang tidak kosong, dan Anda dapat secara manual memasukkan catatan set perubahan "seolah diterapkan" dengan perubahan yang sudah ada di database ke dalam tabel dengan riwayat penerapan set perubahan. Jadi, pada server yang sudah ada, riwayat akan dimulai dari versi 2, dan semua lingkungan baru akan berperilaku sama.
    Bagaimana tidak menembak diri sendiri menggunakan Liquibase

Skenario 4: Migrasi menjadi sangat besar dan tidak dapat mengikuti

Pada awal pengembangan layanan, sebagai aturan, Liquibase digunakan sebagai ketergantungan eksternal, dan semua migrasi diproses saat aplikasi dimulai. Namun, seiring waktu, Anda mungkin menemukan kasus-kasus berikut:

  • Migrasi menjadi sangat besar dan membutuhkan waktu lama untuk diselesaikan.
  • Ada kebutuhan untuk bermigrasi di lingkungan terdistribusi, misalnya, pada beberapa instance server database secara bersamaan.
    Dalam hal ini, menerapkan migrasi terlalu lama akan mengakibatkan waktu tunggu habis saat aplikasi dimulai. Selain itu, menerapkan migrasi pada basis per contoh aplikasi dapat mengakibatkan server yang berbeda berada dalam keadaan tidak sinkron.

Bagaimana menyelesaikan

Dalam kasus seperti itu, proyek Anda sudah besar, bahkan mungkin orang dewasa, dan Liquibase mulai bertindak sebagai alat eksternal yang terpisah. Faktanya adalah bahwa Liquibase, sebagai perpustakaan, dirangkai menjadi file jar, dan dapat berfungsi sebagai ketergantungan dalam proyek, serta mandiri.

Offline, Anda dapat meninggalkan aplikasi migrasi ke lingkungan CI/CD Anda atau ke bahu kuat sysadmin/deployer Anda. Untuk melakukan ini, Anda memerlukan baris perintah Liquibase https://www.liquibase.org/documentation/command_line.html. Dalam mode ini, dimungkinkan untuk meluncurkan aplikasi setelah semua migrasi yang diperlukan telah selesai.

Keluaran

Faktanya, masih banyak lagi jebakan saat bekerja dengan migrasi basis data, dan banyak di antaranya memerlukan pendekatan kreatif. Penting untuk dipahami bahwa jika Anda menggunakan alat ini dengan benar, sebagian besar jebakan ini dapat dihindari. Secara khusus, saya harus menghadapi semua masalah yang terdaftar dalam berbagai bentuk, dan beberapa di antaranya adalah akibat dari tiang tembok saya. Pada dasarnya, ini terjadi, tentu saja, karena kurangnya perhatian, tetapi terkadang karena ketidakmampuan kriminal untuk menggunakan alat tersebut.

Sumber: www.habr.com

Tambah komentar