一、故障背景
站点运行于 Movable Type 3.3,历史跨度较长(十年以上)。 在升级服务器环境(Perl 5.3 + 新版 MySQL / MariaDB)后,发现:
- 文章标题、分类、评论、TrackBack 出现乱码(如:安装笔记)
- 数据库表字符集显示为 utf8 / utf8mb3,但内容明显异常
- 后台管理界面:界面菜单正常,但博客各种内容部分都受中文乱码影响
二、问题本质分析(核心结论)
这是一个经典的历史字符集问题:
- 早期 MT 3.x + MySQL 常以
latin1方式写入数据 - 实际内容是 UTF-8(甚至混有 GBK / GB2312)
- 后期 MySQL / Perl 按 UTF-8 读取,导致“UTF-8 被当 latin1 再显示”
修复原则:
- 不修改程序逻辑:尝试修改mt-config.cgi中配置增加
DBIParams mysql_enable_utf8=0
是没有用的,改用ObjectDriver DBI::MariaDB 但Movable Type 3.3根本不支持MariaDB驱动。Got an error: Unsupported driver MT::ObjectDriver::DBI::MariaDB: Can't locate MT/ObjectDriver/DBI/MariaDB.pm in @INC (you may need to install the MT::ObjectDriver::DBI::MariaDB module) (@INC contains: /home/path/to/cgi-bin/mt/extlib lib /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.34.0 /usr/local/share/perl/5.34.0 /usr/lib/x86_64-linux-gnu/perl5/5.34 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.34 /usr/share/perl/5.34 /usr/local/lib/site_perl) at (eval 8) line 1. BEGIN failed--compilation aborted at (eval 8) line 1.
- 不整体强制转换数据库字符集
- 仅针对“人类可读字段”做字节级修复
- 修复前使用mysqldump或者phpmyadmin的工具备份数据库:mysqldump database_of_mt > mt_entry.bak.sql
三、诊断方法
1. 典型乱码特征
å æ ç é ï :
以上字符几乎可以 100% 判定为 UTF-8 被当作 latin1 显示。
2. 抽样检测 SQL
SELECT entry_id, entry_title FROM mt_entry WHERE entry_title REGEXP '[åæçéï]';
返回结果即为待修复数据。
四、通用修复方案(核心 SQL 模式)
统一采用以下安全转换模式:
CONVERT( CAST(CONVERT(column_name USING latin1) AS BINARY) USING utf8mb4 )
说明:
- latin1:还原历史错误解码
- BINARY:保留原始字节
- utf8mb4:以现代 UTF-8 重新解释
五、各主要数据表修复脚本
1. mt_entry(文章)
UPDATE mt_entry SET entry_title = CONVERT(CAST(CONVERT(entry_title USING latin1) AS BINARY) USING utf8mb4), entry_text = CONVERT(CAST(CONVERT(entry_text USING latin1) AS BINARY) USING utf8mb4), entry_text_more = CONVERT(CAST(CONVERT(entry_text_more USING latin1) AS BINARY) USING utf8mb4), entry_excerpt = CONVERT(CAST(CONVERT(entry_excerpt USING latin1) AS BINARY) USING utf8mb4), entry_keywords = CONVERT(CAST(CONVERT(entry_keywords USING latin1) AS BINARY) USING utf8mb4);
2. mt_comment(评论)
UPDATE mt_comment SET comment_author = CONVERT(CAST(CONVERT(comment_author USING latin1) AS BINARY) USING utf8mb4), comment_text = CONVERT(CAST(CONVERT(comment_text USING latin1) AS BINARY) USING utf8mb4);
3. mt_category (分类目录) / mt_tag (标签)
UPDATE mt_category SET category_label = CONVERT(CAST(CONVERT(category_label USING latin1) AS BINARY) USING utf8mb4), category_description = CONVERT(CAST(CONVERT(category_description USING latin1) AS BINARY) USING utf8mb4);UPDATE mt_tag SET
tag_name = CONVERT(CAST(CONVERT(tag_name USING latin1) AS BINARY) USING utf8mb4);
4. mt_template(模板)
UPDATE mt_template SET template_name = CONVERT(CAST(CONVERT(template_name USING latin1) AS BINARY) USING utf8mb4), template_text = CONVERT(CAST(CONVERT(template_text USING latin1) AS BINARY) USING utf8mb4);
5. mt_tbping(TrackBack ping)
UPDATE mt_tbping SET tbping_blog_name = CONVERT(CAST(CONVERT(tbping_blog_name USING latin1) AS BINARY) USING utf8mb4), tbping_title = CONVERT(CAST(CONVERT(tbping_title USING latin1) AS BINARY) USING utf8mb4), tbping_excerpt = CONVERT(CAST(CONVERT(tbping_excerpt USING latin1) AS BINARY) USING utf8mb4), tbping_junk_log = CONVERT(CAST(CONVERT(tbping_junk_log USING latin1) AS BINARY) USING utf8mb4);
6. mt_blog(博客信息)
UPDATE mt_blog SET blog_name = CONVERT(CAST(CONVERT(blog_name USING latin1) AS BINARY) USING utf8mb4), blog_description = CONVERT(CAST(CONVERT(blog_description USING latin1) AS BINARY) USING utf8mb4), blog_welcome_msg = CONVERT(CAST(CONVERT(blog_welcome_msg USING latin1) AS BINARY) USING utf8mb4);
7. mt_author(作者)
仅修以下字段,严禁修改密码 / token 字段:
UPDATE mt_author SET author_name = CONVERT(CAST(CONVERT(author_name USING latin1) AS BINARY) USING utf8mb4), author_nickname = CONVERT(CAST(CONVERT(author_nickname USING latin1) AS BINARY) USING utf8mb4), author_hint = CONVERT(CAST(CONVERT(author_hint USING latin1) AS BINARY) USING utf8mb4);
六、验证与验收
1. 乱码扫描
SELECT entry_id FROM mt_entry WHERE entry_title REGEXP '[åæçéï]';
返回 0 行表示修复完成。
2. 随机抽样
SELECT entry_id, entry_title FROM mt_entry ORDER BY RAND() LIMIT 10;
七、关于 Warning #1300 的说明
修复过程中可能出现大量:
Warning: #1300 Invalid utf8mb4 character string
这通常意味着:
- 历史数据中混有 GBK / GB2312 或垃圾字节
- 不影响前台显示
- 可安全忽略
八、最终建议
- 不要再次整体转换表字符集
- 不要尝试一键 CONVERT DATABASE
- 完成修复后立即做完整备份
至此,Movable Type 3.3 字符集乱码问题修复完成。
作者:车东 发表于:2025-12-16 11:12 最后更新于:2025-12-16 12:12版权声明:可以转载,转载时请务必以超链接形式标明文章 Movable Type 3.3 字符集乱码故障修复记录: 的原始出处和作者信息及本版权声明。
http://www.chedong.com/blog/archives/001507.html
