Spanner のエラーコード

このページでは、Spanner のエラーコードと、これらのエラーを処理するために推奨される対応について説明しています。Spanner を含む Google API では、google.rpc.Code で定義された正規のエラーコードが使用されます。

Spanner リクエストが成功すると、API はリクエストされたデータと HTTP 200 OK ステータス コードをレスポンスの本文で返します。

リクエストが失敗すると、Spanner API は失敗の概要を表す 4xx または 5xx ステータス コードと、失敗の原因となったエラーの詳細情報を含むレスポンスを返します。

レスポンス オブジェクトには単一のフィールド error が格納されており、その値には次の要素が格納されています。

要素 説明
code リクエストの失敗をおおまかに識別する HTTP ステータス コード
message リクエストの失敗に関する具体的な情報
status Google API の標準的なエラーコードgoogle.rpc.Code)。Spanner API から返されるコードについては、エラーコードをご覧ください。

コンテンツ タイプが application/x-protobuf のリクエストがエラーになると、シリアライズされた google.rpc.Status メッセージがペイロードとして返されます。

エラーコード

エラーの分類におすすめする方法は、標準的なエラーコードgoogle.rpc.Code)の値を調べることです。JSON エラーの場合、このコードは status フィールドに表示されます。application/x-protobuf エラーでは、code フィールドに表示されます。

エラーコード 説明 推奨される対応
ABORTED オペレーションは、通常、シーケンサー チェックの失敗、またはトランザクションの中止などの同時実行の問題のために中止されています。リクエストが別のリクエストと競合していることを示します。 非トランザクション commit の場合:
リクエストを再試行するか、競合がなくなるようにエンティティを構築します。

トランザクション commit に含まれるリクエスト:
トランザクション全体を再試行するか、競合がなくなるようにエンティティを構築します。
ALREADY_EXISTS クライアントが作成しようとしたエンティティはすでに存在します(既存のプライマリキーを持つ行を挿入する場合など)。 問題を解決してから再試行します。
CANCELLED オペレーションがキャンセルされました。通常、キャンセルは呼び出し元により行われます。 オペレーションを再試行してください。
DEADLINE_EXCEEDED オペレーションが完了する前に期限が切れました。 期限が十分かどうかを調査します。レスポンスが役に立つ実際の時間に対応する期限を使用します。システムの状態を変更するオペレーションの場合、オペレーションが正常に完了しても、エラーが返されることがあります。

ヒントについては、期限超過エラーのトラブルシューティングをご覧ください。
FAILED_PRECONDITION リクエストの前提条件が満たされていないため、オペレーションが拒否されました。エラー レスポンスのメッセージ フィールドで、失敗した前提条件に関する情報が提供されます。たとえば、タイムスタンプ ステイルネスの最大値を超えたタイムスタンプからの読み取りやクエリなどです。 問題を解決してから再試行します。
INTERNAL サーバーがエラーを返しました。基盤システムが想定しているいくつかの不変条件が破られました。 エラーの具体的な状況と原因を把握していない限り、再試行しないでください。
INVALID_ARGUMENT クライアントが無効な値を指定しました。エラー レスポンスのメッセージ フィールドで、無効であった値を特定する情報が提供されます。 問題を解決してから再試行します。
NOT_FOUND リクエストされたエンティティ(エンティティの更新、テーブルまたは列のクエリなど)が存在しないことを示します。 問題を解決してから再試行します。
OUT_OF_RANGE オペレーションが有効な範囲を超えて試行されました。 問題を解決してから再試行します。
PERMISSION_DENIED リクエストの実行がユーザーに許可されませんでした。 問題を解決してから再試行します。
RESOURCE_EXHAUSTED 一部のリソースが枯渇しています。

管理プレーンの場合、プロジェクトの割り当てを超えているか、ファイル システム全体で容量が不足している可能性があります。

データプレーンの場合、Spanner ノードが過負荷になっている場合に発生することがあります。

詳細については、セッション関連のエラーコードもご覧ください。
管理プレーンの場合、Spanner またはプロジェクトの割り当てを超えていないことを確認します。割り当てを超えた場合は、割り当ての増加をリクエストするか、割り当てがリセットされるまで待ってからもう一度お試しください。指数バックオフを使用するように再試行を構成します。

データプレーンでは、Spanner ノードの容量を超えていないことを確認します。Spanner は、クライアント ライブラリでこれらのエラーを再試行します。すべての再試行が失敗した場合は、フロー制御メカニズムのエラーをご覧ください。

一般に、アプリケーションで RESOURCE_EXHAUSTED エラーが発生した場合は、UNAVAILABLE エラーと同様に処理し、指数バックオフで再試行します。
UNAUTHENTICATED リクエストには、オペレーションのための有効な認証情報がありません。 問題を解決してから再試行します。
UNAVAILABLE サーバーが利用できません。 指数バックオフを使用して再試行します。非べき等オペレーションの再試行が常に安全であるとは限りません。
UNIMPLEMENTED オペレーションが実装されていないか、このサービスでサポートまたは有効にされていません。 問題を解決してから再試行します。
UNKNOWN サーバーが不明なエラーを返しました。十分なエラー情報を返さない API によって発生したエラーは、このエラーに変換できます。 リクエストが安全であることを確認します。その後、指数バックオフで再試行します。

セッション エラー

Spanner は、セッションを使用して、アプリケーションとデータベース間のインタラクションを管理します。セッションはデータベースへの接続を表し、読み取りや書き込みなどのオペレーションを容易にします。

アプリケーションで発生する可能性のあるセッション関連の一般的なエラーは次のとおりです。

セッションが見つかりません

Session not found エラーは、アプリケーションがすでに存在しないセッションを使用しようとしたときに発生します。この問題は次のような原因で発生することがあります。

  • クライアント アプリケーションがセッションを明示的に削除する場合があります。たとえば、コードでデータベース クライアントを閉じるか、deleteSessions API を直接呼び出すと、セッションが削除されます。Spanner クライアント ライブラリのいずれかを使用していない場合は、このエラーが発生したときに新しいセッションを作成します。新しいセッションをセッション プールに追加し、削除されたセッションをプールから削除します。

  • また、Spanner は特定の条件でセッションを自動的に削除します。

    • セッションが 1 時間以上アイドル状態のままである場合、セッションを削除します。これは、ダウンストリーム処理がセッション アイドル タイムアウトよりも長いデータ ストリーム ジョブで発生する可能性があります。Dataflow ジョブを使用している場合は、Dataflow パイプラインの Spanner 読み取りの後に Reshuffle 変換オペレーションを追加します。これにより、Spanner の読み取りオペレーションを後続の長時間実行処理ステップから切り離すことができます。

    • また、28 日以上経過したセッションも削除されます。クライアント ライブラリを使用している場合は、これらのケースが自動的に処理されます。Spanner クライアント ライブラリのいずれかを使用していない場合は、このエラーが発生したときに新しいセッションを作成します。新しいセッションをセッション プールに追加し、削除されたセッションをプールから削除します。

  • Spanner クライアント ライブラリのいずれかを使用している場合、ライブラリはセッションを自動的に管理します。このエラーが発生した場合は、データベース クライアントを閉じるなど、コードでセッションが明示的に削除されていないことを確認してください。クライアント ライブラリのセッション管理の問題が原因で発生することもあります。

リソース不足です

RESOURCE_EXHAUSTED: No session available in the pool エラーまたは RESOURCE_EXHAUSTED: Timed out after waiting X ms for acquiring session エラーは、アプリケーションがセッション プールからセッションを取得できないことを示します。これは、新しい読み取りリクエストまたは書き込みリクエストを処理できるセッションがない場合に発生します。

次の表に、これらのエラーの原因となる可能性のある理由と、対応する推奨アクションを示します。

理由 推奨される対応
プール内のすべてのセッションが使用中です。アプリケーションが、構成されたセッションの最大数を超える同時リクエストを受信する可能性があります。プール内のすべてのセッションが使用中で、新しいリクエストに使用できるセッションがない。 多重化されたセッションを有効にする。多重化されたセッションを使用すると、複数のトランザクションと読み取りで 1 つのセッションを共有できるため、アプリケーションに必要なセッションの総数を減らすことができます。セッション プール設定maxSession または minSession 構成を増やすこともできます。
リクエストの完了に時間がかかる。長時間実行される読み取りリクエストまたは書き込みリクエストは、使用可能なすべてのセッションを長期間占有する可能性があります。これらのリクエストがセッション取得タイムアウト設定よりも長くかかると、新しいリクエストはセッション プールからセッションを取得できません。 リクエストの完了に時間がかかる理由を調査します。クエリまたはアプリケーション ロジックを最適化して、実行時間を短縮します。セッション取得タイムアウト設定を長くすることができます。また、対象となるクライアント ライブラリで多重化されたセッションを有効にして、セッションの使用率を向上させることもできます。
セッション リークがあります。セッション リークは、アプリケーションがプールからセッションをチェックアウトしたものの、リクエストの完了後にセッションを返さない場合に発生します。これは通常、コード内でイテレータまたは結果セットが適切に閉じられていない場合に発生します。すべてのセッションがリークすると、新しいリクエストに使用できるセッションがなくなります。 アプリケーション コードをデバッグして、セッション リークを特定し、修正します。コードがすべてのイテレータと結果セットを適切に閉じていることを確認します。詳細については、セッション リーク検出ソリューションをご覧ください。セッション リークの自動クリーンアップ機能を使用して、非アクティブなトランザクションを自動的に解決するようにセッション プールを設定することもできます。
セッションの作成が遅い。セッションの作成は、計算コストの高いオペレーションです。クライアント ライブラリは、BatchCreateSessions API を送信して初期セッション(minSession 構成に基づく)を作成し、CreateSessions API を送信して追加セッション(maxSession まで)を作成します。セッションの作成にセッション取得のタイムアウト設定よりも時間がかかると、新しいリクエストはセッションの待機中にタイムアウトする可能性があります。 BatchCreateSessionsCreateSessions の API 呼び出しのレイテンシを確認します。セッションの作成が遅い場合は、Spanner 側のリソースの問題か、同時セッション作成オペレーションの数が多すぎる可能性があります。

フロー制御メカニズムのエラー

Spanner は、次の条件でフロー制御メカニズムを有効にして、過負荷から保護することがあります。

  • Spanner ノードで CPU 使用率が高くなっている。リクエストが CPU 使用率の増加の原因となっていると思われる場合は、CPU 使用率の指標を使用して問題を調査できます。
  • ホットスポットがあり、リクエストの処理時間が長くなる可能性があります。リクエストがホットスポットの原因となっていると思われる場合は、データベース内のホットスポットを見つけるを参照して問題を調査してください。詳細については、Key Visualizer をご覧ください。

フロー制御メカニズムは、次のクライアント ライブラリでサポートされています。

フロー制御メカニズムを使用しているため、リクエストの完了にかかる全体的な時間は増加しません。このメカニズムを使用しないと、Spanner はリクエストの処理を待機し、最終的に DEADLINE_EXCEEDED エラーを返します。

フロー制御メカニズムが有効になっている場合、Spanner はリクエストをクライアントにプッシュして再試行します。再試行でユーザー指定の期限がすべて消費された場合、クライアントは RESOURCE_EXHAUSTED エラーを受け取ります。このエラーは、Spanner がリクエストの処理時間が長すぎると推定した場合に返されます。エラーはフロー制御に伝播し、Spanner は内部で再試行を蓄積するのではなく、クライアントにリクエストを再試行します。これにより、Spanner は追加のリソース消費の蓄積を回避できます。