有个数据迁移的需求,需要将A数据库的数据迁移至数据库B。
我以为直接生成mysqldump脚本再跑一下就行了,但是发现并不行。
问题出在java.lang.Runtime类上。
Runtime.exec()备份MySQL数据库的问题
概括说就是,使用时应该先将指令写入一个文件,使用exec(String command)时,在具体command中执行文件。
//生成指令,指令写入文件
Process p = Runtime.getRuntime().exec("./command.sh");
//获取输入流,查看运行状态等等
解决执行指令问题后,另一个问题出现了,
[Warning] Using a password on the command line interface can be insecure.
当执行的指令中包含明文密码时,会报警告。
[Warning] Using a password on the command line interface can be insecure.
我参考了这篇文章,可以解决问题。
但是后来使用中发现其实并不影响执行指令,出于省事的角度考虑,我就把它输出到一个warn.log文件中就不管了。
贴一下主要的代码
组合mysqldump指令
public String getDumpCommand() {
StringBuilder dump = new StringBuilder();
dump.append("mysqldump -h").append(sourceIP).append(" -P").append(sourcePort).append(" -u").append(sourceUsername).append(" -p").append(sourcePassword.replace("!", "\!")).append(" -C --set-gtid-purged=OFF --databases ").append(sourceDatabase).append(" |mysql -h ").append(targetIP).append(" -P").append(targetPort).append(" -u").append(targetUsername).append(" -p").append(targetPassword.replace("!", "\!")).append(" --database ").append(targetDatabase);
return dump.toString();
}
执行update脚本
public String getimportCommand(File filePath) {
StringBuilder command = new StringBuilder();
command.append("mysql -h").append(sourceIP).append(" -P").append(sourcePort).append(" -u").append(sourceUsername).append(" -p").append(sourcePassword.replace("!", "\!")).append(" -D").append(sourceDatabase).append(" < ").append(filePath.getAbsolutePath());
return command.toString();
}
public String execCommand() {
log.info("脚本迁移启动");
long t1 = System.currentTimeMillis();
//这一行生成需要执行的指令
List command = getSpecifiedCommand();
//指令写到shell中
File shell = new File("command.sh");
if (!shell.exists()) {
try {
shell.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(shell);
bw = new BufferedWriter(fw);
for (String s : command) {
bw.write(s);
bw.newline();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fw.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
log.info("************开始执行sql脚本************");
Runtime.getRuntime().exec("chmod 777 command.sh");
Process p = Runtime.getRuntime().exec("./command.sh");
BufferedReader errorResultReader = null;
BufferedReader infoResultReader = null;
errorResultReader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
infoResultReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String infoLine;
while ((infoLine = infoResultReader.readLine()) != null) {
//log.info("脚本文件执行信息:{}", infoLine);
}
String errorLine;
while ((errorLine = errorResultReader.readLine()) != null) {
log.debug("脚本文件执行异常:{}", errorLine);
}
// 等待程序执行结束并输出状态
int exitCode = p.waitFor();
if (0 == exitCode) {
//log.info("脚本文件执行成功:" + exitCode);
} else {
//log.error("脚本文件执行失败:" + exitCode);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("************sql脚本执行结束************");
long t2 = System.currentTimeMillis();
log.info("脚本迁移结束,用时:" + (t2 - t1) + " 毫秒");
return "";
}



