更新:如果弄清楚了这一点,但我仍然对解释感兴趣。问题是我在运行下面的代码的同时也从 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;
如果我正确阅读了文档,这应该是:
- 读取存储在 S3 上的 CSV 文件
- 将其内容复制到 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/