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.
Dampak awal: restore berhenti di tengah jalan
TEXT
ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci'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.
Alur investigasi: cek server tujuan, lalu isi dump
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 -cDEFAULT 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.
Titik temu: collation itu memang tidak ada di server tujuan
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.
Mitigasi sementara: ganti collation di salinan dump
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.sqlsed 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.
Perbaikan permanen: samakan engine dan versi server
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.