メインコンテンツまでスキップ

Troubleshooting

非同期マテリアライズドビューのトラブルシューティング

このトピックでは、非同期マテリアライズドビューの調査方法と、それらを使用する際に発生する問題の解決方法について説明します。

注意

以下の機能のいくつかは、StarRocks v3.1以降でのみサポートされています。

非同期マテリアライズドビューの調査

まず、作業中の非同期マテリアライズドビューの全体像を把握するために、その動作状態、リフレッシュ履歴、およびリソース使用状況をチェックすることができます。

非同期マテリアライズドビューの動作状態を確認する

SHOW MATERIALIZED VIEWSを使用して、非同期マテリアライズドビューの動作状態を確認できます。返される情報の中で、以下のフィールドに注目できます。

  • is_active:マテリアライズドビューの状態がアクティブかどうか。アクティブなマテリアライズドビューのみがクエリの高速化と書き換えに使用できます。
  • last_refresh_state:直近のリフレッシュの状態。PENDING、RUNNING、FAILED、SUCCESSを含みます。
  • last_refresh_error_message:直近のリフレッシュが失敗した理由(マテリアライズドビューの状態がアクティブでない場合)。
  • rows:マテリアライズドビュー内のデータ行数。この値は、更新が遅延する場合があるため、実際の行数とは異なる場合があります。

返される他のフィールドの詳細については、SHOW MATERIALIZED VIEWS - Returnsを参照してください。

例:

MySQL > SHOW MATERIALIZED VIEWS LIKE 'mv_pred_2'\G
***************************[ 1. row ]***************************
id | 112517
database_name | ssb_1g
name | mv_pred_2
refresh_type | ASYNC
is_active | true
inactive_reason | <null>
partition_type | UNPARTITIONED
task_id | 457930
task_name | mv-112517
last_refresh_start_time | 2023-08-04 16:46:50
last_refresh_finished_time | 2023-08-04 16:46:54
last_refresh_duration | 3.996
last_refresh_state | SUCCESS
last_refresh_force_refresh | false
last_refresh_start_partition |
last_refresh_end_partition |
last_refresh_base_refresh_partitions | {}
last_refresh_mv_refresh_partitions |
last_refresh_error_code | 0
last_refresh_error_message |
rows | 0
text | CREATE MATERIALIZED VIEW `mv_pred_2` (`lo_quantity`, `lo_revenue`, `sum`)
DISTRIBUTED BY HASH(`lo_quantity`, `lo_revenue`) BUCKETS 2
REFRESH ASYNC
PROPERTIES (
"replication_num" = "1",
"storage_medium" = "HDD"
)
AS SELECT `lineorder`.`lo_quantity`, `lineorder`.`lo_revenue`, sum(`lineorder`.`lo_tax`) AS `sum`
FROM `ssb_1g`.`lineorder`
WHERE `lineorder`.`lo_linenumber` = 1
GROUP BY 1, 2;

1 row in set
Time: 0.003s

非同期マテリアライズドビューのリフレッシュ履歴を表示する

データベースinformation_schemaのテーブルtask_runsをクエリすることで、非同期マテリアライズドビューのリフレッシュ履歴を表示することができます。返される情報の中で、以下のフィールドに注目できます。

  • CREATE_TIMEおよびFINISH_TIME:リフレッシュタスクの開始時刻と終了時刻。
  • STATE:リフレッシュタスクの状態。PENDING、RUNNING、FAILED、SUCCESSを含みます。
  • ERROR_MESSAGE:リフレッシュタスクの失敗理由。

例:

MySQL > SELECT * FROM information_schema.task_runs WHERE task_name ='mv-112517' \G
***************************[ 1. row ]***************************
QUERY_ID | 7434cee5-32a3-11ee-b73a-8e20563011de
TASK_NAME | mv-112517
CREATE_TIME | 2023-08-04 16:46:50
FINISH_TIME | 2023-08-04 16:46:54
STATE | SUCCESS
DATABASE | ssb_1g
EXPIRE_TIME | 2023-08-05 16:46:50
ERROR_CODE | 0
ERROR_MESSAGE | <null>
PROGRESS | 100%
EXTRA_MESSAGE | {"forceRefresh":false,"mvPartitionsToRefresh":[],"refBasePartitionsToRefreshMap":{},"basePartitionsToRefreshMap":{}}
PROPERTIES | {"FORCE":"false"}
***************************[ 2. row ]***************************
QUERY_ID | 72dd2f16-32a3-11ee-b73a-8e20563011de
TASK_NAME | mv-112517
CREATE_TIME | 2023-08-04 16:46:48
FINISH_TIME | 2023-08-04 16:46:53
STATE | SUCCESS
DATABASE | ssb_1g
EXPIRE_TIME | 2023-08-05 16:46:48
ERROR_CODE | 0
ERROR_MESSAGE | <null>
PROGRESS | 100%
EXTRA_MESSAGE | {"forceRefresh":true,"mvPartitionsToRefresh":["mv_pred_2"],"refBasePartitionsToRefreshMap":{},"basePartitionsToRefreshMap":{"lineorder":["lineorder"]}}
PROPERTIES | {"FORCE":"true"}

非同期マテリアライズドビューのリソース使用状況を監視する

リフレッシュ中およびリフレッシュ後に、非同期マテリアライズドビューが使用するリソースの消費状況を監視できます。

リフレッシュ中のリソース消費を監視する

リフレッシュタスク中は、SHOW PROC '/current_queries'を使用して、リアルタイムのリソース消費を監視できます。

返される情報の中で、以下のフィールドに注目できます。

  • ScanBytes:スキャンされるデータのサイズ。
  • ScanRows:スキャンされるデータ行数。
  • MemoryUsage:使用されるメモリのサイズ。
  • CPUTime:CPU時間のコスト。
  • ExecTime:クエリの実行時間。

例:

MySQL > SHOW PROC '/current_queries'\G
***************************[ 1. row ]***************************
StartTime | 2023-08-04 17:01:30
QueryId | 806eed7d-32a5-11ee-b73a-8e20563011de
ConnectionId | 0
Database | ssb_1g
User | root
ScanBytes | 70.981 MB
ScanRows | 6001215 rows
MemoryUsage | 73.748 MB
DiskSpillSize | 0.000
CPUTime | 2.515 s
ExecTime | 2.583 s

リフレッシュ後のリソース消費を分析する

リフレッシュタスクの後、クエリプロファイルをチェックしてリフレッシュタスクで消費されるリソースを分析できます。

非同期マテリアライズドビューが自動的にリフレッシュされる際には、INSERT OVERWRITE ステートメントが実行されます。リフレッシュタスクが消費する時間とリソースを分析するために、対応するクエリプロファイルを確認できます。

返される情報の中で、以下の指標に注目できます。

  • Total:クエリが消費した合計時間。
  • QueryCpuCost:クエリの合計CPU時間のコスト。CPU時間のコストは並行プロセスで集約されるため、この指標の値はクエリの実行時間よりも大きい場合があります。
  • QueryMemCost:クエリの合計メモリコスト。
  • その他の演算子(結合演算子や集約演算子など)の指標。

クエリプロファイルの確認方法やその他の指標の理解についての詳細については、クエリプロファイルの分析を参照してください。

クエリが非同期マテリアライズドビューによって書き換えられたかを確認する

クエリプランをEXPLAINを使用してチェックすることで、クエリが非同期マテリアライズドビューによって書き換えられたかどうかを確認できます。

クエリプランのメトリック SCAN が対応するマテリアライズドビューの名前を示す場合、クエリはマテリアライズドビューによって書き換えられています。

例 1:

MySQL > SHOW CREATE TABLE mv_agg\G
***************************[ 1. row ]***************************
Materialized View | mv_agg
Create Materialized View | CREATE MATERIALIZED VIEW `mv_agg` (`c_custkey`)
DISTRIBUTED BY RANDOM
REFRESH ASYNC
PROPERTIES (
"replication_num" = "1",
"replicated_storage" = "true",
"storage_medium" = "HDD"
)
AS SELECT `customer`.`c_custkey`
FROM `ssb_1g`.`customer`
GROUP BY `customer`.`c_custkey`;

MySQL > EXPLAIN LOGICAL SELECT `customer`.`c_custkey`
-> FROM `ssb_1g`.`customer`
-> GROUP BY `customer`.`c_custkey`;
+-----------------------------------------------------------------------------------+
| Explain String |
+-----------------------------------------------------------------------------------+
| - Output => [1:c_custkey] |
| - SCAN [mv_agg] => [1:c_custkey] |
| Estimates: {row: 30000, cpu: ?, memory: ?, network: ?, cost: 15000.0} |
| partitionRatio: 1/1, tabletRatio: 12/12 |
| 1:c_custkey := 10:c_custkey |
+-----------------------------------------------------------------------------------+

もしクエリのリライト機能を無効にした場合、StarRocksは通常のクエリプランを採用します。

例 2:

MySQL > SET enable_materialized_view_rewrite = false;
MySQL > EXPLAIN LOGICAL SELECT `customer`.`c_custkey`
-> FROM `ssb_1g`.`customer`
-> GROUP BY `customer`.`c_custkey`;
+---------------------------------------------------------------------------------------+
| Explain String |
+---------------------------------------------------------------------------------------+
| - Output => [1:c_custkey] |
| - AGGREGATE(GLOBAL) [1:c_custkey] |
| Estimates: {row: 15000, cpu: ?, memory: ?, network: ?, cost: 120000.0} |
| - SCAN [mv_bitmap] => [1:c_custkey] |
| Estimates: {row: 60000, cpu: ?, memory: ?, network: ?, cost: 30000.0} |
| partitionRatio: 1/1, tabletRatio: 12/12 |
+---------------------------------------------------------------------------------------+

問題の診断と解決

以下に、非同期マテリアライズドビューを使用する際に遭遇する可能性のある一般的な問題とそれに対する解決策をいくつかリストアップします。

非同期マテリアライズドビューの作成に失敗する

非同期マテリアライズドビューの作成に失敗した場合、つまり、CREATE MATERIALIZED VIEW ステートメントを実行できない場合、以下の項目を確認できます。

  • **同期マテリアライズドビュー用の SQL ステートメントを誤って使用していないか確認してください。**StarRocksは、同期マテリアライズドビューと非同期マテリアライズドビューの2つの異なるマテリアライズドビューを提供しています。同期マテリアライズドビューを作成するための基本的な SQL ステートメントは次のとおりです:
    CREATE MATERIALIZED VIEW <mv_name> 
    AS <query>
    ただし、非同期マテリアライズドビューを作成するための SQL ステートメントには、さらにいくつかのパラメータが含まれます:
    CREATE MATERIALIZED VIEW <mv_name> 
    REFRESH ASYNC -- 非同期マテリアライズドビューのリフレッシュ戦略
    DISTRIBUTED BY HASH(<column>) -- 非同期マテリアライズドビューのデータ分散戦略
    AS <query>
    SQL ステートメント以外に、両方のマテリアライズドビューの主な違いは、非同期マテリアライズドビューがStarRocksが提供するすべてのクエリ構文をサポートするが、同期マテリアライズドビューは制限付きの集計関数しかサポートしないことです。
  • **正しい「Partition By」カラムを指定したかどうかを確認してください。**非同期マテリアライズドビューを作成する際には、リフレッシュの粒度を細かくするためにパーティショニング戦略を指定することができます。現在、StarRocksは範囲パーティショニングのみをサポートしており、クエリステートメントのSELECT式で参照されるカラムは1つのみをサポートしています。パーティショニング戦略の粒度レベルを変更するためには、date_trunc() 関数を使用してカラムを切り捨ててください。その他の式はサポートされていませんので、注意してください。
  • **マテリアライズドビューを作成するための必要な権限があるかどうか確認してください。**非同期マテリアライズドビューを作成する際には、クエリで参照されるすべてのオブジェクト(テーブル、ビュー、マテリアライズドビュー)の SELECT 権限が必要です。クエリで UDF を使用する場合は、関数の USAGE 権限も必要です。

マテリアライズドビューのリフレッシュが失敗する

マテリアライズドビューのリフレッシュが失敗した場合、つまり、リフレッシュタスクの状態がSUCCESSでない場合、以下の項目を確認できます。

  • **不適切なリフレッシュ戦略を採用していないか確認してください。**デフォルトでは、マテリアライズドビューは作成された直後にリフレッシュされます。しかし、v2.5および以前のバージョンでは、手動でリフレッシュする必要のある MANUAL リフレッシュ戦略のマテリアライズドビューは、作成後に自動的にリフレッシュされません。REFRESH MATERIALIZED VIEW を使用して手動でリフレッシュする必要があります。

  • **リフレッシュタスクがメモリ制限を超えていないか確認してください。**通常、非同期マテリアライズドビューがメモリリソースを使い果たすほどの大規模な集計や結合演算に関与する場合、リフレッシュタスクは多くのリソースを占有します。この問題を解決するためには、以下の方法があります:

    • マテリアライズドビューにパーティショニング戦略を指定し、1つのパーティションごとにリフレッシュします。
    • リフレッシュタスクに Spill to Disk 機能を有効にします。StarRocksは、マテリアライズドビューをリフレッシュする際に、中間結果をディスクにスピルする機能を v3.1以降でサポートしています。以下のステートメントを実行して Spill to Disk を有効にします。
      SET enable_spill = true;
  • **リフレッシュタスクがタイムアウト時間を超えていないか確認してください。**大規模なマテリアライズドビューのリフレッシュタスクは、リフレッシュタスクがタイムアウト時間を超えるために失敗する場合があります。この問題を解決するためには、以下の方法があります:v3.0以降では、マテリアライズドビューの作成時にまたはALTER MATERIALIZED VIEW を使用して以下のプロパティ(セッション変数)を定義することができます。例:

    -- マテリアライズドビューを作成する際にプロパティを定義する
    CREATE MATERIALIZED VIEW mv1
    REFRESH ASYNC
    PROPERTIES ( 'session.enable_spill'='true' )
    AS <query>;

    -- プロパティを追加
    ALTER MATERIALIZED VIEW mv2
    SET ('session.enable_spill' = 'true');
    • マテリアライズドビューに対してパーティショニング戦略を指定し、リフレッシュごとに1つのパーティションをリフレッシュします。
    • タイムアウト時間を長く設定します。

マテリアライズドビューの状態がアクティブでない

マテリアライズドビューがクエリの書き換えやリフレッシュを行えず、マテリアライズドビューの状態is_activefalseの場合、これはベーステーブルのスキーマ変更の結果かもしれません。この問題を解決するためには、以下のステートメントを実行してマテリアライズドビューの状態をアクティブに設定することができます。

ALTER MATERIALIZED VIEW mv1 ACTIVE;

マテリアライズドビューの状態をアクティブに設定しても効果がない場合は、マテリアライズドビューを削除して再作成する必要があります。

マテリアライズドビューのリフレッシュタスクが過剰なリソースを使用する

リフレッシュタスクが過剰なシステムリソースを使用している場合、以下の項目を確認できます。

  • **過大なマテリアライズドビューを作成していないか確認してください。**多くのテーブルを結合して計算量が大きいマテリアライズドビューを作成している場合、リフレッシュタスクは多くのリソースを占有します。この問題を解決するためには、マテリアライズドビューのサイズを評価し、計画を見直す必要があります。
  • **不必要に頻繁なリフレッシュ間隔を設定していないか確認してください。**固定間隔のリフレッシュ戦略を採用している場合、リフレッシュ頻度を低く設定することでこの問題を解決できます。リフレッシュタスクがベーステーブルのデータの変更によってトリガされる場合、頻繁なデータのロードもこの問題の原因となります。この問題を解決するためには、マテリアライズドビューに適切なリフレッシュ戦略を定義する必要があります。
  • **マテリアライズドビューがパーティション分割されているか確認してください。**パーティション分割されていないマテリアライズドビューのリフレッシュはコストがかかる場合があります。StarRocksはリフレッシュごとにマテリアライズドビュー全体をリフレッシュします。この問題を解決するためには、マテリアライズドビューに対してパーティショニング戦略を指定し、リフレッシュごとに1つのパーティションをリフレッシュする必要があります。

リソースを多く消費するリフレッシュタスクを停止するためには、以下の方法があります。

  • マテリアライズドビューの状態を非アクティブに設定することで、全てのリフレッシュタスクを停止します:

    ALTER MATERIALIZED VIEW mv1 INACTIVE;
  • 実行中のリフレッシュタスクを SHOW PROCESSLIST と KILL を使用して中断します:

    -- 実行中のリフレッシュタスクの ConnectionId を取得します。
    SHOW PROCESSLIST;
    -- 実行中のリフレッシュタスクを中断します。
    KILL QUERY <ConnectionId>;

マテリアライズドビューがクエリの書き換えに失敗する

マテリアライズドビューが関連するクエリの書き換えに失敗した場合、以下の項目を確認できます。

  • **マテリアライズドビューとクエリが一致しているかを確認してください。**マテリアライズドビューのクエリリライトの制限事項についての詳細な情報については、マテリアライズドビューによるクエリリライト - 制限事項を参照してください。

    • StarRocksは、マテリアライズドビューとクエリをテキストベースのマッチングではなく、構造ベースのマッチング技術を使用して一致させます。そのため、クエリが似ているだけではクエリがマテリアライズドビューによって書き換えられるとは限りません。
    • マテリアライズドビューは、SPJG(Select/Projection/Join/Aggregation)タイプのクエリのみを書き換えることができます。ウィンドウ関数、ネストされた集計、または結合と集計を含むクエリはサポートされません。
    • ネストされたマテリアライズドビューには、アウタージョインで複雑な結合述語を含むクエリは書き換えることができません。例えば、A LEFT JOIN B ON A.dt > '2023-01-01' AND A.id = B.id というケースでは、JOIN ON 句の述語を WHERE 句に記述することをおすすめします。
  • **マテリアライズドビューの状態がアクティブであることを確認してください。**書き換えクエリの前に、StarRocksはマテリアライズドビューの状態をチェックします。クエリは、マテリアライズドビューの状態がアクティブである場合にのみ書き換えられます。この問題を解決するためには、以下のステートメントを実行してマテリアライズドビューの状態をアクティブに設定することができます。

    ALTER MATERIALIZED VIEW mv1 ACTIVE;
  • **マテリアライズドビューがデータの整合性要件を満たしているか確認してください。**StarRocksは、マテリアライズドビュー内のデータとベーステーブルのデータの整合性をチェックします。デフォルトでは、クエリはマテリアライズドビューのデータが最新である場合にのみ書き換えられます。この問題を解決するためには、以下の方法があります:

    • マテリアライズドビューに PROPERTIES('query_rewrite_consistency'='LOOSE') を追加し、整合性チェックを無効にします。
    • マテリアライズドビューに PROPERTIES('mv_rewrite_staleness_second'='5') を追加し、データの整合性に一定の許容度を持たせます。ベーステーブルのデータが変更されているかどうかに関係なく、最後のリフレッシュがこの時間間隔より前であれば、クエリが書き換えられます。
  • **マテリアライズドビューのクエリステートメントに出力列が不足していないか確認してください。**range や point クエリを書き換えるためには、マテリアライズドビューのクエリステートメントの SELECT 式でフィルタリング述語として使用される列を指定する必要があります。マテリアライズドビューの SELECT ステートメントをチェックし、それがクエリの WHERE 句や ORDER BY 句で参照される列を含んでいることを確認してください。

例 1: マテリアライズドビュー mv1 はネストされた集計を使用しているため、クエリの書き換えに使用することはできません。

CREATE MATERIALIZED VIEW mv1 REFRESH ASYNC AS
select count(distinct cnt)
from (
select c_city, count(*) cnt
from customer
group by c_city
) t;

例 2: マテリアライズドビュー mv2 は結合と集計を使用しているため、クエリの書き換えに使用することはできません。この問題を解決するためには、まず集計のあるマテリアライズドビューを作成し、次にそれをベースにして結合を行うネストされたマテリアライズドビューを作成することができます。

CREATE MATERIALIZED VIEW mv2 REFRESH ASYNC AS
select *
from (
select lo_orderkey, lo_custkey, p_partkey, p_name
from lineorder
join part on lo_partkey = p_partkey
) lo
join (
select c_custkey
from customer
group by c_custkey
) cust
on lo.lo_custkey = cust.c_custkey;

例 3: マテリアライズドビュー mv3 は、選択述語が参照するカラムが SELECT 式に含まれていないため、次のパターンのクエリ(SELECT c_city, sum(tax) FROM tbl WHERE dt='2023-01-01' AND c_city = 'xxx')を書き換えることはできません。

CREATE MATERIALIZED VIEW mv3 REFRESH ASYNC AS
SELECT c_city, sum(tax) FROM tbl GROUP BY c_city;

この問題を解決するためには、以下のようにマテリアライズドビューを作成してください。

CREATE MATERIALIZED VIEW mv3 REFRESH ASYNC AS
SELECT dt, c_city, sum(tax) FROM tbl GROUP BY dt, c_city;