Amazon Redshift コンソールにはクエリのステータスが [Completed] (完了) と表示されますが、その後ステータスが [Aborted] (中断) に変わります。しかし、以前のセッションまたはトランザクションの結果をクエリした際にテーブルは更新されませんでした。なぜこうなったのでしょうか?
簡単な説明
データを操作したりデータベースオブジェクトを作成したりする SQL ステートメントは、トランザクションがコミットされるまでは保持されません。これは、暗黙的に COMMIT を実行する TRUNCATE ステートメントには適用されません。
トランザクションがまだ未処理の場合、Amazon Redshift コンソールでは SQL ステートメントのクエリのステータスは [Completed] (完了) と表示されます。トランザクションがロールバックされると、ステータスは [Aborted] (中断) に変わります。また、STL_QUERY システムテーブルには、中断されたカラム値が 0 の場合に 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 コマンド、または完了するまで実行されない場合、トランザクションの変更は保持されません。直列化可能分離違反がある場合、明示的な ROLLBACKS は発生しません。また、管理者がセッションを終了したり、クエリをキャンセルした場合も発生しません。ネットワーク接続でタイムアウトが発生すると、トランザクションの変更が持続しなくなることもあります。
ロールバックが発生すると、クライアントはエラーメッセージとエラーの詳細を受け取ります。エラーをログに記録するようにクライアントを設定するのがベストプラクティスです。詳細については、「ロギングの設定 (JDBC)」または「ログレベル (ODBC)」を参照してください。
関連情報
STL_DDLTEXT