Amazon Redshift でディスク使用率が高くなるか、いっぱいになる問題をトラブルシューティングする方法を教えてください。

最終更新日: 2020 年 3 月 27 日

Amazon Redshift でディスクの使用率が高くなるか、いっぱいになりました。ディスク使用率が高くなる問題のトラブルシューティング方法を教えてください。

解決方法

ディスク使用率が高いエラーは、次のような要因によって変わります。

  • 分散キーとソートキー
  • クエリ処理
  • VARCHAR (MAX) 列を含むテーブル
  • 列の高圧縮
  • メンテナンスオペレーション
  • クロス結合を持つデカルト積
  • 最小テーブルサイズ
  • 廃棄ブロック
  • 大きなファイルのコピー

分散キーとソートキー

テーブルの分散スタイル、分散キー、ソートキーの選択を確認します。ディスクノードがいっぱいになるのは、分散スキューがあるテーブルで、1 つのノード内に他のノードよりも多くのデータがあることが原因となる可能性があります。偏った分散スタイルを持つテーブルがある場合は、分散スタイルをより均一な分散に変更します。分散と行スキューは、クエリ実行中にストレージスキューと中間行セットに影響を与える可能性があることに注意してください。分散キーとソートキーの詳細については、「Amazon Redshift Engineering の Advanced Table Design Playbook: 前文、前提条件、優先順位付け」を参照してください。

分散キーのカーディナリティを確認するには、次のクエリを実行します。

select distkey, count(*) from public.distribution_skew group by distkey having count(*) > 1 order by 2 desc;

注: ソート手順を回避するには、ORDER BY 句で SORT KEY 列を使用します。ソート手順でメモリが過剰に使用されると、ディスクがあふれることがあります。詳細については、「ソートキーの選択」を参照してください。

分散キーのデータベースブロックがクラスターにマップされる方法を確認するには、Amazon Redshift table_inspector.sql ユーティリティを使用します。

クエリ処理

クエリに割り当てられているメモリを確認します。クエリの処理中は、中間クエリの結果を一時ブロックに格納できます。十分な空きメモリがない場合、テーブルはディスクに書き込まれてディスクを圧迫します。中間結果セットは圧縮されないため、使用可能なディスク容量に影響します。詳細については、「クエリへの不十分な割り当て」を参照してください。

Amazon Redshift のデフォルトは、均等な分散のテーブル構造であり、一時テーブルの列エンコードがありません。ただし、SELECT ... INTO 構文を使用している場合は、CREATE ステートメントの使用をご検討ください。詳細については、「Amazon Redshift のパフォーマンスチューニング手法トップ 10」を参照し、 ヒント #6: 一時テーブルの非効率的な使用への対処の手順に従ってください。

クエリに十分なメモリが割り当てられていない場合、値「true」が存在し、is_diskbased を持つ SVL_QUERY_SUMMARY のステップを参照してみてください。この問題を解決するには、クエリスロットの数を増やして、クエリにより多くのメモリを割り当てます。クエリのスロットを一時的に増やす方法の詳細については、wlm_query_slot_count を参照するか、WLM を調整して混合ワークロードを実行します。また、WLM クエリモニタリングルールを使用して、大量の処理負荷に対処し、入出力の多いクエリを識別することもできます。

VARCHAR (MAX) 列を含むテーブル

VARCHAR または CHARACTER VARYING 列で、データがディスクに格納されているときに省略される可能性がある末尾の空白がないかを確認します。末尾の空白は、クエリ処理中メモリ内の全長 (VARCHAR の最大値は 65535) を占める可能性があります。可能な限り最小の列サイズを使用することがベストプラクティスです。

最大列幅を持つテーブルのリストを生成するには、次のクエリを実行します。

SELECT database, schema || '.' || "table" AS "table", max_varchar FROM svv_table_info WHERE max_varchar > 150 ORDER BY 2;

幅広い VARCHAR テーブルの列の真の幅を識別して表示するには、次のクエリを実行します。

SELECT max(octet_length (rtrim(column_name))) FROM table_name;

テーブル設計の詳細については、「Amazon Redshift のテーブル設計のベストプラクティス」を参照してください。

列の高圧縮

列を最適にエンコードするために、ANALYZE COMPRESSION または Amazon Redshift Column Encoding Utility を使用してすべての列 (ソートキーを除く) をエンコードします。Amazon Redshift には、読み取りパフォーマンスを向上させ、ストレージ全体の消費量を削減できる列エンコード機能があります。システム圧縮機能を使用することがベストプラクティスです。

メンテナンスオペレーション

Amazon Redshift データベースのデータベーステーブルが定期的に分析され、バキューム処理されていることを確認します。データベースの状態を維持する 1 つの方法は、不足している統計または古い統計を特定することです。これにより、Amazon Redshift が不要なテーブル行をスキャンするのを防ぎ、クエリ実行プランの最適化にも役立ちます。

注: VACUUM や DEEP COPY などのメンテナンスオペレーションでは、ソートオペレーションに一時ストレージ領域が使用されるため、ディスク使用量のスパイクが予想されます。

たとえば、次のクエリは、Amazon Redshift で古い統計を特定するのに役立ちます。

SELECT * FROM svv_table_info WHERE stats_off > 10 ORDER BY size DESC;

詳細については、「Amazon Redshift Analyze&Vacuum Schema Utility」を参照してください。

クロス結合を持つデカルト積

デカルト積を含むクエリを検索するには、クエリの EXPLAIN 実行プランを使用します。デカルト積は、無関係なクロス結合で、ブロック数を増やす可能性があります。このクロス結合により、メモリ使用率が高くなり、ディスクに書き込まれるテーブルが増える可能性があります。クロス結合が JOIN 条件を共有していない場合、結合は 2 つのテーブルのデカルト積を生成します。次に、1 つのテーブルのすべての行が、もう 1 つのテーブルのすべての行に結合されます。

クロス結合は、ネストされたループ結合として実行することもでき、処理に最も時間がかかります。ネストされたループ結合により、全体的なディスク使用量が急増します。詳細については、「ネストされたループを持つクエリの特定」を参照してください。

最小テーブルサイズ

同じテーブルでも、クラスターによってテーブルサイズが異なる場合があります。次に、最小テーブルサイズは、列の数と、テーブルに SORTKEY があるか、およびスライスの数が入力されているかどうかによって決まります。最近 Amazon Redshift クラスターのサイズを変更した場合、ディスクストレージ全体に変化が見られる可能性があります。これはスライス数が変化したことが原因です。Amazon Redshift は、各テーブルで使用されるテーブルセグメントもカウントします。詳細については、「Amazon Redshift クラスターのテーブルが想定と異なるディスクストレージを消費していますが、なぜですか?」を参照してください。

廃棄ブロック

廃棄ブロックは、Amazon Redshift テーブルへの WRITE トランザクションが発生し、読み取りが同時に実行される場合に生成されます。Amazon Redshift は、書き込みオペレーションの前にブロックを保持して、同時読み取りオペレーションの一貫性を保ちます。Amazon Redshift ブロックは変更できません。InsertUpdate、または Delete の各アクションは、新しいブロックのセットを作成し、古いブロックを廃棄済みとしてマークします。

テーブルのトランザクションが長時間実行されることが原因で、廃棄ブロックがコミット段階でクリアされないことがあります。廃棄ブロックは、同時に実行されている ETL ロードが多すぎる場合にもクリアに失敗することがあります。Amazon Redshift はトランザクションの開始時点からデータベースをモニタリングするため、データベースに書き込まれたテーブルにも廃棄ブロックが保持されます。長時間実行されるテーブルトランザクションが定期的に、複数のロードにわたって発生した場合、廃棄ブロックが蓄積されてディスクがいっぱいになるエラーが発生する可能性があります。

commit コマンドを実行して、Amazon Redshift に廃棄ブロックに関する分析を強制的に実行させることもできます。

アクティブな実行時間の長いクエリがある場合は、commit コマンドを使用して、クエリを終了 (および後続のすべてのブロックを解放) します。

begin;
create table a (id int);
insert into a values(1);
commit;
drop table a; 

廃棄ブロックを確認するには、次のクエリを実行します。

select trim(name) as tablename, count(case when tombstone > 0 then 1 else null end) as tombstones from svv_diskusage group by 1 having count(case when tombstone > 0 then 1 else null end) > 0 order by 2 desc;

大きなファイルのコピー

COPY オペレーション中に、十分なストレージが利用可能であっても、Disk Full (ディスクがいっぱいです) エラーが発生する可能性があります。このエラーは、ソートオペレーションがディスクに書き出され、一時ブロックが作成される場合に発生します。

Disk Full エラーメッセージが表示された場合は、STL_DISK_FULL_DIAG テーブルを確認します。

select '2000-01-01'::timestamp + (currenttime/1000000.0)* interval '1 second' as currenttime,node_num,query_id,temp_blocks from pg_catalog.stl_disk_full_diag;

その他のベストプラクティスについては、「データをロードする際の Amazon Redshift のベストプラクティス」を参照してください。

追加のトラブルシューティング

Amazon Redshift コンソール の [Performance] タブで、[Percentage of Disk Space] を確認します。各クラスターノードに対して、Amazon Redshift は追加のディスクスペースを提供します。これは、名目上のディスク容量よりも大きくなります。

使用率の急激なスパイクに気付いた場合は、 STL_QUERY を使用して、実行中のアクティビティとジョブを特定します。

select * from stl_query where starttime between '2018-01-01 00:30:00' and '2018-01-01 00:40:00';

注: スパイクが発生した時刻で値を更新します。

上位 20 のディスクスピルクエリを特定するには、次のクエリを実行します。

select A.userid, A.query, blocks_to_disk, trim(B.querytxt) text from stl_query_metrics A, stl_query B where A.query = B.query and segment=-1 and step = -1 and max_blocks_to_disk > 0 order by 3 desc limit 20;

クエリがディスクに正しく書き込んでいるかどうかを確認するには、次のクエリを実行します。

SELECT q.query, trim(q.cat_text)
FROM (
SELECT query,
replace( listagg(text,' ') WITHIN GROUP (ORDER BY sequence), '\\n', ' ') AS cat_text
FROM stl_querytext
WHERE userid>1
GROUP BY query) q
JOIN (
SELECT distinct query
FROM svl_query_summary
WHERE is_diskbased='t' AND (LABEL ILIKE 'hash%' OR LABEL ILIKE 'sort%' OR LABEL ILIKE 'aggr%' OR LABEL ILIKE 'save%' OR LABEL ILIKE 'window%' OR LABEL ILIKE 'unique%')
AND userid > 1) qs
ON qs.query = q.query;

この記事はお役に立ちましたか?

改善できることはありますか?


さらにサポートが必要な場合