Cara Backup Database MySQL Otomatis di Ubuntu Server
Database merupakan salah satu komponen paling penting dalam sebuah server. Ketika database mengalami kerusakan, terhapus, atau VPS mengalami masalah, aplikasi dapat kehilangan data penting jika tidak memiliki backup.
Karena itu, backup database sebaiknya tidak dilakukan hanya ketika administrator mengingatnya. Backup dapat dibuat secara otomatis menggunakan mysqldump dan cron job di Ubuntu Server.
Dengan konfigurasi yang tepat, server dapat membuat backup MySQL secara berkala, menyimpan file backup dalam direktori tertentu, mengompresnya, serta menghapus backup lama berdasarkan kebijakan retensi.
Artikel ini membahas cara membuat sistem backup MySQL otomatis di Ubuntu Server dari awal sampai proses restore.
Kenapa Backup Database Penting?
Database dapat mengalami masalah karena berbagai alasan, misalnya:
- Human error.
- Perintah SQL yang salah.
- Database corruption.
- Disk VPS mengalami masalah.
- Aplikasi mengalami bug.
- Server terkena serangan.
- Kesalahan konfigurasi.
- Penghapusan data secara tidak sengaja.
- Kegagalan saat deployment atau maintenance.
Backup memberikan titik pemulihan ketika data utama mengalami masalah.
Production Database
│
│ backup
↓
Backup File
│
↓
Storage Backup
│
│ jika terjadi masalah
↓
Restore
│
↓
Database Pulih
Namun perlu dipahami bahwa backup yang belum pernah diuji restore bukanlah backup yang benar-benar terverifikasi.
Apa Itu mysqldump?
mysqldump adalah utility command-line yang dapat digunakan untuk membuat dump database MySQL.
Dump biasanya berisi instruksi SQL untuk membuat kembali struktur database dan memasukkan data.
Contoh sederhana:
mysqldump -u root -p nama_database > backup.sql
Setelah command dijalankan, MySQL akan meminta password.
File:
backup.sql
kemudian dapat digunakan untuk proses restore.
Memeriksa mysqldump
Pastikan utility tersedia di server:
mysqldump --version
Jika command belum tersedia, instal client MySQL sesuai sistem Ubuntu dan versi MySQL yang digunakan.
Backup Satu Database MySQL
Misalnya database aplikasi bernama:
myapp
Backup dapat dibuat menggunakan:
mysqldump -u root -p myapp > myapp.sql
File myapp.sql akan dibuat pada direktori saat command dijalankan.
Lebih baik menentukan lokasi backup secara eksplisit.
mkdir -p /var/backups/mysql
mysqldump -u root -p myapp > /var/backups/mysql/myapp.sql
Backup dengan Timestamp
Jika setiap backup menggunakan nama file yang sama, backup sebelumnya akan tertimpa.
Karena itu, kita dapat menambahkan timestamp pada nama file.
mysqldump -u root -p myapp \
> "/var/backups/mysql/myapp_$(date +%Y-%m-%d_%H-%M-%S).sql"
Contoh nama file:
myapp_2026-09-04_02-00-00.sql
Dengan demikian setiap proses backup menghasilkan file baru.
Kenapa Backup Sebaiknya Dikompresi?
File SQL hasil dump dapat berukuran besar, terutama jika database memiliki banyak data.
File tersebut dapat dikompresi menggunakan gzip.
mysqldump -u root -p myapp | gzip > myapp.sql.gz
File yang dihasilkan:
myapp.sql.gz
Ukuran file biasanya lebih kecil dibandingkan SQL dump tanpa kompresi.
Restore Backup .sql
Jika backup berupa file SQL biasa, restore dapat dilakukan menggunakan:
mysql -u root -p myapp < backup.sql
Database target harus sudah tersedia jika dump tidak berisi perintah pembuatan database.
Misalnya:
mysql -u root -p -e "CREATE DATABASE myapp;"
Kemudian:
mysql -u root -p myapp < backup.sql
Restore File .sql.gz
Jika backup dikompresi dengan gzip, file tidak harus diekstrak terlebih dahulu.
Kita dapat menggunakan:
gunzip -c backup.sql.gz | mysql -u root -p myapp
Alurnya:
backup.sql.gz
│
↓
gunzip
│
↓
SQL dump
│
↓
MySQL
│
↓
Database
Membuat User Khusus untuk Backup
Menggunakan akun root database untuk script otomatis bukan pendekatan yang ideal.
Lebih baik membuat user khusus backup dengan privilege yang diperlukan.
Contoh:
CREATE USER 'backup_user'@'localhost'
IDENTIFIED BY 'PASSWORD_KUAT';
GRANT SELECT, SHOW VIEW, TRIGGER, EVENT
ON myapp.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
Privilege yang dibutuhkan dapat berbeda tergantung struktur database, fitur MySQL yang digunakan, dan metode backup.
Untuk database production, pastikan privilege benar-benar diuji dengan proses dump sebelum automation diaktifkan.
Menyimpan Password MySQL untuk Script
Masalah yang sering muncul adalah bagaimana membuat mysqldump berjalan otomatis tanpa administrator mengetik password setiap kali.
Salah satu pendekatan adalah menggunakan MySQL client option file dengan permission yang ketat.
Contohnya file:
/root/.my.cnf
Isi sederhananya:
[client]
user=backup_user
password=PASSWORD_KUAT
host=localhost
Kemudian batasi permission:
chmod 600 /root/.my.cnf
Setelah itu command berikut dapat menggunakan credential dari file tersebut:
mysqldump myapp > backup.sql
Lokasi dan metode penyimpanan credential harus disesuaikan dengan user yang menjalankan script. Jangan membuat file credential dapat dibaca oleh user lain.
Kenapa Password Jangan Ditulis di Command?
Hindari pola seperti:
mysqldump -u backup_user -pPASSWORD myapp > backup.sql
Password dapat berisiko terekspos melalui history, proses, atau mekanisme lain tergantung environment.
Gunakan mekanisme credential yang lebih aman dan batasi permission file.
Membuat Script Backup
Daripada menulis command panjang langsung di cron, lebih mudah membuat script khusus.
Misalnya:
nano /usr/local/bin/backup-mysql.sh
Isi script:
#!/bin/bash
BACKUP_DIR="/var/backups/mysql"
DATABASE="myapp"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
BACKUP_FILE="${BACKUP_DIR}/${DATABASE}_${TIMESTAMP}.sql.gz"
mkdir -p "$BACKUP_DIR"
mysqldump "$DATABASE" | gzip > "$BACKUP_FILE"
if [ $? -eq 0 ]; then
echo "Backup berhasil: $BACKUP_FILE"
else
echo "Backup gagal"
rm -f "$BACKUP_FILE"
exit 1
fi
Kemudian jadikan executable:
chmod 700 /usr/local/bin/backup-mysql.sh
Uji secara manual:
/usr/local/bin/backup-mysql.sh
Periksa hasilnya:
ls -lh /var/backups/mysql
Menambahkan Retensi Backup
Jika backup dilakukan setiap hari tetapi file lama tidak pernah dihapus, storage VPS akhirnya dapat penuh.
Karena itu, backup membutuhkan kebijakan retensi.
Misalnya kita ingin menyimpan backup selama 7 hari.
find "$BACKUP_DIR" \
-type f \
-name "${DATABASE}_*.sql.gz" \
-mtime +7 \
-delete
Command tersebut mencari file backup yang lebih lama dari batas tertentu kemudian menghapusnya.
Retensi sebaiknya disesuaikan dengan kebutuhan aplikasi dan kapasitas storage.
Script Backup dengan Retensi
Contoh script yang lebih lengkap:
#!/bin/bash
set -u
BACKUP_DIR="/var/backups/mysql"
DATABASE="myapp"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
BACKUP_FILE="${BACKUP_DIR}/${DATABASE}_${TIMESTAMP}.sql.gz"
mkdir -p "$BACKUP_DIR"
if mysqldump "$DATABASE" | gzip > "$BACKUP_FILE"; then
echo "$(date '+%Y-%m-%d %H:%M:%S') Backup berhasil: $BACKUP_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') Backup gagal"
rm -f "$BACKUP_FILE"
exit 1
fi
find "$BACKUP_DIR" \
-type f \
-name "${DATABASE}_*.sql.gz" \
-mtime +7 \
-delete
echo "$(date '+%Y-%m-%d %H:%M:%S') Retensi backup selesai"
Perhatikan bahwa detail script production perlu disesuaikan dengan kebutuhan, versi MySQL, permission, dan strategi backup yang digunakan.
Menambahkan Logging
Backup otomatis sebaiknya memiliki log agar kita dapat mengetahui apakah proses berjalan atau gagal.
Misalnya:
LOG_FILE="/var/log/mysql-backup.log"
echo "$(date '+%Y-%m-%d %H:%M:%S') Backup dimulai" >> "$LOG_FILE"
Command backup dapat diarahkan ke log:
/usr/local/bin/backup-mysql.sh >> /var/log/mysql-backup.log 2>&1
Untuk melihat log:
tail -f /var/log/mysql-backup.log
Menjalankan Backup dengan Cron
Setelah script berjalan dengan baik secara manual, kita dapat membuat cron job.
Buka crontab:
crontab -e
Contoh menjalankan backup setiap hari pukul 02:00:
0 2 * * * /usr/local/bin/backup-mysql.sh >> /var/log/mysql-backup.log 2>&1
Format cron tersebut berarti:
0 2 * * *
│ │ │ │ │
│ │ │ │ └── Hari dalam minggu
│ │ │ └──── Bulan
│ │ └────── Hari dalam bulan
│ └──────── Jam
└────────── Menit
Dengan demikian script akan dijalankan setiap hari pada pukul 02:00.
Jangan Langsung Memasukkan Cron Sebelum Testing
Urutan yang lebih aman adalah:
- Buat script.
- Pastikan permission benar.
- Jalankan script secara manual.
- Pastikan file backup dibuat.
- Pastikan file dapat dibaca.
- Lakukan test restore.
- Baru masukkan ke cron.
Dengan cara ini, masalah dapat ditemukan sebelum automation dijalankan setiap hari.
Memeriksa Apakah Cron Berjalan
Jika backup tidak muncul sesuai jadwal, periksa service cron:
systemctl status cron
Log cron juga dapat diperiksa tergantung konfigurasi Ubuntu:
journalctl -u cron
Selain itu, periksa log yang dibuat oleh script backup.
Backup Beberapa Database
Jika VPS memiliki beberapa database, kita dapat membuat daftar database.
DATABASES=(
"app_production"
"wordpress"
"iot"
)
Kemudian melakukan dump untuk setiap database:
for DATABASE in "${DATABASES[@]}"; do
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
mysqldump "$DATABASE" \
| gzip \
> "/var/backups/mysql/${DATABASE}_${TIMESTAMP}.sql.gz"
done
Pendekatan ini cocok ketika setiap database perlu memiliki file backup terpisah.
Backup Semua Database
MySQL juga menyediakan opsi untuk melakukan dump semua database:
mysqldump --all-databases | gzip > all-databases.sql.gz
Ini dapat berguna untuk kebutuhan tertentu, tetapi untuk sistem yang memiliki banyak database, backup per database sering lebih fleksibel ketika proses restore hanya membutuhkan satu aplikasi.
Backup Struktur Database Saja
Kadang kita hanya membutuhkan struktur tabel tanpa data.
Gunakan:
mysqldump --no-data myapp > schema.sql
File tersebut berisi struktur database tanpa data.
Backup Data Tanpa Struktur
Sebaliknya, kita dapat menggunakan:
mysqldump --no-create-info myapp > data.sql
Namun untuk backup production normal, biasanya struktur dan data perlu disimpan bersama sesuai kebutuhan restore.
Transaksi dan Konsistensi Backup
Backup database production perlu memperhatikan konsistensi data.
Untuk database yang menggunakan transactional storage engine seperti InnoDB, opsi yang umum digunakan adalah:
mysqldump \
--single-transaction \
--routines \
--triggers \
--events \
myapp \
| gzip > myapp.sql.gz
--single-transaction dapat membantu membuat dump konsisten untuk tabel transactional tanpa melakukan lock global seperti pendekatan tertentu lainnya.
Namun opsi backup yang tepat tetap bergantung pada engine tabel, workload, ukuran database, dan kebutuhan recovery.
Jangan Lupa Stored Procedure, Trigger, dan Event
Data tabel bukan satu-satunya komponen database.
Database dapat memiliki:
- Stored procedure.
- Function.
- Trigger.
- Event scheduler.
- View.
Jika komponen tersebut diperlukan oleh aplikasi, pastikan metode dump yang digunakan benar-benar menyertakannya.
Backup Database Bukan Backup Server
Ini adalah perbedaan penting.
Jika kita hanya menjalankan:
mysqldump myapp > backup.sql
yang dibackup adalah database, bukan seluruh server.
File aplikasi, konfigurasi Nginx, SSL certificate, upload, environment, Docker volume, dan konfigurasi sistem tidak otomatis ikut dibackup.
Untuk server production, strategi backup dapat mencakup:
Server Backup Strategy
│
├── Database
├── Application Source
├── Upload / Storage
├── Configuration
├── SSL / Certificate
├── Docker Volume
└── Server Configuration
3-2-1 Backup Rule
Salah satu prinsip backup yang populer adalah pendekatan 3-2-1:
- 3 salinan data.
- 2 media atau lokasi penyimpanan berbeda.
- 1 salinan berada di lokasi berbeda atau off-site.
Contohnya:
Production Database
│
├── VPS Local Backup
│
├── Backup Storage
│
└── Off-site Backup
Backup lokal membantu pemulihan cepat, sedangkan backup off-site membantu ketika VPS atau storage utama mengalami masalah besar.
Jangan Hanya Menyimpan Backup di VPS yang Sama
Misalnya database berada di:
VPS
└── MySQL
dan backup juga berada di:
VPS
└── /var/backups/mysql
Jika VPS tersebut hilang atau disk mengalami kerusakan, database dan backup lokal dapat hilang bersamaan.
Karena itu, backup penting sebaiknya disalin ke storage terpisah.
Contoh Arsitektur Backup yang Lebih Aman
Production VPS
│
↓
MySQL Database
│
↓
Local Backup
│
↓
Remote Storage
│
┌─────────┴─────────┐
↓ ↓
Backup Retention Backup Monitoring
Remote storage dapat berupa server backup, object storage, atau media lain yang sesuai kebutuhan organisasi.
Backup dan Encryption
Database backup dapat mengandung data sensitif.
Jika backup disimpan di lokasi lain, pertimbangkan encryption at rest dan keamanan credential akses ke storage tersebut.
Contoh sederhana menggunakan GPG:
gpg --symmetric --cipher-algo AES256 backup.sql.gz
Perlu diperhatikan bahwa encryption hanya berguna jika key atau password juga dikelola dengan aman.
Monitoring Backup
Backup otomatis yang gagal selama berminggu-minggu tanpa diketahui merupakan masalah serius.
Karena itu, sistem backup idealnya memiliki mekanisme untuk mengetahui:
- Kapan backup terakhir berhasil.
- Ukuran backup terakhir.
- Apakah proses dump berhasil.
- Apakah storage masih tersedia.
- Apakah upload ke remote storage berhasil.
Minimal, script dapat mencatat status ke log.
Memeriksa Ukuran Backup
Periksa ukuran file:
ls -lh /var/backups/mysql
Jika ukuran backup biasanya sekitar 500 MB kemudian tiba-tiba hanya 1 KB, kondisi tersebut patut diperiksa.
Ukuran file bukan satu-satunya indikator validitas, tetapi dapat menjadi sinyal awal adanya masalah.
Test Restore Secara Berkala
Backup sebaiknya diuji restore secara berkala.
Contoh workflow:
Backup
│
↓
Copy to Test Server
│
↓
Create Test Database
│
↓
Restore
│
↓
Verify Tables
│
↓
Verify Application
Dengan test restore, kita dapat mengetahui apakah backup benar-benar dapat digunakan ketika terjadi keadaan darurat.
Contoh Prosedur Restore
Misalnya file backup:
myapp_2026-09-04_02-00-00.sql.gz
Buat database target:
mysql -u root -p -e "CREATE DATABASE myapp_restore;"
Kemudian restore:
gunzip -c myapp_2026-09-04_02-00-00.sql.gz \
| mysql -u root -p myapp_restore
Setelah selesai, periksa database:
mysql -u root -p myapp_restore
Kemudian jalankan:
SHOW TABLES;
Untuk aplikasi production, proses verifikasi dapat dilanjutkan dengan pengecekan data dan fungsi aplikasi.
Full Backup vs Incremental Backup
mysqldump umumnya digunakan untuk logical dump. Untuk database yang besar, kebutuhan backup dapat menjadi lebih kompleks.
Beberapa strategi backup antara lain:
| Strategi | Karakteristik |
|---|---|
| Logical dump | Menghasilkan representasi SQL/data yang dapat direstore |
| Physical backup | Membackup file database secara fisik |
| Incremental | Menyimpan perubahan sejak backup tertentu |
| Full backup | Menyimpan keseluruhan dataset sesuai metode yang digunakan |
Untuk database kecil hingga menengah, logical dump sering kali sudah cukup. Database yang sangat besar atau memiliki kebutuhan recovery time dan recovery point yang ketat mungkin memerlukan strategi yang lebih khusus.
Backup MySQL di Docker
Jika MySQL berjalan di Docker, konsep backup tetap sama, tetapi command dapat dijalankan melalui container.
Misalnya:
docker exec mysql-container \
mysqldump -u backup_user -p myapp \
| gzip > myapp.sql.gz
Untuk penggunaan production, credential dan pipe perlu dikonfigurasi dengan hati-hati agar password tidak terekspos.
Jika database menggunakan Docker volume, volume tersebut juga perlu dipahami dalam strategi backup.
Kesalahan Umum Backup MySQL
1. Backup Hanya Disimpan di Server yang Sama
Jika server hilang, backup dapat ikut hilang.
2. Tidak Pernah Test Restore
File backup belum tentu dapat digunakan hanya karena file tersebut berhasil dibuat.
3. Tidak Menggunakan Retensi
Backup yang menumpuk dapat memenuhi disk VPS.
4. Menggunakan Root untuk Semua Hal
Gunakan user backup dengan privilege yang sesuai.
5. Tidak Memantau Kegagalan Cron
Automation tanpa monitoring dapat gagal diam-diam.
6. Mengabaikan Data Non-Database
Upload, source code, konfigurasi, dan storage aplikasi juga dapat menjadi bagian penting dari disaster recovery.
7. Tidak Memperhitungkan Ukuran Database
Database besar membutuhkan strategi backup yang lebih matang daripada sekadar menjalankan dump setiap beberapa jam.
Contoh Checklist Backup MySQL Production
- Backup berjalan otomatis.
- Backup memiliki timestamp.
- Backup dikompresi jika sesuai kebutuhan.
- Ada retensi backup.
- Backup memiliki log.
- Backup menggunakan credential khusus.
- Permission file backup dibatasi.
- Backup disalin ke lokasi berbeda.
- Backup memiliki encryption jika diperlukan.
- Restore diuji secara berkala.
- Monitoring kegagalan tersedia.
- Kapasitas storage dipantau.
- RPO dan RTO sudah dipahami.
Memahami RPO dan RTO
Dalam disaster recovery, dua konsep penting adalah RPO dan RTO.
RPO — Recovery Point Objective
RPO menjawab pertanyaan:
Berapa banyak data yang masih dapat kita terima jika terjadi kegagalan?
Misalnya backup dilakukan setiap 24 jam. Dalam skenario terburuk, perubahan data sejak backup terakhir dapat hilang.
RTO — Recovery Time Objective
RTO menjawab pertanyaan:
Berapa lama waktu yang dapat ditoleransi sampai sistem kembali berjalan?
RPO dan RTO membantu menentukan seberapa sering backup harus dilakukan dan seberapa cepat proses restore harus dapat dilakukan.
Contoh Strategi Backup Sederhana
Untuk VPS aplikasi kecil, strategi awal dapat berupa:
Setiap hari
│
↓
mysqldump
│
↓
gzip
│
↓
Local Backup
│
↓
Remote Storage
│
↓
Retensi 7-30 hari
│
↓
Test Restore Berkala
Strategi tersebut kemudian dapat dikembangkan sesuai kebutuhan bisnis.
Kesimpulan
Backup database MySQL di Ubuntu Server sebaiknya dibuat otomatis agar tidak bergantung pada aktivitas manual administrator.
Dengan mysqldump, kita dapat membuat logical backup database. Dengan gzip, file backup dapat dikompresi. Dengan cron, proses backup dapat dijalankan secara terjadwal.
MySQL
│
↓
mysqldump
│
↓
gzip
│
↓
Backup File
│
├── Retention
├── Logging
├── Remote Copy
└── Restore Test
Hal yang paling penting bukan sekadar memiliki file backup, tetapi memastikan backup tersebut tersedia, aman, memiliki retensi yang jelas, tersimpan di lokasi berbeda, dan benar-benar dapat direstore.
Untuk server production, backup database sebaiknya menjadi bagian dari strategi disaster recovery yang lebih luas, bersama backup file aplikasi, storage, konfigurasi server, monitoring, dan prosedur pemulihan.
