使用java做mysql数据迁移时遇到的两个问题

有个数据迁移的需求,需要将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指令

/**	
	 * mysqldump -h 1.1.1.1 -P3306 -uroot -proot -C --set-gtid-purged=OFF --databases db1|mysql -h 1.1.1.2 -P3306 -uroot -proot --database db1
	 *
	 * @return
	 */
	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脚本

/**
	 * 语法格式:mysql -h ip -u userName -p  -D dbName < sqlFilePath(最后没有分号)
	 * -h:数据库所在的主机。如果是本机,可以使用localhost,或者省略此项
	 * -u:连接数据库用户名
	 * -p:连接数据库密码
	 * dbName:要使用的具体的某个数据库。如果sql脚本中没有使用“use dbName”选择数据库,则此处必须定制数据库;如果使用了则和可以省略
	 * sqlFilePath : sql脚本的路径。如我将sql脚本放在了D盘,我的sql脚本的名字是”test_sql.sql”。则路径为”D:\test_sql.sql”。
	 *
	 * @return
	 */
	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<String> 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 "";
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值