【问题标题】:Restoring Mysql dump from java: why does it hang the process?从java恢复Mysql转储:为什么它会挂起进程?
【发布时间】:2012-10-28 23:54:06
【问题描述】:

我正在尝试从 Java 应用程序恢复 Mysql 转储。 我正在使用此代码:

    Runtime rt = Runtime.getRuntime();
                try {
                   comando = "mysql -u root -ppass -e \"source " + path + "\\sql\\backup.sql\" legapelis" ; 

                   Process proceso = rt.exec(comando);
                   System.out.println("ejecutando");
                   System.out.println(comando);


                   proceso.getInputStream().close();
                   proceso.getOutputStream().close();
                   proceso.getErrorStream().close();


                   completado = proceso.waitFor();
                   if (completado != 0) {
                       System.out.println("error");
                       addActionError(getText("backup.errcopia") + ": " + String.valueOf(completado));
                       consultarCopias();
                       return "error";
                   }
                   System.out.println("fin");


                } catch (Exception e) {
                    addActionError(e.getLocalizedMessage());
                    consultarCopias();
                    return "error";
                }

但是这段代码打开的Mysql进程永远不会结束。它挂起,如果我杀死它,Mysql 服务将停止正常工作(我必须重新启动它)。我尝试了很多代码:关闭流,读取它......但结果相同。

有什么提示吗?

如果我的英语不太好,请见谅。

谢谢

Ps:我尝试将 -v 选项添加到命令中以从输入流中读取它。它开始读取,但随后又挂起(并且没有完成读取命令的输出:它突然停止)

【问题讨论】:

  • 如果您要在终端中运行该命令,mysql 进程在完成操作后通常会自行终止吗?
  • 因为您关闭了所有流,而它们现在阻止了所有内容。阅读 Process 的 JavaDoc
  • 从终端,该命令工作正常
  • 我相信这篇文章的答案将解决您的问题。 stackoverflow.com/questions/13008526/…
  • EMAcOttawa,现在我通过Java方法分析SQL文件解决了它;但我会看看。谢谢。

标签: java mysql process runtime dump


【解决方案1】:

Process 的 JavaDoc:

创建的子进程没有自己的终端或控制台。全部 它的标准 io(即 stdin、stdout、stderr)操作将是 通过三个流重定向到父进程 (getOutputStream()、getInputStream()、getErrorStream())。父母 进程使用这些流来提供输入并从中获取输出 子进程。因为有些原生平台只提供有限的缓冲区 标准输入输出流的大小,未能及时写入 子进程的输入流或读取输出流可能会导致 子进程阻塞,甚至死锁。

您需要从这些流中读取,而不是关闭它们。

【讨论】:

  • 这有点棘手,尝试阅读和测试这个:securecoding.cert.org/confluence/display/java/…,一般情况下,如果可能,尝试使用 ProcessBuilder:docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
  • 待定;我已经尝试了该链接中的示例(同时使用 Runtime 和 ProcessBuilder),结果是相同的。例如,使用重定向解决方案,它会停在“c = is.read()”
  • 看起来 Inputstream 没有数据要读取,调用阻塞了线程。我可以在单独的线程中运行它,但我会遇到同样的问题;如果我不消费流,waitFor 也会阻塞。
【解决方案2】:

好吧,最后我改变了程序,因为我无法解决这个问题。现在,我阅读了 SQL 文件,并用句子创建了一个 ArrayList,然后我自己执行它们。

感谢大家的支持。

【讨论】:

    猜你喜欢
    • 2011-05-17
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    相关资源
    最近更新 更多