Vấn đề trông như thế nào
Trước
INSERT INTO wp_posts (post_title) VALUES ('Tiếng Việt – Hà Nội');Sau
INSERT INTO wp_posts (post_title) VALUES ('Tiếng Việt – Hà Nội');Nguyên nhân từ đâu
WordPress lưu văn bản dạng UTF-8. Nhưng nhiều website cũ tạo bảng bằng latin1 hoặc kết nối bằng latin1. Miễn là việc ghi và đọc cùng sai như nhau thì không ai nhận ra. Sau khi chuyển sang máy chủ mới, xuất bằng phpMyAdmin hoặc đổi bảng mã kết nối, mọi chữ có dấu đồng loạt thành nhiều ký tự lạ.
DB_CHARSETtrongwp-config.phplàlatin1hoặc không khớp với các bảng.- File sao lưu được xuất bằng
latin1nhưng nhập bằngutf8mb4, hoặc ngược lại. - Một plugin hay script nhập liệu chuyển mã văn bản vốn đã lỗi thêm một lần nữa. Khi đó xuất hiện lỗi font hai lần.
Sửa file xuất
- Sao lưu cơ sở dữ liệu trước khi thay đổi bất cứ thứ gì.
- Xuất các bảng bị ảnh hưởng thành file
.sql, ví dụ bằng phpMyAdmin hoặcmysqldump --default-character-set=utf8mb4. - Kéo thả file vào ô phía trên. Mojibuster chỉ sửa các chỗ lỗi và hiển thị mọi thay đổi.
- Tải file đã sửa về và nhập bằng
utf8mb4vào một cơ sở dữ liệu thử nghiệm mới. - Kiểm tra website. Nếu mọi thứ đúng thì mới nhập vào cơ sở dữ liệu chính.
File sao lưu không bị tải lên. Điều này quan trọng vì nó thường chứa tài khoản người dùng, địa chỉ email và bình luận.
Cẩn thận với dữ liệu tuần tự hóa
WordPress lưu một số thiết lập trong wp_options và wp_postmeta dưới dạng giá trị PHP tuần tự hóa như s:14:"Tiếng Việt";. Con số là độ dài tính bằng byte, không phải số ký tự. Khi ệ trở lại thành ệ, độ dài không còn khớp và WordPress sẽ bỏ giá trị đó. Vì vậy hãy sửa các bảng nội dung như wp_posts, wp_comments, wp_terms trước. Với phần tùy chọn, wp search-replace của WP-CLI phù hợp hơn vì nó cập nhật cả độ dài.
Khắc phục nguyên nhân trong MySQL
- Chuyển bảng và kết nối sang
utf8mb4, đồng thời đặtdefine('DB_CHARSET', 'utf8mb4');trongwp-config.php. - Nếu cột
latin1đang chứa byte UTF-8 thì đừng chuyển đổi trực tiếp, vì như vậy sẽ bị mã hóa thêm lần nữa. Cách thường dùng là đi qua kiểu nhị phân: trước hếtMODIFY … LONGBLOB, sau đóMODIFY … LONGTEXT CHARACTER SET utf8mb4. - Luôn thử mọi thay đổi trên bản sao của cơ sở dữ liệu trước.
Câu hỏi thường gặp
Tôi có sửa được cả cơ sở dữ liệu WordPress cùng lúc không?
Có, kể cả file SQL lớn. Tuy nhiên hãy lưu ý dữ liệu tuần tự hóa trong wp_options và wp_postmeta, WP-CLI xử lý phần này tốt hơn.
Ký tự đúng trong file có bị thay đổi không?
Không. Mojibuster chỉ sửa những chuỗi rõ ràng bị lỗi. Văn bản đúng được giữ nguyên.
utf8 và utf8mb4 khác nhau thế nào?
utf8 của MySQL chỉ lưu ký tự tối đa ba byte nên emoji bị mất. utf8mb4 mới là UTF-8 đầy đủ và là lựa chọn đúng cho WordPress.
Có dùng được cho hệ thống khác ngoài WordPress không?
Có. Joomla, Drupal, Magento hoặc ứng dụng tự xây trên MySQL, MariaDB đều gặp cùng vấn đề và cùng cách sửa.