Migrasi Database MySQL Antar Server Tanpa Kehilangan Satu Baris pun
Migrasi database itu salah satu pekerjaan yang tidak ada toleransi untuk kesalahan. Berbeda dengan deploy kode yang kalau ada bug masih bisa di-rollback dengan cepat, data yang hilang atau korup itu dampaknya bisa permanen. Satu langkah yang terlewat bisa berujung pada downtime panjang atau, yang lebih buruk, data yang tidak bisa dipulihkan.
Saya sudah melakukan beberapa kali migrasi database, dari yang kecil (ratusan MB) sampai yang cukup besar (belasan GB). Dari semua proses itu, ada alur yang sekarang selalu saya ikuti tanpa pengecualian.
Persiapan: Jangan Terburu-buru
Sebelum menyentuh apapun, ada beberapa hal yang harus disiapkan:
1. Inventarisasi database β Tahu persis database apa saja yang ada, ukurannya, dan dependensinya:
-- Di MySQL server lama
SHOW DATABASES;
-- Cek ukuran semua database
SELECT
table_schema AS "Database",
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Ukuran (MB)"
FROM information_schema.tables
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;
-- Cek versi MySQL
SELECT VERSION();
Catat versi MySQL di server lama dan server baru. Kalau versinya berbeda (misal dari 5.7 ke 8.0), ada beberapa hal yang perlu diperhatikan terkait kompatibilitas.
2. Cek koneksi dari server baru ke server lama β kalau rencana mau transfer langsung antar server:
ping ip_server_lama
ssh user@ip_server_lama "echo 'Koneksi OK'"
Backup: Ini Wajib, Bukan Opsional
#!/bin/bash
# Backup semua database dengan opsi yang aman
TANGGAL=$(date +%Y%m%d_%H%M)
mysqldump
--user=root
--password
--all-databases
--single-transaction # konsisten tanpa lock tabel (InnoDB)
--flush-logs # flush binary log sebelum dump
--master-data=2 # catat posisi binary log (untuk replikasi)
--routines # include stored procedures dan functions
--triggers # include triggers
--events # include scheduled events
--default-character-set=utf8mb4
| gzip > backup_all_${TANGGAL}.sql.gz
echo "Backup selesai: backup_all_${TANGGAL}.sql.gz"
echo "Ukuran: $(du -sh backup_all_${TANGGAL}.sql.gz | cut -f1)"
Flag --single-transaction sangat penting untuk tabel InnoDB β memungkinkan backup konsisten tanpa harus mengunci tabel sehingga aplikasi masih bisa berjalan selama proses backup.
Transfer File ke Server Baru
Untuk file kecil (di bawah 1GB), SCP cukup:
scp backup_all_20250301_0200.sql.gz user@ip_server_baru:/home/user/
Untuk file besar, rsync lebih baik karena bisa dilanjutkan kalau koneksi terputus:
rsync -avz --progress
backup_all_20250301_0200.sql.gz
user@ip_server_baru:/home/user/
Setelah transfer selesai, selalu verifikasi integritas file dengan checksum:
# Di server lama
md5sum backup_all_20250301_0200.sql.gz
# Di server baru, bandingkan hasilnya
md5sum backup_all_20250301_0200.sql.gz
Kalau checksum-nya sama, file transfer berjalan sempurna tanpa corruption.
Restore di Server Baru
Sebelum restore, pastikan MySQL di server baru sudah dikonfigurasi dengan character set yang sama:
# Di /etc/mysql/mysql.conf.d/mysqld.cnf
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
Restart MySQL setelah perubahan konfigurasi:
sudo systemctl restart mysql
Lakukan restore:
# Restore semua database
gunzip < backup_all_20250301_0200.sql.gz | mysql -u root -p
# Atau kalau mau monitor progresnya (butuh pv terinstall)
gunzip < backup_all_20250301_0200.sql.gz | pv | mysql -u root -p
Verifikasi Setelah Restore
Ini langkah yang paling sering dilewat tapi paling krusial:
-- Bandingkan jumlah tabel
SELECT COUNT(*) as jumlah_tabel, table_schema
FROM information_schema.tables
WHERE table_schema NOT IN ("information_schema", "performance_schema", "sys", "mysql")
GROUP BY table_schema;
-- Cek beberapa tabel utama
USE nama_database;
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM posts;
SELECT MAX(created_at) FROM posts; -- pastikan data terbaru ada
-- Cek apakah ada tabel yang corrupt
CHECK TABLE users, posts, comments;
Bandingkan angka-angka ini dengan yang ada di server lama. Kalau sama, restore berhasil.
Migrasi dengan Downtime Minimal
Untuk aplikasi yang tidak boleh down lama, ada strategi yang bisa digunakan: jalankan migrasi saat traffic rendah (dini hari), dan minimalkan window downtime:
- Lakukan backup besar beberapa jam sebelumnya dan restore di server baru
- Saat siap switch, masukkan mode maintenance di aplikasi
- Backup incremental (hanya data yang berubah sejak backup besar)
- Restore incremental di server baru
- Arahkan koneksi aplikasi ke server baru
- Nonaktifkan mode maintenance
Dengan cara ini, window downtime bisa dikurangi menjadi hanya beberapa menit β cukup untuk backup incremental dan switch koneksi.
Rollback Plan
Selalu siapkan plan B sebelum mulai. Kalau setelah switch ke server baru ada masalah yang tidak bisa diselesaikan cepat, harus bisa kembali ke server lama dengan cepat. Pastikan server lama masih berjalan dan bisa dijangkau sampai yakin server baru sudah stabil.
Migrasi database yang baik itu bukan yang cepat, tapi yang aman. Tidak perlu buru-buru β yang penting setiap langkah diverifikasi sebelum lanjut ke langkah berikutnya. π
Belum ada komentar. Jadilah yang pertama menulis.
Tulis Komentar