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却还原失败了…