メインコンテンツまでスキップ
バージョン: 3.1

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

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

注意

以下に示す機能の一部は、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" = "3",
"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_TIMEFINISH_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: クエリの総メモリコスト。
  • ジョインオペレーターや集計オペレーターなど、個々のオペレーターの他のメトリクス。

クエリプロファイルの確認方法や他のメトリクスの理解についての詳細は、Analyze query profile を参照してください。

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

非同期マテリアライズドビューによってクエリが書き換えられるかどうかは、そのクエリプランを使用して確認できます。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" = "3",
"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 ステートメントに加えて、2つのマテリアライズドビューの主な違いは、非同期マテリアライズドビューが StarRocks が提供するすべてのクエリ構文をサポートするのに対し、同期マテリアライズドビューは限られた集計関数のみをサポートすることです。

  • 正しい Partition By 列を指定しているか確認する。

    非同期マテリアライズドビューを作成する際に、パーティショニング戦略を指定できます。これにより、マテリアライズドビューをより細かい粒度でリフレッシュできます。

    現在、StarRocks はレンジパーティション化のみをサポートしており、マテリアライズドビューを構築するために使用されるクエリステートメントの SELECT 式から単一の列を参照することのみをサポートしています。date_trunc() 関数を使用して列を切り捨て、パーティショニング戦略の粒度レベルを変更できます。他の式はサポートされていないことに注意してください。

  • マテリアライズドビューを作成するための必要な権限を持っているか確認する。

    非同期マテリアライズドビューを作成する際には、クエリされるすべてのオブジェクト(テーブル、ビュー、マテリアライズドビュー)の SELECT 権限が必要です。クエリで UDF が使用されている場合、関数の USAGE 権限も必要です。

マテリアライズドビューのリフレッシュに失敗した

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

  • 不適切なリフレッシュ戦略を採用していないか確認する。

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

  • リフレッシュタスクがメモリ制限を超えていないか確認する。

    通常、非同期マテリアライズドビューが大規模な集計やジョイン計算を含む場合、メモリリソースを使い果たします。この問題を解決するには、次の方法があります。

    • マテリアライズドビューにパーティショニング戦略を指定して、各パーティションを個別にリフレッシュします。

    • リフレッシュタスクのためにディスクへのスピル機能を有効にします。v3.1以降、StarRocks はマテリアライズドビューをリフレッシュする際に中間結果をディスクにスピルすることをサポートしています。ディスクへのスピルを有効にするには、次のステートメントを実行します。

      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');

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

マテリアライズドビューがクエリを書き換えたりリフレッシュできない場合、マテリアライズドビューの状態 is_activefalse であることがあります。これはベーステーブルのスキーマ変更が原因である可能性があります。この問題を解決するには、次のステートメントを実行してマテリアライズドビューの状態を手動でアクティブに設定できます。

ALTER MATERIALIZED VIEW mv1 ACTIVE;

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

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

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

  • 過大なマテリアライズドビューを作成していないか確認する。

    多くのテーブルをジョインして大量の計算を引き起こす場合、リフレッシュタスクは多くのリソースを占有します。この問題を解決するには、マテリアライズドビューのサイズを評価し、再計画する必要があります。

  • 不必要に頻繁なリフレッシュ間隔を設定していないか確認する。

    固定間隔のリフレッシュ戦略を採用している場合、リフレッシュ頻度を下げることで問題を解決できます。ベーステーブルのデータ変更によってリフレッシュタスクがトリガーされる場合、データを頻繁にロードすることもこの問題を引き起こす可能性があります。この問題を解決するには、マテリアライズドビューに適切なリフレッシュ戦略を定義する必要があります。

  • マテリアライズドビューがパーティション化されているか確認する。

    パーティション化されていないマテリアライズドビューは、リフレッシュが高コストになる可能性があります。StarRocks は毎回マテリアライズドビュー全体をリフレッシュするためです。この問題を解決するには、マテリアライズドビューにパーティショニング戦略を指定して、各パーティションを個別にリフレッシュする必要があります。

過剰なリソースを占有するリフレッシュタスクを停止するには、次の方法があります。

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

    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 句で指定することをお勧めします。

    マテリアライズドビューのクエリ書き換えの制限についての詳細は、Query rewrite with materialized views - Limitations を参照してください。

  • マテリアライズドビューの状態がアクティブであるか確認する。

    StarRocks は、クエリを書き換える前にマテリアライズドビューの状態を確認します。マテリアライズドビューの状態がアクティブな場合にのみ、クエリを書き換えることができます。この問題を解決するには、次のステートメントを実行してマテリアライズドビューの状態を手動でアクティブに設定できます。

    ALTER MATERIALIZED VIEW mv1 ACTIVE;
  • マテリアライズドビューがデータ整合性の要件を満たしているか確認する。

    StarRocks は、マテリアライズドビューのデータとベーステーブルのデータの整合性を確認します。デフォルトでは、マテリアライズドビューのデータが最新である場合にのみクエリを書き換えることができます。この問題を解決するには、次の方法があります。

    • マテリアライズドビューに PROPERTIES('query_rewrite_consistency'='LOOSE') を追加して整合性チェックを無効にします。
    • PROPERTIES('mv_rewrite_staleness_second'='5') を追加して、一定のデータ不整合を許容します。ベーステーブルのデータが変更されているかどうかに関係なく、最後のリフレッシュがこの時間間隔の前であれば、クエリを書き換えることができます。
  • マテリアライズドビューのクエリステートメントに出力列が不足していないか確認する。

    範囲クエリやポイントクエリを書き換えるには、マテリアライズドビューのクエリステートメントの 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 c_city, sum(tax) FROM tbl WHERE dt='2023-01-01' AND c_city = 'xxx' のパターンのクエリを書き換えることができません。なぜなら、述語が参照する列が SELECT 式に含まれていないからです。

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;