AWS Redshift上的COPY错误疑难解答

时间:2018-05-22 18:39:57

标签: java jdbc amazon-redshift

更新:如果弄清楚但仍然对解释感兴趣。问题是我在运行下面的代码同时从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;

如果我已正确阅读文档,则应该:

  1. 读取存储在S3上的CSV文件
  2. 将其内容复制到Redshift表(my_schema.mytable
  3. 当我在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...日志语句,但软件就会挂起。我等了30分钟,看看它是否因某种原因而变慢。我在整个(以及之后)30分钟内刷新了我的SqlWorkbenchJ连接并运行SELECT COUNT(*) FROM my_schema.my_table并且计数始终为0.所以它进行连接但是实际上没有任何东西被复制,或者如果没有,它不是承诺。

    我想看看Redshift方面发生了什么:是否有任何表格或日志(在AWS控制台或其他方面)我可以尾随或检查以查看记录是否实际被复制并在某处进行了分段,或者从Redshift的角度看是否有任何错误报告?

2 个答案:

答案 0 :(得分:1)

您的Java代码没有问题。如果记录数量较少,它的效果非常好。

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

创建一个包含数据#的CSV,并将其放在S3中,只有2-3条记录,

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 Complaint,意味着在您的复制命令完成并提交之前,因此,您将看不到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文档。

答案 1 :(得分:0)

问题在于我在运行下面的代码,同时还从SqlWorkbenchJ连接到我的Redshift集群(两者都在同一台笔记本电脑上运行)。第二个我断开我的SqlWorkbenchJ会话并重新运行我的代码,它不会挂起。