java - 排查 AWS Redshift 上的 COPY 错误

标签 java jdbc amazon-redshift

更新:如果弄清楚了这一点,但我仍然对解释感兴趣。问题是我在运行下面的代码的同时也从 SqlWorkbenchJ 连接到我的 Redshift 集群(两者都在同一台笔记本电脑上运行)。第二次我断开 SqlWorkbenchJ session 并重新运行我的代码时,它没有挂起。 为什么?

<小时/>

请注意:虽然我在这个问题中提到了 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;

如果我正确阅读了文档,这应该是:

  1. 读取存储在 S3 上的 CSV 文件
  2. 将其内容复制到 Redshift 表 ( my_schema.mytable )

当我在 Redshift UI 客户端 (SqlWorkbenchJ) 中运行此命令时,它会正确执行并在几秒钟内运行。但是,当我执行以下 JDBC 代码(使用完全相同相同的连接 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... log 语句,但随后软件就挂起。我等了长达30分钟,看看是不是因为某种原因速度慢了。我还在这 30 分钟内(以及之后)刷新了我的 SqlWorkbenchJ 连接并运行 SELECT COUNT(*) FROM my_schema.my_table并且计数始终为 0。因此它建立了连接,但实际上没有复制任何内容,或者如果复制了,则没有提交。

我想看看 Redshift 方面发生了什么:是否有任何表或日志(在 AWS 控制台或其他地方)我可以跟踪或检查记录是否确实被复制并暂存在某处,或者查看从 Redshift 的角度是否报告了任何错误?

最佳答案

您的Java代码没有问题。如果记录数量较少,它工作得很好。

create table my_table (
  c_name            varchar(25)    not null,
  c_address         varchar(25)    not null,
  c_city            varchar(25)    not null);

使用 data# 创建一个 CSV 并将其放入仅包含 2-3 条记录的 S3 中,

one,two,three
example1,example2,example3

然后,运行您的代码,它将出现以下输出。

 Attempting to connect!
 Connection made!
 Executing...
 Hey I think it worked!!!

现在,做

Select * from my_table;

 c_name  | c_address |  c_city
 ----------+-----------+----------
 one      | two       | three
 example1 | example2  | example3

回到你的问题,为什么你在 Select * from my_table; 中看到 0 条记录

事实: Amazon Redshift 完全满足 ACID 要求,这意味着在您的复制命令完成并提交之前,您将不会在 SELECT 中看到任何记录。

解决方案: 您想看看您的查询发生了什么,是被执行还是被终止?

您可以运行以下命令来查看所有当前正在运行的查询。

  select pid, user_name, starttime, query from stv_recents where status='Running';

  //OR

  select query, pid, elapsed, substring from svl_qlog where userid = 100 order by starttime desc limit 5;

请参阅 AWS Redshift system query文档以获取更多详细信息。

关于java - 排查 AWS Redshift 上的 COPY 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50474428/

相关文章:

java - 让套接字等待来自 JTextArea 的输入

尝试连接到 Oracle 数据库时出现 java.sql.SQLException

mysql - 将数据从 MySql 同步到 Amazon RedShift

amazon-web-services - 如何授予 Amazon Redshift 用户读取系统表、 View 、日志等的访问权限?

java - spring-boot2 上的 Resilience4j - 断路器未打开

java - 在spring mvc中按名称获取cookie值

java - 在我的 servlet 中调用 Store.connect 挂起

java - 使用 JDBC 更新多行

Eclipse 中的 java.lang.ClassNotFoundException : com. mysql.jdbc.Driver 即使引用了 mysql-connector jar

mysql - Amazon Redshift 中的 CREATE TABLE LIKE/AS 中的表权限是否会继承?