MYSQL备份还原失败终极解决方法
问题是这样的:先用mysqldump -uroot -p magnetlib>magnetlib.sql备份数据库,成功。然后对magnetlib数据库中的数据记录进行修改。在还原备份的时候却失败了,不仅没有成功还原,反而把数据全删了…
用mysqldump -uroot -p magnetlib<magnetlib.sql还原数据库备份,mysql先是把原表删除,再建新表、执行Insert语句。如果在执行Insert语句的过程中遇到错误,那么最后数据库中就只剩表结构而无数据。
尝试用Source命令恢复,失败。尝试用navicat恢复,失败。但是在navicat中看到了执行的SQL语句。想起来SQL文件是由SQL语句组成的。想查看SQL文件的文本内容,记事本和notepad++都因为文件过大而大不开。最终在手机ES文件浏览器打开。
SQL文件内是多条SQL语句。添加数据的语句是INSERT INTO VALUES(…),(…)语句,且每条INSERT语句不分行。尝试复制一条INSERT语句到Idea的数据库查询控制台中,居然可以正常执行。用自己编写的代码也可以执行该INSERT语句。
对于当前只有表而没有数据的情况,可以读取SQL文件中的所有INSERT语句并执行。代码如下:
package background;
import background.connection.ConnectionPool;
import background.connection.ConnectionPoolUtils;
import java.io.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class ImportFromSQL {
/**从SQL文件导入数据
* 逐行读取,执行*/
public void importFromSQL(String pathname){
File file=new File(pathname);
if(!file.exists()||file.isDirectory())return;
try {
BufferedReader reader=new BufferedReader(new FileReader(file));
String line=null;
int index=0;
while ((line=reader.readLine())!=null){
//这里只执行修改某个表的语句
if(line.startsWith("INSERT INTO `magnets`")){
// System.out.println(line);
executeSQL(line);
System.out.println(index++);
}
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**执行一条SQL语句*/
public void executeSQL(String sql){
if(sql==null)return;
try {
statement.executeLargeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally {
}
}
Statement statement;//只用一个statement来执行,否则sql可能报内存不足错误
Connection conn;
/**初始准备:加载连接和Statement*/
void init(){
ConnectionPool cp= ConnectionPoolUtils.getPoolInstance();
conn= null;
try {
conn = cp.getConnection();
statement = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}finally {
cp.returnConnection(conn);
}
}
/**关闭数据库连接和语句*/
public void close(){
try {
statement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ImportFromSQL importFromSQL = new ImportFromSQL();
importFromSQL.init();
importFromSQL.importFromSQL("D:\\mysql\\mysql-8.0.25-winx64\\bin\\magnetlib.sql");
importFromSQL.close();
}
}
要修改的部分是获取数据库连接和语句。注意只用一个数据库语句Statement来执行,否则可能使sql报内存不足错误。(猜测sql可能是先提交给语句再执行的,创建多个Statement执行,可能会由于并行而降低执行速度)
执行完成,全部成功,并无报错,3百万条学习记录又回来了。不明白的是:为什么mysql和navicat却还原失败了…