使用dbsake恢复.frm文件时遇到解码及字符集查找错误
问题描述
使用dbsake恢复数据表结构时,前几个文件处理正常,最后两个表报错,完整错误日志:
Uncaught exception!Error in sys.excepthook: Traceback (most recent call last): File "./dbsake/dbsake/cli/__init__.py", line 106, in handle_uncaught_exception UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 8: ordinal not in range(128) Original exception was: Traceback (most recent call last): File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main "__main__", fname, loader, pkg_name) File "/usr/lib/python2.7/runpy.py", line 72, in _run_code exec code in run_globals File "./dbsake/__main__.py", line 22, in <module> File "./dbsake/__main__.py", line 18, in main File "./dbsake/dbsake/cli/__init__.py", line 123, in main File "./dbsake/click/core.py", line 722, in __call__ File "./dbsake/click/core.py", line 697, in main File "./dbsake/click/core.py", line 1066, in invoke File "./dbsake/click/core.py", line 895, in invoke File "./dbsake/click/core.py", line 535, in invoke File "./dbsake/click/decorators.py", line 17, in new_func File "./dbsake/dbsake/cli/cmd/frm.py", line 71, in frmdump File "./dbsake/dbsake/cli/cmd/frm.py", line 26, in parse_and_print File "./dbsake/dbsake/core/mysql/frm/__init__.py", line 41, in parse File "./dbsake/dbsake/core/mysql/frm/binaryfrm.py", line 402, in parse File "./dbsake/dbsake/core/mysql/frm/binaryfrm.py", line 314, in unpack_columns File "./dbsake/dbsake/core/mysql/frm/charsets.py", line 1151, in lookup LookupError: Charset id '0' not found
解决方案
核心问题是dbsake无法识别字符集ID 0,可尝试以下方法修复:
- 指定默认字符集运行命令:在dbsake frmdump命令后添加
--charset参数,强制指定字符集,比如:
常用字符集ID对应:utf8(33)、latin1(8)、utf8mb4(45),可根据原数据库实际情况选择。dbsake frmdump --charset=utf8 /path/to/your/error_table.frm - 修改dbsake的字符集处理逻辑:找到dbsake安装目录下的
dbsake/core/mysql/frm/charsets.py,修改lookup函数,添加对ID 0的 fallback 处理:
修改后保存,重新运行dbsake命令。def lookup(self, charset_id): try: return self.charset_by_id[charset_id] except KeyError: if charset_id == 0: # 将ID 0映射为latin1(可根据需求替换为其他字符集) return self.charset_by_name['latin1'] raise LookupError("Charset id '%s' not found" % charset_id) - 手动修复frm文件:用十六进制编辑器打开报错的frm文件,定位到字符集ID的存储位置(通常在列定义的元数据区域),将值为0的字节替换为有效的字符集ID(比如0x21对应utf8,0x08对应latin1),注意操作前备份原文件。
- 换用其他工具提取表结构:如果以上方法无效,可尝试MySQL官方工具
mysqlfrm,或者Percona的frm2sql,这类工具对异常frm文件的兼容性更强。
内容的提问来源于stack exchange,提问作者SiwyJ
相关产品推荐
相关产品推荐

