PHP从SQL文件恢复数据库备份失败问题求助
搞定数据库恢复失败的问题
看起来你备份文件已经生成,但恢复环节掉链子了,我来帮你拆解下可能的原因,以及对应的排查和修复方案:
1. 先确认备份文件的基础问题
你用$_GET['restore']获取文件名,这里先打两个补丁:
- 先检查文件真的存在且可读取吗?别传了个不存在的路径:
$file = $_GET['restore']; if (!file_exists($file) || !is_readable($file)) { die('<div class="alert-box error"><span>error: </span>备份文件不存在或无法读取!</div>'); } - 再检查服务器权限:运行PHP的进程(比如Apache的
www-data用户)有没有读取这个文件的权限?可以给文件设置644权限,或者查看服务器的error log,有没有权限相关的报错。
2. 备份文件的SQL格式是否合法
mysqli_multi_query是靠分号来拆分多个SQL语句的,但你代码里用\n\n\n拆分(虽然没实际用到),这可能不是备份文件的正确分隔方式。建议你先把$fileRollback的内容复制到MySQL命令行或者phpMyAdmin里直接执行,如果执行失败,那就是备份文件本身的SQL有问题——比如:
- 多行的INSERT语句被换行拆坏了?
- mysqldump生成的特殊注释(比如
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;)导致语法错误? - 备份时的数据库版本和当前MySQL版本差异太大?
先在数据库客户端里跑一遍备份的SQL,能快速定位是不是SQL本身的锅。
3. 修复mysqli_multi_query的执行逻辑
你现在的代码只判断了第一个语句的执行结果,mysqli_multi_query执行多个语句时,必须处理完所有结果集,否则会导致连接异常,而且后续语句的错误会被忽略。改成下面的代码,能捕获到具体的错误信息:
$result = mysqli_multi_query($con2, $fileRollback); $allSuccess = true; if ($result) { do { // 释放当前查询的结果集 if ($resultSet = mysqli_store_result($con2)) { mysqli_free_result($resultSet); } // 检查下一个查询是否存在错误 if (mysqli_more_results($con2) && !mysqli_next_result($con2)) { echo('<div class="alert-box error"><span>error: </span>' . mysqli_error($con2) . '</div>'); $allSuccess = false; break; } } while (mysqli_more_results($con2)); } else { echo('<div class="alert-box error"><span>error: </span>' . mysqli_error($con2) . '</div>'); $allSuccess = false; } if ($allSuccess) { echo('<div class="alert-box success"><span>Success: </span>备份文件恢复成功!</div>'); }
这样就能看到具体是哪条SQL出了问题,而不是只知道“恢复失败”。
4. 数据库用户权限够不够?
你的$con2连接用的MySQL用户,有没有足够的权限执行备份里的所有操作?比如备份里有CREATE TABLE,用户需要CREATE权限;有INSERT需要INSERT权限;有DROP TABLE需要DROP权限。可以在MySQL命令行里执行:
SHOW GRANTS FOR '你的用户名'@'你的主机';
看看权限是否齐全。
5. 字符集不匹配也会坑人
如果备份文件的字符集和当前数据库连接的字符集不一样,可能会导致乱码或者语法错误。连接数据库后记得设置正确的字符集:
mysqli_set_charset($con2, 'utf8mb4'); // 换成你备份时用的字符集,比如utf8、gbk等
建议你先从“在数据库客户端执行备份SQL”这一步开始排查,这是最快找到问题的方法。
内容的提问来源于stack exchange,提问作者Abobaker EngIt
相关产品推荐
相关产品推荐

