我目前正在尝试加快用于在Jenkins上进行测试的数据库转储的恢复。

当前情况:当前转储(〜15 MB)使用大量的“ INSERT”来还原数据库中的所有数据。使用了多年使用JDBC的工具来还原转储和所有较新的更新脚本(来自补丁等)。

问题:默认情况下,较新的转储使用“ COPY”,但是该工具似乎存在问题。由于stdin部分,一个简单的statement.execute(sqlstring)似乎失败。一个copyManager.copyIn(sqlstring)失败,并出现错误:“ \”或附近的语法错误(每个复制命令后跟一个\。)
命令示例:

COPY foo_data (id, cusid, tnmnid, usrid, some_text, more_text, archiv) FROM stdin;
\.


使用CopyManager的源:

CopyManager cpManager = ((BaseConnection) connection).getCopyAPI();

String sqlContent;
sqlContent = FileUtils.readFileToString(sqlFile, "UTF-8");
// The dump contains a user variable that needs to be replaced
sqlContent = StringUtils.replace(sqlContent, DB_USER, dbName);

cpManager.copyIn(sqlContent);


我可能会错过什么吗?

提前致谢!

最佳答案

您应该怀疑方法没有将表名作为参数…

该函数的第一个参数必须是带有copyIn SQL语句的字符串。

该函数的单参数形式仅在COPY语句命名应从中读取数据的文件(在数据库服务器上!)时才有效,例如

COPY tablename FROM '/path/to/datafile'


具有第二个(可能还有第三个)参数的表单用于

COPY tablename FROM STDIN


在这里,数据是从数据库客户端读取的,您必须以COPYjava.io.Reader的形式提供它们。

您的代码可能如下所示:

try {
    org.postgresql.copy.CopyManager copy = ((org.postgresql.PGConnection)conn).getCopyAPI();
    java.io.FileReader infile = new java.io.FileReader("/home/laurenz/copydata");
    copy.copyIn("COPY copydest FROM STDIN (FORMAT 'csv')", infile);
} catch (java.io.IOException e) {
    System.err.println("Could not read file with COPY data.");
}

10-02 04:26