技巧教程 备份导出后在导入恢复备份时数据丢失的可能解决方法

  • 欢迎 游客 您的光临,下载之前请先阅读 积分规则(暂行) 。任何技术问题请在论坛提问,本站定制插件、模板主题售前、售后问题请联系QQ:5916171
UID
446
注册
2019/10/02
消息
7
反馈评分
0
黄金
2,302.9G
    Windows 10 Chrome 88.0.4324.190
  • #1
由于fullUnicode选项貌似是默认打开的,如果数据库使用UTF-8编码,在备份的时候,部分内容可能乱码,导致数据库插入语句无效,造成数据丢失

解决方法是修改数据库排序规则为utf8mb4_general_ci

官方说明文档: https://xenforo.com/docs/xf2/unicode/




以下内容为具体分析

# 商业转载请联系作者获得授权,非商业转载请注明出处。
# For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.
# 协议(License):署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
# 作者(Author):Rayzggz
# 链接(URL):https://blog.ranfu.net/archives/391

# 来源(Source):Roy's Blog

分析

由于辣鸡宝塔的数据库导入导出都没有返回任何报错信息,所以最开始采用Navicat进行读取,使用Navicat的导出导入,由此得到以下测试结果

宝塔导出Mysqldump命令导出Navicat导出
宝塔导入导入报错、数据丢失导入报错、数据丢失正常
Mysqldump命令导入导入报错、数据丢失导入报错、数据丢失正常
Navicat导入导入报错、数据丢失导入报错、数据丢失正常




通过翻阅宝塔源码文件
代码:
/www/server/panel/class/database.py
可得知,宝塔使用的备份指令为
代码:
--default-character-set="+ public.get_database_character(name)
由此可以发现与命令备份指令相同,推测应该不是宝塔导出的问题,而且命令本身有问题。通过查阅相关资料,也并没有发现此备份命令有不当之处。



虽然从逻辑分析,应该是导出问题,但是由于导出没有任何报错,所有只能转向导出的报错提示
代码:
ERROR 1062 (23000) at line 106: Duplicate entry '???'; for key 'username'
代码:
ERROR 1062 (23000) at line 109: Duplicate entry '?????' for key 'username'
通过查阅谷歌,发现以下出现同样问题的人
根据回复,应该是编码问题,但是米坛社区一直使用utf-8编码,从未使用过GBK等中文编码,应该不存在此问题,而且这也无法解释为什么会导致大量数据丢失,因为不可能人人都错误的使用GBK编码作为用户名注册。



由此,只能针对备份出来的SQL文件进行分析,通过对比原数据库和丢失数据了的测试服务器数据库,发现都在命令导出的SQL文件中,丢失的数据都位于同一个 INSERT INTO 语句,因为语句出错,导致整条 INSERT INTO 语句无法正常执行,只能跳过, INSERT INTO 语句中所有用户数据都没被成功导入。


由于 INSERT INTO 语句过长,有大概3000条用户信息,所有只能在原数据库一条条查看可疑的可能导致乱码的用户名,最后找到了两个使用emoji的用户名,并且在命令导出的sql文件中,这两个用户的用户名都乱码了,使用Navicat导出的由于软件正确识别,正常的写入了文件,所以一切正常。


归因

通过查阅资料,MySQL如果使用普通的UTF-8编码,是无法储存emoji的,xenforo提供了
代码:
$config['fullUnicode'] = true;
选项来解决此问题,此选项是默认开启的,但是当初在使用宝塔创建数据库的时候,并不知道有这个限制,整个数据库使用了默认的UTF-8编码,而事实上应该使用UTF-8mb4,xenforo又自动的在创建表的使用UTF-8mb4进行了储存,所以emoji被正常储存了。但是宝塔在备份时使用了参数 --default-character-set="+ public.get_database_character(name)这导致备份输出使用了UTF-8,所有的emoji数据乱码,数据丢失。


所有这个问题就是在 xenforo没有检测直接使用UTF-8mb4 + 宝塔默认没有使用兼容性更好的UTF-8mb4 + 宝塔导入数据库不返回报错 的多重因素下产生了


解决


解决方法也很简单,直接修改数据库排序规则为 utf8mb4_general_ci 即可



参考资料:
https://xenforo.com/docs/xf2/unicode/
https://www.v2ex.com/t/60317
 
打赏用户:
死了算了

死了算了

管理成员
CNXFans
UID
1
注册
2017/07/28
消息
1,145
解决方案
26
反馈评分
5,191
黄金
58,430.3G
 
最后编辑:
购买收费内容用户: