【发布时间】:2018-11-01 14:53:11
【问题描述】:
更新:如果想通了,但我仍然对解释感兴趣。问题是我正在运行下面的代码,同时还从 SqlWorkbenchJ 连接到我的 Redshift 集群(两者都在同一台笔记本电脑上运行)。第二次我断开我的 SqlWorkbenchJ 会话并重新运行我的代码,它没有挂起。 为什么?
请注意:虽然我在这个问题中提到了 Java/JDBC,但它严格来说是一个关于排查 Redshift 的问题,并且与语言/框架无关!!!
还有一个 SSCCE 代码库,它完美地重现了挂起的问题: https://github.com/bitbythecron/redshift-copy-troubleshooting
我正在尝试从 Java 代码运行以下 Redshift COPY 命令(使用 Postgres JDBC 驱动程序):
COPY my_schema.mytable
FROM 's3://com.example.mybucket/mydata.csv/part-00000-bc1b179d-b4c1-459f-8f5e-8fe361d4b40f-c000.csv'
iam_role 'arn:aws:iam::blah:role/MyRedshiftRole'
csv;
如果我没看错文档,应该:
- 读取存储在 S3 上的 CSV 文件
- 将其内容复制到 Redshift 表中 (
my_schema.mytable)
当我在我的 Redshift UI 客户端 (SqlWorkbenchJ) 中运行此命令时,它会正确执行并在几秒钟内运行。但是,当我执行以下 JDBC 代码(使用 exact 相同的连接 URL、凭据等)时,代码只是挂在 executeUpdate 命令处:
Connection conn = null;
Statement statement = null;
try {
Class.forName("org.postgresql.Driver");
Properties props = new Properties();
props.setProperty("user", redshiftInfo.username);
props.setProperty("password", redshiftInfo.password);
log.info("\n\nAttempting to connect!\n\n");
conn = DriverManager.getConnection("jdbc:postgresql://<sameExactUrl_thatIUser_inSqlWorkbenchJ>", props);
log.info("\n\nConnection made!\n\n");
statement = conn.createStatement();
String command = "COPY my_schema.my_table FROM 's3://com.example.mybucket/mydata.csv/part-00000-bc1b179d-b4c1-459f-8f5e-8fe361d4b40f-c000.csv' iam_role 'arn:aws:iam::blah:role/MyRedshiftRole' csv";
log.info("\n\nExecuting...\n\n");
statement.executeUpdate(command);
log.info("\n\nHey I think it worked!!!\n\n");
statement.close();
conn.close();
} catch (Exception ex) {
log.info(ExceptionUtils.getStackTrace(ex));
}
当它运行时,在日志中我会看到 Executing... 日志语句,但随后软件就会挂起。我已经等了 30 分钟,看看它是否因为某种原因变慢了。我还在这 30 分钟内(和之后)刷新了我的 SqlWorkbenchJ 连接并运行 SELECT COUNT(*) FROM my_schema.my_table 并且计数始终为 0。因此它建立了连接,但实际上并没有被复制,或者如果是,它没有被提交.
我想看看 Redshift 方面发生了什么:是否有任何表或日志(在 AWS 控制台或其他地方)我可以跟踪或检查记录是否真的被复制并暂存于某处,或者从 Redshift 的角度查看是否有任何错误被报告?
【问题讨论】:
-
有一个 Redshift 控制台,您可以在其中查看正在执行的所有查询和加载。服务 -> Redshift -> 集群 -> 您的集群 -> 查询/加载选项卡。
-
您是否尝试过使用
PreparedStatement?比如:PreparedStatement stmt = connection.prepareStatement(command); stmt.execute(); -
代码是否与您通过 SqlWorkbenchJ 运行时在同一系统(笔记本电脑或其他)上运行?你在 stl_load_errors 表中看到什么了吗?如果不是,那么可能与权限有关。副本中的角色是让redshift访问s3。客户端在 redshift 上执行的权限是分开的。
-
是的,在我安装了 SqlWorkbenchJ 的同一台笔记本电脑上运行代码,使用相同的用户/密码,使用相同的精确(逐字)COPY 命令。 :-/ 我认为重要的是挂起,我希望它是否与权限/安全相关,会引发某种异常。
-
@DanW 介意看看我的更新,有什么想法吗?再次感谢!
标签: java jdbc amazon-redshift