Bali, Indonesia
Insights

Restore Gagal karena Unknown collation utf8mb4_0900_ai_ci, Edit Dump atau Ganti Server?

November 1, 2026
0:00
Dump dari server MySQL 8 di-restore ke server lain, lalu prosesnya berhenti dengan pesan Unknown collation: 'utf8mb4_0900_ai_ci'. Kasus ini sering muncul saat pindah hosting, saat restore ke VPS yang memakai MariaDB, atau saat developer menarik database produksi ke mesin lokal yang servernya lebih lama. Pertanyaan berikutnya hampir selalu sama: cukup ganti teks collation di file dump, atau server tujuannya yang perlu diganti? Jawabannya tergantung isi data dan seberapa besar aplikasi bergantung pada cara string dibandingkan. Artikel ini disusun seperti post-mortem: dampak awal, alur investigasi, titik temu penyebab, mitigasi sementara, lalu perbaikan permanen. Ini bukan cerita insiden tertentu, melainkan pola yang umum terjadi.
Gejalanya biasanya seperti ini (contoh format output):
TEXT
ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci'
Collation adalah aturan yang dipakai database untuk membandingkan dan mengurutkan string. Aturan ini menentukan apakah huruf besar dan kecil dianggap sama, apakah e sama dengan é, dan bagaimana spasi di akhir teks diperlakukan. Setiap tabel dan kolom teks punya collation, dan nama collation itu ikut tertulis di file dump. Yang sering terlewat: client mysql secara default berhenti di error pertama. Tabel yang posisinya sebelum baris error sudah terbentuk, sisanya belum. Hasilnya database setengah jadi. Website bisa terlihat hidup di halaman tertentu, lalu error di halaman lain karena tabelnya tidak ada. Opsi --force memang membuat restore jalan terus, tapi tabel yang gagal tetap tidak dibuat dan data untuk tabel itu juga gagal masuk. Jadi --force bukan solusi, justru menyembunyikan masalah.
Langkah pertama adalah memastikan server tujuan memang tidak mengenal collation tersebut, lalu melihat collation apa saja yang dipakai di dump. Dua-duanya read-only dan aman dijalankan.
BASH
# Versi dan engine server tujuan (MySQL atau MariaDB terlihat dari string versinya)
mysql -e 'SELECT VERSION();'

# Collation utf8mb4 yang dikenal server tujuan, perhatikan juga kolom Pad_attribute
mysql -e "SHOW COLLATION LIKE 'utf8mb4%';"

# Collation keluarga 0900 yang muncul di dump, beserta jumlahnya
grep -o 'utf8mb4_0900_[a-z_]*' dump.sql | sort | uniq -c

# Kalau dump dikompres gzip
zcat dump.sql.gz | grep -o 'utf8mb4_0900_[a-z_]*' | sort | uniq -c
Di dalam dump, nama collation bisa muncul di beberapa tempat: di definisi tabel (DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci), di level kolom, di header SET NAMES, dan di blok pembuka trigger, view, atau stored routine yang menyimpan collation_connection. Bagian terakhir ini sering lupa dicek. Tabelnya sudah beres, tapi restore tetap gagal di trigger. Kalau hasil grep hanya menunjukkan utf8mb4_0900_ai_ci, situasinya relatif sederhana. Kalau ada varian lain seperti _as_cs (peka aksen dan huruf besar-kecil) atau _bin, berarti ada kolom yang sengaja dibuat dengan aturan perbandingan berbeda. Varian itu butuh pengganti yang dipilih satu per satu, bukan disamaratakan. Di support hosting, pertanyaan pertama yang perlu ditanyakan ke pemilik situs biasanya sederhana: dump ini berasal dari server apa, dan mau di-restore ke server apa. Banyak kebingungan selesai di situ.
utf8mb4_0900_ai_ci adalah default collation untuk utf8mb4 di MySQL 8.0. Angka 0900 merujuk ke Unicode Collation Algorithm versi 9.0.0, ai berarti accent-insensitive, dan ci berarti case-insensitive. MySQL 5.7 tidak mengenal collation ini. MariaDB juga tidak mewarisinya, karena sejak berpisah dari MySQL, MariaDB mengembangkan jalurnya sendiri, termasuk collation berbasis UCA yang lebih baru seperti utf8mb4_uca1400_ai_ci di versi-versi barunya. Beberapa rilis MariaDB terbaru dilaporkan menambahkan alias kompatibilitas untuk nama 0900, jadi jangan mengandalkan asumsi. Cek langsung lewat SHOW COLLATION di server kamu. Yang penting dipahami: masalahnya bukan cuma soal nama. Perilakunya juga berbeda di dua hal. Pertama, soal spasi di akhir string. Collation keluarga 0900 bersifat NO PAD, artinya 'abc' dan 'abc ' (dengan spasi di belakang) dianggap berbeda. Collation lama seperti utf8mb4_unicode_ci dan utf8mb4_general_ci bersifat PAD SPACE, sehingga keduanya dianggap sama. Kolom Pad_attribute di output SHOW COLLATION menunjukkan sifat ini. Kedua, soal urutan dan kesetaraan karakter. utf8mb4_unicode_ci berbasis UCA 4.0.0, jauh lebih tua dari 9.0.0. Untuk teks Latin biasa seperti nama produk atau artikel berbahasa Indonesia, perbedaannya umumnya kecil. Untuk emoji, aksara non-Latin, atau karakter yang ditambahkan ke Unicode belakangan, urutan dan hasil perbandingannya bisa berbeda.
Mengedit dump cukup aman kalau datanya didominasi teks Latin, aplikasi tidak bergantung pada urutan sorting yang sangat spesifik, dan tidak ada unique index yang membedakan nilai hanya dari spasi di akhir. Situs WordPress dan aplikasi web pada umumnya biasanya masuk kategori ini. Pilih pengganti yang ada di server tujuan. utf8mb4_unicode_ci tersedia di MySQL 5.7 dan MariaDB, jadi itu pilihan aman secara kompatibilitas. Kalau server tujuan adalah MariaDB versi baru yang punya utf8mb4_uca1400_ai_ci, collation itu lebih dekat ke perilaku Unicode modern. utf8mb4_general_ci lebih sederhana dan kurang akurat untuk banyak karakter, jadi biasanya bukan pilihan pertama.
BASH
# Kerjakan di salinan, file dump asli tetap utuh sebagai cadangan
sed 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' dump.sql > dump-fixed.sql

# Pastikan tidak ada varian 0900 lain yang tersisa (hasil 0 berarti bersih)
grep -c 'utf8mb4_0900' dump-fixed.sql

# Uji dulu ke database kosong, jangan langsung ke database produksi
mysql nama_db_uji < dump-fixed.sql
Perintah sed di atas tidak mengubah file asli, tapi butuh ruang disk kira-kira sebesar dump itu sendiri. Untuk dump yang sangat besar, cek dulu sisa ruang disk. Perlu diingat juga bahwa sed mengganti teks di mana pun, termasuk di dalam data. Kalau ada baris data yang kebetulan berisi string utf8mb4_0900_ai_ci (misalnya artikel dokumentasi tentang MySQL), isinya ikut berubah. Kasusnya jarang, tapi bisa terjadi. Setelah restore uji berhasil, ada tiga risiko yang perlu dicek sebelum dipakai di produksi. Yang pertama adalah Duplicate entry saat pembuatan unique index. Karena pindah dari NO PAD ke PAD SPACE, dua nilai yang dulu dianggap berbeda hanya karena spasi di akhir sekarang dianggap sama, sehingga index gagal dibuat. Kalau error ini muncul, data perlu dibersihkan dulu, dan keputusan mana yang dipertahankan sebaiknya diambil bersama pemilik aplikasi. Yang kedua adalah Illegal mix of collations. Error ini muncul kalau sebagian tabel sudah diganti sementara yang lain belum, atau kalau koneksi aplikasi memaksa collation tertentu. Di WordPress misalnya, cek nilai DB_COLLATE di wp-config.php. Kalau isinya masih menyebut collation 0900, query bisa gagal walaupun restore-nya sukses. Yang ketiga adalah urutan hasil query. Fitur seperti daftar nama yang diurutkan, pencarian, atau pengecekan username unik bisa memberi hasil sedikit berbeda dari server lama. Coba beberapa halaman yang memakai sorting dan pencarian, jangan hanya cek halaman depan.
Mengedit dump adalah tambalan. Itu masuk akal untuk satu kali migrasi situs kecil, tapi kurang tepat dalam beberapa kondisi: aplikasi bergantung pada perilaku perbandingan string (misalnya kolom case-sensitive atau aturan unik yang ketat), database besar dengan banyak tabel dan routine, atau data yang akan bolak-balik dipindah antara dua server. Dalam kondisi seperti itu, setiap restore jadi proses manual yang rawan salah. Perbaikan yang lebih rapi adalah menyamakan engine dan versi mayor di semua tempat database itu bisa mendarat: produksi, staging, server cadangan, dan lingkungan development. Kalau produksi memakai MySQL 8, server tujuan restore sebaiknya juga MySQL 8, bukan MariaDB atau MySQL 5.7. Dengan begitu dump bisa di-restore apa adanya, dan perilaku sorting serta perbandingan tetap sama. Kalau migrasi ke engine lain memang disengaja, misalnya pindah ke MariaDB, perlakukan itu sebagai proyek tersendiri. Tentukan collation target, uji konversi di staging, cek index unik dan query yang bergantung pada sorting, lalu baru jalankan migrasi. Collation hanyalah salah satu perbedaan. Dump dari MySQL 8 bisa memuat fitur lain yang tidak didukung atau diperlakukan berbeda di MariaDB. Pelajaran yang paling sering terlewat: backup yang tidak pernah diuji restore ke server tujuan sebenarnya belum terbukti bisa dipakai. Error collation ini biasanya baru ketahuan saat restore benar-benar dibutuhkan. Pembahasan lebih lengkap soal ini ada di Why a Successful Backup Job Does Not Guarantee a Working Database Restore. Aturan praktisnya: kalau datanya teks biasa dan ini restore satu kali, ganti collation di salinan dump, uji ke database kosong, lalu cek unique index, DB_COLLATE atau setting koneksi sejenis, dan beberapa halaman yang memakai sorting. Kalau aplikasinya sensitif terhadap perbandingan string atau database ini akan terus dipindah-pindah, jangan tambal dump-nya. Samakan engine dan versi servernya, lalu jadwalkan uji restore rutin supaya masalah seperti ini ketahuan sebelum benar-benar dibutuhkan.