为什么我的 Amazon Redshift 查询状态在未进行更改的情况下从“已完成”变成“已中止”?

上次更新日期:2022 年 11 月 3 日

Amazon Redshift 控制台显示查询状态为“已完成”,但该状态随后变为“已中止”。但是,当我查询上一个会话或事务的结果时,没有对表进行更新。为什么会发生这种情况?

简短描述

操作数据或创建数据库对象的 SQL 语句在事务提交前不会持续。这不适用于 TRUNCATE 语句,这种语句会隐式执行 COMMIT

如果 SQL 语句仍处于尚未完成的事务中,Amazon Redshift 控制台会显示查询的状态为“已完成”。事务回滚时状态将会变为“已中止”。当中止的列值为 0 时,STL_QUERY 系统表还会显示 SQL 语句已成功完成。

如果稍后提交事务,将会显示更改。但是,如果无法提交该事务,Amazon Redshift 控制台将显示查询已中止。要确定无法提交事务的原因,请检查 STL 系统表。

解决方案

要确认事务是否已提交或回滚,请对 SVL_STATEMENTTEXT 系统表使用以下查询的输出。然后,按 SQL 语句的事务 ID (xid) 进行筛选:

SELECT *
FROM SVL_STATEMENTTEXT
WHERE xid IN (SELECT xid FROM STL_QUERY WHERE query = [Query ID]) ORDER BY starttime, sequence;

查询的输出显示回滚事务的 “Undoing 1 transactions”(撤消 1 个事务)语句。

如果事务以 BEGIN 语句开头,则该语句由用户或应用程序显式打开。该声明还必须显式提交。未使用 BEGIN 语句启动的事务通常由 SQL 客户端或驱动程序的 AUTO COMMIT 选项自动提交。如果禁用该选项,则用户必须显式发送 COMMIT。

当事务被正确提交时,事务的更改是持久的(长久的),并且可以被在 COMMIT 语句之后启动的其他 XID 看到。有关详细信息,请参阅可序列化隔离

当在 SVL_STATEMENTTEXT 系统表中看不到 END、COMMIT 或“Undoing 1 transactions”(撤消 1 个事务)消息时,XID 可能仍处于打开状态。使用 SVV_TRANSACTIONS 视图来识别打开的事务和锁争用

系统表 STL_COMMIT_STRATS 和 STL_UNDONE 也可用于确认事务是以 COMMIT 还是 ROLLBACK 结束。

运行以下查询以确定更改是否已提交:

SELECT q.query, q.xid, NVL2 (cs.endtime, cs.endtime::text, 'NO COMMIT') AS commit_endtime
FROM STL_QUERY q LEFT JOIN STL_COMMIT_STATS cs ON q.xid = cs.xid AND cs.node = -1
WHERE q.query = [QUERY ID];

运行以下查询以确定更改是否已回滚:

SELECT *
FROM STL_UNDONE
WHERE xact_id_undone IN (SELECT cid from STL_QUERY where query = [QUERY ID]);

由于显式的 ROLLBACK 命令或者事务更改直到完成才运行,事务更改不会被保存。当存在可序列化的隔离违规时,不会发生显式回滚。当管理员终止会话或取消查询时,它们也不会发生。网络连接中的超时也会阻止事务更改持续存在。

如果发生回滚,则客户端会收到一条包含更多详细信息的错误消息。最佳做法是将您的客户端配置为日志错误。有关更多信息,请参阅配置日志(JDBC)或 LogLevel(ODBC)。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?