削除対象としてマークされた行を含む Amazon Redshift テーブルで VACUUM FULL または VACUUM DELETE ONLY 操作を実行しています。操作は正常に完了しているように表示されます。ディスク容量が解放されないのはなぜですか?
簡単な説明
アクティブのままで長時間実行されるトランザクションがある場合、ディスク容量が解放されない可能性があります。行が削除されると、非表示のメタデータ ID 列 DELETE_XID は、行を削除したトランザクション ID でマークされます。削除前に開始されたアクティブな長時間実行トランザクションがある場合、VACUUM は行をクリーンアップできません。これは、ディスク容量を解放できないことを意味します。DELETE_XID 列の詳細については、「細長いテーブルのストレージの最適化」を参照してください。
解決方法
1. クラスターで長時間実行されているトランザクションを確認するには、次のクエリを実行します。
rsdb=# select *,datediff(s,txn_start,getdate())/86400||' days '||datediff(s,txn_start,getdate())%86400/3600||' hrs '||datediff(s,txn_start,getdate())%3600/60||' mins '||datediff(s,txn_start,getdate())%60||' secs' duration from svv_transactions where lockable_object_type='transactionid' and pid<>pg_backend_pid() order by 3;
次の出力から、xid 50341 が 19 分 37 秒間アクティブであったことが示しています。
txn_owner | txn_db | xid | pid | txn_start | lock_mode | lockable_object_type | relation | granted | duration
-----------+--------+-------+-------+----------------------------+---------------+----------------------+----------+---------+------------------------------
superuser | rsdb | 50341 | 21612 | 2019-08-19 20:20:33.147622 | ExclusiveLock | transactionid | | t | 0 days 0 hrs 19 mins 37 secs
(1 row)
2. 次のクエリを実行して、Amazon Redshift テーブルから行が削除されたかどうかを確認します。
select a.query, a.xid, trim(c.name) tablename, b.deleted_rows, a.starttime, a.endtime
from stl_query a
join (select query, tbl, sum(rows) deleted_rows from stl_delete group by 1,2) b
on a.query = b.query
join (select id, name from stv_tbl_perm group by 1,2) c
on c.id = b.tbl
where a.xid in (select distinct xid from stl_commit_stats)
and trim(c.name) = 'tablename'
order by a.starttime;
次の出力は、行の削除のためにマークされたトランザクション (xid 50350) が、長時間実行トランザクション (xid 50341) の後に開始されたことを示しています。
query | xid | tablename | deleted_rows | starttime | endtime
-------+-------+-----------+--------------+----------------------------+----------------------------
18026 | 50350 | test | 5 | 2019-08-19 20:20:48.137594 | 2019-08-19 20:20:50.125609
(1 rows)
VACUUM DELETE がこれらの削除された行を再利用できるようにするには、次のいずれかのオプションを選択し、VACUUM 操作を再実行します。
長時間実行されるトランザクションの調査
SVL_STATEMENTTEXT ビューをクエリして、長時間実行されているトランザクションのアクティビティを確認します。
rsdb=# select pid, xid, trim(label), starttime, endtime, trim(text) from svl_statementtext where xid = 50341 order by starttime , sequence;
この出力例を次に示します。
pid | xid | btrim | starttime | endtime | btrim
-------+-------+---------+----------------------------+----------------------------+--------------------------
21612 | 50341 | default | 2019-08-19 20:20:31.733843 | 2019-08-19 20:20:31.733844 | begin;
21612 | 50341 | default | 2019-08-19 20:20:33.146937 | 2019-08-19 20:20:35.020556 | select * from sometable;
(2 rows)
STV_INFLIGHT ビューにクエリを実行し、次のトランザクションでクエリが実行されているかどうかを確認します。
rsdb=# select query, xid, pid, starttime, trim(text) from stv_inflight where xid = 50341;
この出力例を次に示します。
query | xid | pid | starttime | btrim
-------+-----+-----+-----------+-------
(0 rows)
長時間実行されるトランザクションの原因となる一般的な問題
次の動作により、トランザクションが長時間実行される可能性があります。
- ユーザーは、自動コミットが無効になっているクライアントから暗黙的なトランザクションを開始します。トランザクションは、ユーザーが COMMIT または ROLLBACK コマンドを使って明示的にトランザクションを閉じるまで、またはセッションが終了するまでアクティブのままです。
- ユーザーは BEGIN コマンドで明示的にトランザクションを開始しますが、COMMIT または ROLLBACK コマンドでトランザクションを閉じることはありません。
関連情報
テーブルのバキューム処理
バキューム処理時間の管理