Apakah mencadangkan database MySQL di Git adalah ide yang bagus?

57

Saya mencoba memperbaiki situasi cadangan untuk aplikasi saya. Saya memiliki aplikasi Django dan database MySQL. Saya membaca sebuah artikel yang menyarankan membuat cadangan database di Git.

Di satu sisi saya suka, karena akan menyimpan salinan data dan kode dalam sinkronisasi.

Tapi Git dirancang untuk kode, bukan untuk data. Dengan demikian akan melakukan banyak pekerjaan tambahan untuk membedakan setiap dump MySQL, yang sebenarnya tidak perlu. Jika saya mengkompres file sebelum menyimpannya, apakah git masih akan membuat file berbeda?

(File dump saat ini 100MB tidak terkompresi, 5,7MB saat di-bzip.)

Sunting: definisi skema dan basis data skema sudah ada di Git, ini benar-benar data yang saya khawatirkan untuk mencadangkan sekarang.

wobbily_col
sumber
13
Jika perusahaan Anda memiliki departemen TI, mereka harus menangani ini.
Michael Hampton
1
apakah data bagian dari aplikasi, atau apa yang dibuat melalui aplikasi?
Winston Ewert
1
Git akan mencoba untuk diff semua file ketika Anda menjalankan git gc(atau itu mendasarinya git repack; git, secara default dapat dikonfigurasi, kadang-kadang menjalankannya secara otomatis). Itu juga akan selalu mengempiskan mereka , jadi mungkin lebih baik menyimpannya tanpa kompresi.
Jan Hudec
1
Apa jenis database itu: apakah itu database produksi atau pengembangan?
el.pescado
6
viget.com/extend/backup-your-database-in-git , dia adalah "pengembang senior".
wobbily_col

Jawaban:

101

Sebelum Anda kehilangan data apa pun, izinkan saya mencoba memperkenalkan perspektif sysadmin untuk pertanyaan ini.

Hanya ada satu alasan kami membuat cadangan: untuk memungkinkan pengembalian ketika terjadi kesalahan, seperti yang selalu terjadi . Dengan demikian, sistem cadangan yang tepat memiliki persyaratan yang jauh melampaui apa yang bisa ditangani oleh git secara wajar.

Berikut adalah beberapa masalah yang dapat saya ramalkan dengan mencoba membuat cadangan database Anda di git:

  • Repositori akan tumbuh secara dramatis dengan setiap "cadangan". Karena git menyimpan seluruh objek (walaupun dikompresi) dan kemudian membedanya nanti (misalnya ketika Anda menjalankan git gc) , dan menyimpan sejarah selamanya , Anda akan memiliki sejumlah besar data yang disimpan yang sebenarnya tidak Anda butuhkan atau bahkan inginkan. Anda mungkin perlu membatasi jumlah atau periode penyimpanan cadangan yang Anda lakukan untuk menghemat ruang disk atau karena alasan hukum, tetapi sulit untuk menghapus revisi lama dari repo git tanpa banyak kerusakan jaminan.
  • Pemulihan terbatas pada titik waktu yang Anda simpan di repositori, dan karena datanya sangat besar, kembali lebih dari jumlah waktu yang sepele mungkin lambat. Sistem cadangan yang dirancang untuk tujuan membatasi jumlah data yang disimpan sekaligus berpotensi memberikan rincian lebih besar, dan memberikan pemulihan lebih cepat, mengurangi waktu henti jika terjadi bencana. Solusi pencadangan sadar-database ( contoh ) juga dapat menyediakan pencadangan berkelanjutan , memastikan tidak ada satu transaksi pun yang hilang.
  • Komit juga cenderung lambat, dan semakin lambat seiring bertambahnya basis data. Ingat bahwa git pada dasarnya adalah penyimpanan data bernilai-kunci yang dipetakan ke sistem file , dan karenanya tunduk pada karakteristik kinerja sistem file yang mendasarinya. Dimungkinkan untuk jangka waktu ini untuk akhirnya melebihi interval cadangan, dan pada saat itu Anda tidak lagi dapat memenuhi SLA Anda. Sistem pencadangan yang tepat juga membutuhkan waktu lebih lama untuk pencadangan saat data tumbuh, tetapi tidak secara dramatis, karena mereka akan secara otomatis mengelola ukurannya sendiri berdasarkan kebijakan penyimpanan yang akan Anda konfigurasi.

Terlepas dari kenyataan bahwa ternyata ada beberapa hal menarik yang dapat Anda lakukan dengan dump basis data jika Anda memasukkannya ke git, secara keseluruhan saya tidak dapat merekomendasikannya untuk tujuan menyimpan cadangan. Terutama karena sistem cadangan tersedia secara luas (dan banyak yang bahkan open source) dan bekerja jauh lebih baik dalam menjaga data Anda aman dan memungkinkan untuk pulih secepat mungkin.

Michael Hampton
sumber
Ini adalah jawaban terbaik karena Michael telah membahas masalah konsistensi. Bergantung pada ukuran dan penggunaan database, snapshot tidak dapat dipercaya mereproduksi data pada titik waktu tertentu dan Anda cenderung mengalami masalah kendala. Replikasi mungkin sesuatu yang Anda ingin tinjau - dev.mysql.com/doc/refman/5.0/en/replication.html
Aaron Newton
4
Ini bukan hanya jawaban terbaik, itu satu-satunya jawaban. Sebagai aturan umum, Anda adalah pengembang sehingga cadangan bukan bisnis Anda; orang lain (atau seharusnya) sudah merawat mereka, dan jika Anda mulai terlibat, Anda mungkin mengganggu sistem yang sudah berfungsi. Kotak-kotak ini seharusnya sudah dicadangkan, jadi Anda akan memiliki cadangan, cadangan Anda sendiri, dan cadangan cadangan Anda sendiri, semuanya dengan ukuran yang semakin meningkat. Itu hanya gila. Plus: Anda seorang pengembang: mengapa Anda (mungkin) mendekati kotak produksi?
Maximus Minimus
2
@JimmyShelter Ada aliran pemikiran bahwa DevOps tidak berarti Dev dan Ops bekerja sama secara erat, tetapi Dev itu benar - benar melakukan Ops. Biasanya tidak bekerja dengan baik, tetapi itu tidak menghentikan orang untuk mencobanya.
Michael Hampton
Ini harus menjadi jawaban yang diterima. Ini dengan jelas menjelaskan persyaratan dan tujuan sistem cadangan, kemudian menunjukkan bagaimana git tidak cocok. Poin bonus tambahan untuk diskusi konsistensi dan kinerja.
Gabriel Bauman
Izinkan saya berkomentar bahwa saya memposting jawaban saya dengan asumsi bahwa OP tidak memiliki tim Operasi yang dapat menangani masalah ini untuknya. Saya setuju dengan Anda bahwa tugas semacam ini sebaiknya diserahkan kepada mereka yang benar-benar mengoperasikan sistem, dan mengetahui jalan keluarnya. Tetapi ada situasi di mana Anda harus mengenakan topi yang bukan milik Anda, dan saya percaya dalam situasi itu lebih baik untuk mencoba mempelajari beberapa praktik terbaik daripada hanya datang dengan solusi Anda sendiri yang dibuat-buat. Saya harus mengatakan bahwa saya juga menemukan jawaban Anda sangat instruktif!
logc
39

Dua sen saya: Saya pikir itu bukan ide yang baik. GIT melakukan sesuatu seperti "menyimpan snapshot dari set file pada waktu yang berbeda", sehingga Anda dapat menggunakan GIT dengan sempurna untuk hal seperti itu, tetapi itu tidak berarti Anda harus melakukannya . GIT dirancang untuk menyimpan kode sumber, sehingga Anda akan kehilangan sebagian besar fungsinya, dan Anda akan memperdagangkan banyak kinerja hanya dengan sedikit kenyamanan.

Biarkan saya berasumsi bahwa alasan utama mengapa Anda berpikir tentang ini adalah untuk "menyimpan salinan data dan kode dalam sinkronisasi", dan bahwa ini berarti Anda khawatir bahwa versi 2.0 dari kode Anda memerlukan skema basis data yang berbeda dari versi 1.0 . Solusi yang lebih sederhana adalah dengan menyimpan skema database, sebagai satu set skrip SQL dengan CREATEpernyataan, di sepanjang kode sumber di repositori Git Anda. Kemudian, bagian dari prosedur instalasi Anda adalah untuk mengeksekusi skrip-skrip itu pada server database yang diinstal sebelumnya.

Isi sebenarnya dari CREATEtabel -d itu tidak ada hubungannya dengan versi kode sumber Anda. Bayangkan Anda menginstal perangkat lunak Anda, versi 1.0, di server A dan di server B, yang digunakan di berbagai perusahaan oleh tim yang berbeda. Setelah beberapa minggu, isi tabel akan sangat berbeda, meskipun skema persis sama.

Karena Anda ingin mencadangkan konten database, saya sarankan kepada Anda agar Anda menggunakan skrip cadangan yang menandai dump cadangan dengan versi perangkat lunak saat ini yang dimiliki oleh dump tersebut. Script harus dalam repositori GIT (sehingga memiliki akses ke string versi kode sumber), tetapi kesedihan itu sendiri tidak termasuk dalam sistem kontrol versi.

EDIT :

Setelah membaca posting asli yang memotivasi pertanyaan , saya menemukan ini ide yang lebih meragukan. Poin kuncinya adalah bahwa mysqldumpperintah mengubah keadaan saat ini dari DB menjadi serangkaian INSERTpernyataan SQL , dan GIT dapat mengubah mereka untuk mendapatkan hanya baris tabel yang diperbarui.

Bagian mysqldumpini masuk akal, karena ini adalah salah satu metode cadangan yang tercantum dalam dokumentasi MySQL. Bagian GIT adalah tempat penulis gagal memperhatikan bahwa server basis data menyimpan log transaksi untuk pulih dari kerusakan, termasuk MySQL . Hal ini menggunakan log ini , tidak GIT, bahwa Anda harus membuat backup inkremental untuk database Anda. Ini memiliki, pertama dan terpenting, keuntungan bahwa Anda dapat memutar atau menyiram log setelah pemulihan, alih-alih membengkak repositori GIT hingga tak terbatas dan di luar ...

logc
sumber
2
Saya tidak yakin saya melihat ada gunanya menyimpan skema database tanpa data dalam kontrol versi. Data adalah hal yang paling penting, dan itulah yang ingin saya buat cadangannya. Saya suka gagasan menandai cadangan basis data dengan versi perangkat lunak saat ini. Saya akan mencoba menerapkan sesuatu seperti itu.
wobbily_col
10
Inti dari menyimpan skema tanpa data adalah bahwa, tepat setelah instalasi, perangkat lunak Anda harus "siap digunakan". Jika itu adalah wiki, maka itu harus siap untuk mulai membuat halaman wiki dan menulis sesuatu ke dalamnya. Jika Anda menginstal skema dan konten, maka wiki Anda sudah diisi dengan halaman wiki X setelah instalasi ... Itu bukan "menginstal sistem wiki untuk menulis konten kami", tetapi "menyalin wiki dari suatu tempat untuk membacanya" .
logc
3
Mungkin ide yang baik untuk mengubah pertanyaan Anda dengan situasi aktual Anda. Bahkan jika Anda tidak dapat memposting semua detail, penting untuk menyatakan bahwa Anda memerlukan banyak data agar tampak tidak dimodifikasi di setiap instalasi, atau ada satu instalasi ...
logc
2
@wobbily_col Format biner berbasis non-teks memiliki nilai terbatas dalam konteks kontrol sumber. Anda tidak dapat membedakannya , Anda tidak dapat melakukan percabangan / menggabungkannya , dll. Jadi, walaupun Anda tentu BISA menggunakan git untuk menyimpan DB, kebanyakan orang lebih suka untuk skrip struktur DB serta data yang diperlukan. Ini adalah kompromi antara memiliki pekerjaan sedikit lebih banyak, tetapi memberikan daftar fitur di atas. Anda harus mempertimbangkan apakah ini adalah ide yang baik untuk solusi Anda. Kalau tidak, Anda mungkin bisa mendapatkan GIT untuk menyimpan DB secara langsung, hanya saja itu tidak cocok untuk tugas tersebut.
Daniel B
3
@ RaduMurzea: Saya pikir ini adalah pertanyaan tentang prinsip. Sistem kontrol versi dirancang untuk mengelola kode sumber, dan bukan binari, itu saja. Ini bukan masalah ukuran. Tidak, kesedihan basis data tidak boleh masuk ke dalam repositori, seperti halnya video pelatihan juga tidak harus diperiksa. Tetapi tidak ada yang menghentikan Anda untuk melakukannya. :)
logc
7

Secara pribadi, saya tidak berpikir itu ide yang baik untuk menggunakan sistem versi kontrol sumber untuk menyimpan file cadangan, karena kontrol versi GIT dirancang untuk file data, bukan untuk biner atau file dump seperti file dump cadangan MySQL. Fakta bahwa Anda dapat melakukannya bukan berarti secara otomatis Anda harus melakukannya. Selain itu, repositori Anda, mempertimbangkan cadangan basis data baru untuk setiap komit baru, akan tumbuh secara dramatis, menggunakan banyak ruang hard disk dan kinerja GIT akan terpengaruh, yang mengakibatkan sistem kontrol sumber lambat. Bagi saya tidak apa-apa untuk menjalankan strategi cadangan dan selalu menyiapkan file cadangan ketika Anda perlu mengembalikan database ketika ada sesuatu dalam kode Anda yang salah, tetapi alat kontrol sumber tidak dibuat untuk menyimpan data biner.

Untuk alasan ini, saya tidak melihat utilitas apa pun dalam menyimpan file cadangan untuk hari 1 dan untuk hari 2, dan kemudian melihat perbedaan antara dua file cadangan. Ini akan membutuhkan banyak pekerjaan ekstra dan tidak berguna. Alih-alih menggunakan GIT untuk menyimpan cadangan basis data saat Anda melakukan kode baru, simpan cadangan basis data di jalur yang berbeda, dipisahkan oleh tanggal dan waktu, dan masukkan kode Anda beberapa referensi ke cadangan basis data baru yang dibuat untuk setiap versi, menggunakan tag, sebagai seseorang yang sudah disarankan.

Catatan terakhir saya tentang backup database dan GIT: Seorang administrator database, ketika dia perlu mengembalikan database karena beberapa data telah hilang, tidak perlu memeriksa perbedaan antara file cadangan untuk hari 1 dan file cadangan untuk hari 2, dia hanya perlu tahu mana yang merupakan file cadangan terakhir yang akan memungkinkannya untuk memulihkan database, tanpa kesalahan dan kehilangan data, mengurangi waktu henti. Memang, tugas administrator database adalah membuat data tersedia untuk pemulihan sesegera mungkin, ketika sistem, karena alasan tertentu, gagal. Jika Anda menyimpan cadangan basis data di GIT, yang ditautkan dengan komit Anda, Anda tidak mengizinkan administrator basis data untuk memulihkan data dengan cepat, karena cadangan Anda terbatas pada titik waktu Anda disimpan dalam repositori GIT, dan untuk mengurangi waktu henti. dari sistem,

Kemudian, saya tidak merekomendasikan untuk menyimpan cadangan menggunakan GIT, sebagai gantinya gunakan solusi perangkat lunak cadangan yang baik (ada beberapa di sini ), yang akan memberikan lebih banyak rincian dan akan memungkinkan Anda untuk menjaga data Anda aman dan aman, dan membuat Anda pemulihan data sederhana dan cepat jika terjadi bencana.

Alberto Solano
sumber
Mungkin sang downvoter akan menjelaskan mengapa dia kalah.
Alberto Solano
1
Bukan downvoter, tapi saya pikir pendekatan ini memperkenalkan konflik penggabungan yang selalu ada yang tidak kondusif untuk alur kerja cabang — sering, gabung — sering kali lebih disukai sebagian besar pengguna git.
Daniel B
@DanielB Saya mengusulkan untuk tidak menggunakan sistem kontrol versi untuk menyimpan file cadangan database. Saya pikir masalah cadangan database dapat dengan mudah diselesaikan tanpa menggunakan sistem kontrol versi apa pun. Sistem kontrol versi (GIT, TFS, SVN dan sebagainya ..) dirancang untuk perangkat lunak, bukan membuang file atau cadangan database atau hanya untuk menyimpan data (ada banyak solusi untuk itu).
Alberto Solano
Saya pikir sebagian besar pengguna membaca beberapa kalimat pertama dan downvote, karena sepertinya Anda akan mengatakan itu ok untuk digunakan.
1
@AlbertoSolano saya melihat; tetapi membaca pertanyaan ("bisakah saya membuat cadangan DB saya di dalam GIT?") dan kemudian pernyataan pertama Anda ("tidak apa-apa untuk menyimpan file cadangan ..."), sepertinya Anda mengatakan sebaliknya. Jawabannya yang lain sepertinya mengatakan bahwa itu tidak penting, sementara saya curiga kebanyakan orang berpikir itu adalah kecelakaan kereta api yang menunggu untuk terjadi.
Daniel B
1

Anda seharusnya tidak menyimpan data biner di Git - terutama basis data.
Perubahan kode dan perubahan DML basis data adalah hal yang sangat berbeda.

MySQL dan Oracle dapat menulis log arsip untuk tujuan dipulihkan ke titik waktu mana pun. Hanya cadangan log tersebut ke tempat yang aman dan Anda akan baik-baik saja.

Untuk menggunakan Git untuk mencadangkan "arsip log" ini tidak masuk akal. Log arsip di lingkungan produksi agak berat dan harus dihapus setelah melakukan pencadangan penuh secara teratur. Juga tidak ada gunanya untuk menempatkan mereka di git - mereka sudah menjadi repositori dalam arti tertentu.

Jehy
sumber
1
mengapa seseorang tidak menggunakan Git untuk mencadangkan "arsip log" yang dibuat oleh MySQL ini?
nyamuk
1
Hanya karena itu tidak masuk akal. Log arsip di lingkungan produksi agak berat dan harus dihapus setelah melakukan pencadangan penuh secara teratur. Juga tidak ada gunanya untuk menempatkan mereka di git - mereka sudah menjadi repositori dalam arti tertentu. Michael Hampton memberikan jawaban yang cukup bagus tentang masalah ini (di halaman ini).
Jehy
1
Mengapa repot-repot memutar log, jika Anda akan menyimpan salinan semua yang ada di git? Mungkin juga hanya menyimpan satu file log monster.
wobbily_col